def show(self, players): self.last_dealer_hand = players[0].hand self.last_dealer_value = card.value(self.last_dealer_hand) self.last_player_hand = [ p.hand for p in players if p.player.name == self.name ][0] self.last_player_value = card.value(self.last_player_hand)
def play(self, dealer, players): action = self.choose_from_matrix(dealer, players) #nao pode ser asssim #tem de ser mais complexo e guardar todas as acooes #q o nosso jogador efectuou numa jogada #inves do turno total #desta maneira, agora, #apenas guarda a accao final do jogador #evidenciado pelos prints na choose_from_matrix for p in players: if p.player.name == self.name: r = p.hand # if self.turn == 1: # if card.value(r) == 15: # print "teste" # self.turn =0 # return "d" if card.value(r) > 19: self.turn = 0 action = 's' return 's' elif card.value(r) < 6: self.turn = 0 action = 'h' return 'h' self.last_actions.append( [card.value(dealer.hand), card.value(r), action]) #print self.last_actions self.turn = 0 return action
def debug_state(self, dealer, players): print("--------------------------------------------") print("{:10s}: {!s:32s} = {}".format("Dealer", ['🎴 '] + dealer.hand, card.value(dealer.hand))) for p in players: print("{:10s}: {!s:32s} = {}".format(p.player.name, p.hand, card.value(p.hand)))
def getUseableAce(self, hand): numberAces = len([c for c in hand if c.is_ace()]) if numberAces == 0: return False elif numberAces == 2 and len(hand) == 2 and (card.value(hand) == 12 or card.value(hand) == 2): return True handNoAce = card.value([c for c in hand if not c.is_ace()]) return True if numberAces + handNoAce == card.value(hand) else False
def payback(self, winners): for p in self.state[1:]: if p.watch: #skip watchers continue if p in winners and card.value(self.state[0].hand) == card.value( p.hand): p.player.payback(0) #bet is returned elif p in winners: p.player.payback(-p.bet + p.bet * BET_MULTIPLIER) else: p.player.payback(-p.bet) #this means the player lost
def choose_from_matrix(self, dealer, players): for p in players: if p.player.name == self.name: r = card.value(p.hand) c = card.value(dealer.hand) l = self.m[r][c] nl = [] for i in l: nl.append([i[0], self.success_rate(i[1], i[2])]) return self.weighted_choice(nl)
def play(self, dealer, players): player = [x for x in players if x.player.name == self.name][0] # player = my boot (name = Student) dealer_value = card.value(dealer.hand) if card.value(dealer.hand) <= 21 else 0 # value cards dealer player_value = card.value(player.hand) if card.value(player.hand) <= 21 else 0 # value cards my boot if (self.firstBet): op = self.firstMove(player, dealer, player_value, dealer_value) self.firstBet = False; else: op = self.moderatePlayer(player, dealer, player_value, dealer_value) self.dealer_cards = len(dealer.hand) return op
def test_value(self): card = Card(10, "J") card1 = Card(11, 'A') card2 = Card(1, 'A') self.assertEqual(card.value(), 10) self.assertEqual(card1.value(), 11) self.assertEqual(card2.value(), 1)
def probGanharAgora(dealerHand, myHand): x = 0 myVal = card.value(myHand) if (myVal == 21) or (card.value(dealerHand) > 21): print "100%\n" return float(100) if myVal > 21: print "0%" return float(0) for i in baralho: carta = Card(suit=0, rank=i) dealerVal = card.value(dealerHand + [carta]) if (dealerVal > myVal) and (dealerVal <= 21): x = x + 1 p = 100 - (float(x) / float(13)) * 100 #print ("probabilidade de ganhar agora: %2.2f%%"% (p)) return p
def probGanharProxRondaHitStand(myHand, dealerHand): #dealer faz hit e jog faz stand x = 0 c = 0 myVal = card.value(myHand) for i in baralho: carta = Card(suit=0, rank=i) for j in baralho: cartaj = Card(suit=0, rank=j) dealerVal = card.value(dealerHand + [carta] + [cartaj]) if ((dealerVal > myVal) and (dealerVal <= 21)) or (myVal > 21): x = x + 1 c = c + 1 else: c = c + 1 p = 100 - (float(x) / float(c)) * 100 #print ("probabilidade de ganhar na proxima jogada fazendo stand e o dealer hit: %2.2f%%"% (p)) return p
def probGanharProxRondaStandHit(myHand, dealerHand): #dealer faz stand e jog faz hit x = 0 #em que o dealer ganha c = 0 #casos totais for i in baralho: carta = Card(suit=0, rank=i) myVal = card.value(myHand + [carta]) for k in baralho: cartak = Card(suit=0, rank=k) dealerVal = card.value(dealerHand + [cartak]) if ((dealerVal > myVal) and (dealerVal <= 21)) or (myVal > 21): x = x + 1 c = c + 1 else: c = c + 1 p = 100 - (float(x) / float(c)) * 100 #print ("probabilidade de ganhar na proxima jogada fazendo hit e o dealer stand: %2.2f%%"% (p)) return p
def player_probability(self, player): player_value = card.value(player.hand) if card.value(player.hand) <= 21 else 0 # value cards my boot player_hand_Ace = False # mao do player contem Ace player_hand_nAce = 0 # numero de Ace's visiveis do player if any(c.is_ace() for c in player.hand): player_hand_Ace = True for c in player.hand: if c.is_ace(): player_hand_nAce += 1; player_totalValue = 0 # valor total da mao do player for c in player.hand: if c.is_ace(): player_totalValue += c.value() + 10 else: player_totalValue += c.value() # CASO PLAYER FACA HIT dif_player = 0 # diferenca entre blackjack e o valor da mao do dealer if (player_hand_Ace): # Caso a mao do dealer contenha 1 ou mais Ace's if (player_value != player_totalValue): dif_player = 21 - player_value # teremos que subtratir o o numero de Ace * 10 else: dif_player = 21 - ( player_totalValue - (player_hand_nAce * 10)) else: dif_player = 21 - player_value; num_benefit_cards_player = len( [x for x in self.value_cards if dif_player >= x]) # numer de cartas beneficas para o player prob_player_not_bust = 1.0 * num_benefit_cards_player / 13 # probabilidade de player melhorar a sua mao prob_player_bust = 1 - (1.0 * prob_player_not_bust) # probabilidade de o player fazer bust if (player_hand_Ace): # calcular probabilidade de melhorar mao em caso de "h" prob_better_hand = 1.0 * (21 - player_value) / 13 else: prob_better_hand = prob_player_not_bust return [prob_player_bust, prob_better_hand]
def play(self, dealer, players): player = [p for p in players if self.name == p.player.name][0] ##WHO AM I? GET MYSELF FROM PLAYERS dealer_value = card.value(dealer.hand) ##DEALER HAND VALUE player_value = card.value(player.hand) ##MY HAND VALUE table = open('table.txt', 'rb') ##LOAD PROB MATRIX FROM FILE matrix = pickle.load(table) table.close() action = self.getAction(player_value, dealer_value, matrix) ##BEST ACTION BASED ON PROBABILITIES MATRIX ##HE CAN STILL LEARN SURRENDER OR DOUBLE DOWN, BUT STILL I HARDCODED 3 CASES BELOW if self.turn == 0 and player_value == 11 : ##BUT IF WE HAVE 11, ALWAYS DOUBLE DOWN action = "d" elif self.turn == 0 and player_value == 10 and dealer_value < 10: ## SECOND CASE I USE DOUBLE DOWN action = "d" elif self.turn == 0 and player_value == 16 and dealer_value >= 9: ##SURRENDER HARDCODED IN 3 CELLS OF THE MATRIX action = "u" if self.turn != 0: ## APPEND STATE BETWEEN ROUNDS UNTIL PAYBACK state = {'Action': action, 'Player_Value': player_value, 'Dealer_Value': dealer_value} ## ONE STATE CONTAINS PLAYER_VALUE, DEALER_VALUE AND ACTION self.hist.append(state) elif self.turn == 0 and len(self.hist) > 0: ##UPDATES MATRIX ON THE FIRST ROUND OF A NEW GAME for i in self.hist: matrix = self.update(i['Player_Value'],i['Dealer_Value'], matrix, i['Action']) ##UPDATES MATRIX WITH VALUES FROM THE LAST GAME self.hist = [] table = open('table.txt', 'wb') ##SAVE MATRIX IN FILE pickle.dump(matrix, table) table.close() nice_table = open("nice_table.txt", "w") ##TABLE FOR VISUALIZATION for i in range(21): nice_table.write("Player_value: " + str(i+1) + " " + str(matrix[i]) + "\n") nice_table.close() self.turn += 1 ##NEXT TURN return action
def play(self, dealer, players): player_cards = [x for x in players if x.player.name == self.name][0].hand dealer_hand = card.value(dealer.hand) #get the value of the dealer hand my_hand = card.value(player_cards) #get the value of the player hand first_turn = self.current == [] #check if it is the first turn my_soft_hand = self.is_soft_hand(player_cards) #check if the player has a soft hand dealer_soft_hand = self.is_soft_hand(dealer.hand) #check if the dealer has a soft hand if not my_soft_hand and not dealer_soft_hand: soft_hand = 0 elif my_soft_hand and not dealer_soft_hand: soft_hand = 1 elif my_soft_hand and dealer_soft_hand: soft_hand = 2 elif not my_soft_hand and dealer_soft_hand: soft_hand = 3 if initial_train: num = random.randint(0,2) if num == 0: p = 'h' elif num == 1: p = 's' else: p = 'd' else: p = self.matrix.get_best_play(my_hand, dealer_hand, soft_hand, first_turn) #get the best play based on the player hand, #dealer hand and if it is the first turn self.current += [(my_hand, dealer_hand, soft_hand, p)] #add the current turn to the list of turns if p == 'u': self.surrender = True if p == 'd': self.double_down_bet = True if debug: print("Current list: " + self.current.__str__()) return p
def bet(self, dealer, players): self.turn = 0 ##SET FIRST TURN/ROUND player = [p for p in players if p.player.name == self.name][0] player_value = card.value(player.hand) dealer_value = card.value(dealer.hand) if player_value < 21: fav = 21 - player_value # juntar maos do jogador e dealer para fins de contagem e apurar se o fav existe numa das duas all = self.concatenar(dealer.hand, player.hand) p = 0 while(fav>0): #contar os pontos iguais aos favoraveis fshow = all.count(fav) p = p + self.prob(fav, fshow, len(all), 4) fav = fav -1 result = p*10 if result > 10: return 5 elif result < 1: return 1 else: return result
def loop(self): #deal initial cards self.state[0].hand += self.shoe.deal_cards(2) for p in self.state[1:]: if not p.watch: p.hand += self.shoe.deal_cards(2) turn = 0 if card.blackjack( self.state[0].hand ): #if the dealer has blackjack there is no point in playing... self.done = True return [p for p in self.state[1:] if card.blackjack(p.hand)] #lets play while not self.done: turn += 1 hits = 0 for p in self.state[::-1]: if p.watch or p.bust or p.done or card.value( p.hand ) == 21: #skip players watching, bust players, players who have double down and players who already have blackjack! continue if self.debug: print("TURN {}: {}".format(turn, p.player.name)) print(self) action = "" while action not in ["h", "s", "d", "u"]: if isinstance(p.player, Dealer): action = p.player.play(self.state[0], self.state[1:]) else: action = p.player.play(self.state[0].hide_card(), self.state[1:]) if action == "d" and turn != 1: print( "YOU CAN'T DOUBLE DOWN!!! double down is only available on the 1st turn" ) action = "" if action == "u": p.watch = True p.player.payback( -p.bet // 2) #this means the player lost half his bet continue if action == "d": p.take_bet(self.state, self.rules) p.done = True if action in ["h", "d"]: p.hand += self.deal(1) hits += 1 if card.value(p.hand) >= 21: if card.value(p.hand) > 21: p.bust = True else: p.done = True #already has blackjack if isinstance(p.player, Dealer): self.done = True #game is over we already have a blackjack if hits == 0: self.done = True self.done = True return [ p for p in self.state if not isinstance(p.player, Dealer) and #Dealer is not really a winner not card.blackjack(self.state[0].hand) and #If dealer gets blackjack no one wins not p.bust and #bust players can't win :) ( card.value(p.hand) >= card.value(self.state[0].hand) or self.state[0].bust ) #winners have more points then the dealer or the dealer has gone bust ]
def dealer_probability(self, dealer): dealer_value = card.value(dealer.hand) if card.value(dealer.hand) <= 21 else 0 # value cards dealer dealer_value_estimated = dealer_value + 6.85 # valor estimado da mao do delaer dealer_hand_Ace = False # mao do dealer contem Ace dealer_hand_nAce = 0 # numero de Ace's visiveis do dealer if any(c.is_ace() for c in dealer.hand): dealer_hand_Ace = True for c in dealer.hand: if c.is_ace(): dealer_hand_nAce += 1; dealer_totalValue = 0 # valor total da mao do delaer dealer_totalValue_estimated = 0 # valoer total estimado da mao do dealer for c in dealer.hand: if c.is_ace(): dealer_totalValue += c.value() + 10 else: dealer_totalValue += c.value() dealer_totalValue_estimated = dealer_totalValue + 6.85 dif_dealer = 0 dif_dealer_estimated = 0 if (dealer_hand_Ace): # diferenca entre blackjack e o valor da mao do dealer if (dealer_value != dealer_totalValue): # Caso a mao do dealer contenha 1 ou mais Ace's dif_dealer = 21 - dealer_value else: dif_dealer = 21 - ( dealer_totalValue - (dealer_hand_nAce * 10)) # teremos que subtratir o o numero de Ace * 10 else: dif_dealer = 21 - dealer_value dif_dealer_estimated = (dif_dealer - 6.85) + 1 num_benefit_cards_dealer = len( [x for x in self.value_cards if dif_dealer >= x]) # numer de cartas beneficas para o dealer num_benefit_cards_dealer_estimated = len( [x for x in self.value_cards if dif_dealer_estimated >= x]) prob_dealer_not_bust = 1.0 * num_benefit_cards_dealer / 13 # probabilidade de dealer melhorar a sua mao prob_dealer_bust = 1 - (1.0 * prob_dealer_not_bust) prob_dealer_not_bust_estimated = 1.0 * num_benefit_cards_dealer_estimated / 13 prob_dealer_bust_estimated = 1 - (1.0 * prob_dealer_not_bust_estimated) if (dealer_hand_Ace): # calcular probabilidade de melhorar mao prob_better_hand = 1.0 * (21 - dealer_value) / 13 prob_better_hand_estimated = 1.0 * (21 - dealer_value_estimated) / 13 else: prob_better_hand = prob_dealer_not_bust prob_better_hand_estimated = prob_dealer_not_bust_estimated count = 0 for c in self.value_cards: if (c < (17 - dealer_value)): count += 1 if (dealer_value < 17): # probabilidade do dealer fazer hit na proxima jogada if (dealer_value <= 10): if (count > 12): count = 12; prob_hit = 1.0 * (count + 1) / 13 # +1 porque o Ace é favorável neste caso else: prob_hit = 1.0 * (count) / 13 else: prob_hit = 0 countEstimated = 0 for c in self.value_cards: if (c < (17 - dealer_value_estimated)): countEstimated += 1 if (dealer_value_estimated < 17): # probabilidade estimada # do dealer fazer hit na proxima jogada if (dealer_value_estimated <= 10): if (countEstimated > 12): countEstimated = 12; prob_hit_estimated = 1.0 * (countEstimated + 1) / 13 # +1 porque o Ace é favorável neste caso else: prob_hit_estimated = 1.0 * (countEstimated) / 13 else: prob_hit_estimated = 0 return [prob_dealer_bust, prob_better_hand, prob_hit, prob_dealer_bust_estimated, prob_better_hand_estimated, prob_hit_estimated]
def prob_win(self): all_cards = [card.Card(rank=r) for r in range(1, 14)] scenarios = [card.value(self.player_hand + [c]) for c in all_cards] return len([v for v in scenarios \ if v < 22 and v > self.last_dealer_value]) / len(scenarios)
def getPlayerValue(self, players): for p in players: if p.player.name == self.name: return p.hand, card.value(p.hand)
def debug_state(self, dealer, players): print "{:10s}: {:32s} = {}".format("Dealer", dealer.hand, card.value(dealer.hand)) for p in players: print "{:10s}: {:32s} = {}".format(p.player.name, p.hand, card.value(p.hand))
def play(self, dealer, players): if card.value(dealer.hand) < 17: return "h" return "s"
def get_hand_value(self): val = 0 for card in self.hand: val = val + card.value() return val
def card_values(cards): return [card.value(c) for c in cards]
def prob_dealer_bust(self): all_cards = [card.Card(rank=r) for r in range(1, 14)] scenarios = [card.value(self.dealer_hand + [c]) for c in all_cards] return len([v for v in scenarios \ if v > 21]) / len(scenarios)
def play(self, dealer, players): # Get player hand new_player_hand = [ p.hand for p in players if p.player.name == self.name ][0] new_dealer_hand = dealer.hand # Get players' total new_player_value = card.value(new_player_hand) new_dealer_value = card.value(dealer.hand) # Increment turn self.turn += 1 # Evaluate older state if self.create and self.turn > 1: query = self.queries[-1][0] wins_defeats = query[1:] good_flag = False if self.action == 'h': # If probably the dealer was on bust if self.prob_dealer_bust() > self.bust_threshold: # Maybe we should stand wins_defeats[self.plays.index('s')] += 1 else: # If the prob of being in advantage over the dealer is low # on the previous play if self.player_value > self.dealer_value: wins_defeats[self.plays.index(self.action)] += 1 # If we were in advantage, check if our score hasn't decreased elif new_player_value >= self.player_value: wins_defeats[self.plays.index(self.action)] += 1 # If we were in advantage and our score has decreased else: # If we are still in the lead if new_player_value > new_dealer_value: # If out score was above 18, we should have stand if self.player_value > 18: wins_defeats[self.plays.index('s')] += 1 # Else the hit was a good option to keep playing else: wins_defeats[self.plays.index( self.action)] += 1 # If we lost the lead, then we should have stand else: wins_defeats[self.plays.index('s')] += 1 elif self.action == 's': if new_player_value > 17: wins_defeats[self.plays.index(self.action)] += 1 else: wins_defeats[self.plays.index('h')] += 1 query = wins_defeats + [query[0]] self.conn.execute(self.update_prob_query, (query)) self.player_hand = new_player_hand self.dealer_hand = new_dealer_hand # Get players' total self.player_value = new_player_value self.dealer_value = new_dealer_value player_ace = len([c for c in self.player_hand if c.is_ace()]) player_sum = sum([c.value() for c in self.player_hand]) soft_hand = player_sum != self.player_value self.state = (self.player_value, self.dealer_value, \ soft_hand, self.turn == 1, player_ace > 0) # Access table and search for the best probability based on state-action self.states_query = list(self.conn.execute(self.get_prob_query, \ (self.state)).fetchall()[0]) wins = [self.states_query[1] + self.states_query[3], \ self.states_query[2] + self.states_query[4]] defeats = self.states_query[-1] probs = [a / sum(wins) for a in wins] intervals = [sum(probs[:idx]) for idx in range(1, len(probs) + 1)] r = random.random() idx = 0 while intervals[idx] < r: idx += 1 if self.create: self.action = self.plays[idx] else: diff = abs(probs[0] - probs[1]) self.action = self.plays[idx] if diff < self.probs_threshold \ else self.plays[probs.index(max(probs))] self.queries += [(self.states_query, self.action)] if not self.create: if self.player_value > 11 \ and sum(wins) / (sum(wins) + defeats) < self.surrender_threshold: self.action = 'u' elif self.turn == 1 and self.player_value > 9 \ and sum(self.states_query[3:5]) / sum(wins) > self.use_dd_threshold \ and self.states_query[4] / sum(self.states_query[3:5]) > self.dd_threshold: self.action = 'd' return self.action
def getDealerValue(self, dealer): dealerHand = card.value(dealer.hand) if len([c for c in dealer.hand if c.is_ace()]) > 0: dealerHand = 1 return dealerHand
def play(self, dealer, players): val_dealer = card.value(dealer.hand) numCards_dealer = len(dealer.hand) if self.dealer_numCards == numCards_dealer: self.dealer_didntHit = 1 else: self.dealer_didntHit = 0 self.dealer_numCards = numCards_dealer ases_dealer = len([x for x in dealer.hand if x.rank == 1]) for player_state in players: if player_state.player == self: self.round_number += 1 val_player = card.value(player_state.hand) numCards_player = len(player_state.hand) ases_player = len([x for x in player_state.hand if x.rank == 1]) #if self.round_number == 1: #double-down only on the 1st turn # if self.pocket >= self.amount_to_bet*2: # self.double_down = 1 # else: # self.double_down = 0 if val_player == 11: if self.round_number == 1: #double-down only on the 1st turn self.double_down = 1 # calcular probabilidades com o modelo #ver os maximos. se for para perder, usar surrender prob_stand = self.model.get_classifier().predict_proba( np.array([[val_player, numCards_player, ases_player, val_dealer, numCards_dealer, self.dealer_didntHit , ases_dealer, 0]])) # stand prob_hit = self.model.get_classifier().predict_proba( np.array([[val_player, numCards_player, ases_player, val_dealer, numCards_dealer, self.dealer_didntHit , ases_dealer, 1]])) # hit class_hit = np.argmax(prob_hit) class_stand = np.argmax(prob_stand) class_hit_prob = np.max(prob_hit) class_stand_prob = np.max(prob_stand) if class_hit_prob < 0.1 and class_stand_prob < 0.1: play = Play(val_player, numCards_dealer, ases_player, val_dealer, numCards_dealer, self.dealer_didntHit, ases_dealer, 1) return "u" #SURRENDER #if(self.want_to_play(rules = self.rules) == False): # play = Play(val_player, numCards_dealer, ases_player, val_dealer, numCards_dealer, self.dealer_didntHit, ases_dealer, 1) # return "u" # SURRENDER if class_hit == class_stand: if class_hit == 1: if class_hit_prob > class_stand_prob: if self.double_down != 0: play = Play(val_player, numCards_player, ases_player, val_dealer, numCards_dealer, self.dealer_didntHit, ases_dealer, 1) self.plays.append(play) return "d" #DOUBLE_DOWN else: self.double_down = 0 play = Play(val_player, numCards_player, ases_player, val_dealer, numCards_dealer, self.dealer_didntHit, ases_dealer, 1) self.plays.append(play) return "h" #HIT else: self.double_down = 0 play = Play(val_player, numCards_player, ases_player, val_dealer, numCards_dealer, self.dealer_didntHit, ases_dealer, 0) self.plays.append(play) return "s" #STAND else: if class_hit_prob < class_stand_prob: if self.double_down != 0: play = Play(val_player, numCards_player, ases_player, val_dealer, numCards_dealer, self.dealer_didntHit, ases_player, 1) self.plays.append(play) return "d" #DOUBLE_DOWN else: self.double_down = 0 play = Play(val_player, numCards_player, ases_player, val_dealer, numCards_dealer, self.dealer_didntHit, ases_dealer, 1) self.plays.append(play) return "h" #HIT else: self.double_down = 0 play = Play(val_player, numCards_player, ases_player, val_dealer, numCards_dealer, self.dealer_didntHit, ases_dealer, 0) self.plays.append(play) return "s" #STAND else: self.double_down = 0 if class_hit == 1: play = Play(val_player, numCards_player, ases_player, val_dealer, numCards_dealer, self.dealer_didntHit, ases_dealer, 1) self.plays.append(play) return "h" #HIT else: play = Play(val_player, numCards_player, ases_player, val_dealer, numCards_dealer, self.dealer_didntHit, ases_dealer, 0) self.plays.append(play) return "s" #STAND return "s" #STAND