fork(1) download
  1. import random
  2. import multiprocessing
  3. import math
  4. import time
  5.  
  6. # configuration options
  7. simulations = 6000000
  8. num_decks = 4
  9. shuffle_perc = 75
  10.  
  11. def simulate(queue, batch_size):
  12. deck = []
  13.  
  14. def new_deck():
  15. std_deck = [
  16. # 2 3 4 5 6 7 8 9 10 J Q K A
  17. 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11,
  18. 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11,
  19. 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11,
  20. 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11,
  21. ]
  22.  
  23. # add more decks
  24. std_deck = std_deck * num_decks
  25.  
  26. random.shuffle(std_deck)
  27.  
  28. return std_deck[:]
  29.  
  30. def play_hand():
  31. dealer_cards = []
  32. player_cards = []
  33.  
  34. # deal initial cards
  35. player_cards.append(deck.pop(0))
  36. dealer_cards.append(deck.pop(0))
  37. player_cards.append(deck.pop(0))
  38. dealer_cards.append(deck.pop(0))
  39.  
  40. # deal player to 12 or higher
  41. while sum(player_cards) < 12:
  42. player_cards.append(deck.pop(0))
  43.  
  44. # deal dealer on soft 17
  45. while sum(dealer_cards) < 18:
  46. exit = False
  47. # check for soft 17
  48. if sum(dealer_cards) == 17:
  49. exit = True
  50. # check for an ace and convert to 1 if found
  51. for i, card in enumerate(dealer_cards):
  52. if card == 11:
  53. exit = False
  54. dealer_cards[i] = 1
  55.  
  56. if exit:
  57. break
  58.  
  59. dealer_cards.append(deck.pop(0))
  60.  
  61. p_sum = sum(player_cards)
  62. d_sum = sum(dealer_cards)
  63.  
  64. # dealer bust
  65. if d_sum > 21:
  66. return 1;
  67. # dealer tie
  68. if d_sum == p_sum:
  69. return 0;
  70. # dealer win
  71. if d_sum > p_sum:
  72. return -1;
  73. # dealer lose
  74. if d_sum < p_sum:
  75. return 1
  76.  
  77. # starting deck
  78. deck = new_deck()
  79.  
  80. # play hands
  81. win = 0
  82. draw = 0
  83. lose = 0
  84. for i in range(0, batch_size):
  85. # reshuffle cards at shuffle_perc percentage
  86. if (float(len(deck)) / (52 * num_decks)) * 100 < shuffle_perc:
  87. deck = new_deck()
  88.  
  89. # play hand
  90. result = play_hand()
  91.  
  92. # tally results
  93. if result == 1:
  94. win += 1
  95. if result == 0:
  96. draw += 1
  97. if result == -1:
  98. lose += 1
  99.  
  100. # add everything to the final results
  101. queue.put([win, draw, lose])
  102.  
  103.  
  104. start_time = time.time()
  105.  
  106. print("start!")
  107.  
  108. # simulate
  109. cpus = multiprocessing.cpu_count()
  110. batch_size = int(math.ceil(simulations / float(cpus)))
  111.  
  112. queue = multiprocessing.Queue()
  113.  
  114. # create n processes
  115. processes = []
  116.  
  117. for i in range(0, cpus):
  118. process = multiprocessing.Process(target=simulate, args=(queue, batch_size))
  119. processes.append(process)
  120. process.start()
  121.  
  122. # wait for everything to finish
  123. for proc in processes:
  124. proc.join()
  125.  
  126. finish_time = time.time() - start_time
  127.  
  128.  
  129.  
  130. # get totals
  131. win = 0
  132. draw = 0
  133. lose = 0
  134.  
  135. for i in range(0, cpus):
  136. results = queue.get()
  137. win += results[0]
  138. draw += results[1]
  139. lose += results[2]
  140.  
  141. print
  142. print (' cores used: %d' % cpus)
  143. print (' total simulations: %d' % simulations)
  144. print (' simulations/s: %d' % (float(simulations) / finish_time))
  145. print (' execution time: %.2fs' % finish_time)
  146. print (' win percentage: %.2f%%' % ((win / float(simulations)) * 100))
  147. print (' draw percentage: %.2f%%' % ((draw / float(simulations)) * 100))
  148. print (' lose percentage: %.2f%%' % ((lose / float(simulations)) * 100))
  149. print
  150.  
Time limit exceeded #stdin #stdout 5s 49736KB
stdin
Standard input is empty
stdout
start!