def deriveHand(self, player: BJPlayer): """ derive hand cards and interpret them into face of hand return face of hand (in the form of 'XX') """ # case0 : exceed 21 if player.minPoint > 21: return 'XX' # case1 : at least an Ace in hand if player.maxPoint != player.minPoint: if player.total() > 21: return 'A' + str(player.minPoint - 1) elif player.total() == 21: if len(player.hand) == 2: return 'AX' return '21' elif player.minPoint < 11: return 'A' + str(player.minPoint -1) else: return str(player.total()) else: # case2 : 77 or 88 if player.hand[0].face == player.hand[1].face and player.hand[0].face in [6, 7]: if len(player.hand) == 2: return '77' if player.hand[0].face == 6 else '88' else: return str(player.total()) # case3 : not 77 or 88 and no Ace in hand else: return str(player.minPoint)
def __init__(self, initCapital, betPercent, round, pause=False, nDeck=1): self.player = BJPlayer(initCapital) self.dealer = BJDealer(nDeck) self.game = BJGameMove(self.player, self.dealer) self.bet = int(initCapital * betPercent) self.nRound = round self.pauseEachRound = pause
def __init__(self, initCapital, betPercent, round, pause = False, nDeck = 1): self.player = BJPlayer(initCapital) self.dealer = BJDealer(nDeck) self.game = BJGameMove(self.player, self.dealer) self.bet = int(initCapital * betPercent) self.nRound = round self.pauseEachRound = pause self.FirstChoice = { 'A1':[4], 'A2':[1], 'A3':[1,3,5], 'A4':[1,3,5], 'A5':[1,3,5], 'A6':[1,3,5], 'A7':[1,3], 'A8':[1,2,3], 'A9':[1,2,3], 'AX':[3], '77':[1,3,4,5], '88':[1,3,4,5], '4' :[1], '5' :[1], '6' :[1], '7' :[1], '8' :[1], '9' :[1,2], '10':[1,2], '11':[1,2], '12':[1], '13':[1], '14':[1,3,5], '15':[1,3,5], '16':[1,3,5], '17':[1,3,5], '18':[3], '19':[3], '20':[3], '21':[0], 'XX':[3] } self.SecondChoice = { 'A1': [1], 'A2': [1], 'A3': [1, 3], 'A4': [1, 3], 'A5': [1, 3], 'A6': [1, 3], 'A7': [1, 3], 'A8': [1, 3], 'A9': [1, 3], 'AX': [3], '77': [0], '88': [0], '4' : [0], '5' : [0], '6' : [1], '7' : [1], '8' : [1], '9' : [1], '10': [1], '11': [1], '12': [1], '13': [1], '14': [1, 3], '15': [1, 3], '16': [1, 3], '17': [1, 3], '18': [3], '19': [3], '20': [3], '21': [3], 'XX': [3] }
def AddTwoCardsToPlayer(dealer: BJDealer, player: BJPlayer, known: KnownCards): c1 = Card(dealer.draw()) c2 = Card(dealer.draw()) player.addCard(c1) player.addCard(c2) known.add(c1) known.add(c2)
def ExpectedScore(self, c1: Card, c2: Card): player = BJPlayer(0) player.addCard(c1) player.addCard(c2) if player.minPoint == player.maxPoint: return self.history[str(player.minPoint)]['avg'] else: return self.history['A' + str(player.minPoint - 1)]['avg']
def Score(dealer: BJDealer, player: BJPlayer): """return 'win' or 'lose' or 'tie' of a player""" # case1: Dealer has BlackJack if dealer.isBlackJack(): if player.isBlackJack(): return 0.0 else: return -1.0 # case2: Dealer doesn't have BlackJack and doesn't exceed 21 points elif dealer.total() <= 21: if player.isBlackJack(): return 1.5 # "Big" WIN means winning by getting BlackJack elif player.total() == dealer.total(): return 0.0 elif player.total() < dealer.total() or player.total() > 21: return -1.0 else: return 1.0 # case3: Dealer exceed 21 points else: if player.isBlackJack(): return 1.5 elif player.total() <= 21: return 1.0 else: return -1.0
def judge(self, player: BJPlayer): """return 'win' or 'lose' or 'tie' of a player""" # case1: Dealer has BlackJack if self.isBlackJack(): if player.isBlackJack(): return 'tie' else: return 'lose' # case2: Dealer doesn't have BlackJack and doesn't exceed 21 points elif self.total() <= 21: if player.isBlackJack(): return 'WIN' # "Big" WIN means winning by getting BlackJack elif player.total() == self.total(): return 'tie' elif player.total() < self.total() or player.total() > 21: return 'lose' else: return 'win' # case3: Dealer exceed 21 points else: if player.isBlackJack(): return 'WIN' elif player.total() <= 21: return 'win' else: return 'lose'
def deriveHand(self, player: BJPlayer): # case0: exceed 21 if player.total() > 21: return '18' # case1: Pairs twoTen = player.hand[0].face >= 9 and player.hand[1].face >= 9 if player.hand[0].face == player.hand[1].face or twoTen: if player.hand[0].face == 0: return 'AA' if player.hand[0].face >= 9: return 'TT' return str(11 * (player.hand[0].face + 1)) # case2: Soft total elif player.minPoint != player.maxPoint and player.minPoint < 11: return 'A' + str(player.minPoint - 1) # case3: Hard total else: if player.total() >= 18: return '18' else: return str(player.total())
class DealerStrategy(): def __init__(self, initCapital, betPercent, round, pause=False, nDeck=1): self.player = BJPlayer(initCapital) self.dealer = BJDealer(nDeck) self.game = BJGameMove(self.player, self.dealer) self.bet = int(initCapital * betPercent) self.nRound = round self.pauseEachRound = pause def nextStep(self, game: BJGameMove): if game.player.total() < 17: return game.moreCard() if game.player.total() >= 17: return game.stop() def play(self, showGame=False): while self.player.round < self.nRound or self.game.playing: if not self.game.playing: if not self.game.newGame( self.bet): # can't start newGame -> End print("can't start new round") break if not self.nextStep( self.game): # playing but can't start nextStep -> End print("next step failed.") break if self.game.playing: if showGame: self.game.print() else: if showGame: self.game.print(result=True) if self.pauseEachRound: input("Press any key to continue...") self.endPlay() def endPlay(self): print(self.player.cashRemain(), "dollar left.\tYou played", self.player.round, "rounds.") ########### # test = DealerStrategy(5000, 0.02, 100, pause=False) # rn.seed(121) # test.play(showGame=True)
class RandomStrategy(): def __init__(self, initCapital, betPercent, round, pause = False, nDeck = 1): self.player = BJPlayer(initCapital) self.dealer = BJDealer(nDeck) self.game = BJGameMove(self.player, self.dealer) self.bet = int(initCapital * betPercent) self.nRound = round self.pauseEachRound = pause self.FirstChoice = { 'A1':[4], 'A2':[1], 'A3':[1,3,5], 'A4':[1,3,5], 'A5':[1,3,5], 'A6':[1,3,5], 'A7':[1,3], 'A8':[1,2,3], 'A9':[1,2,3], 'AX':[3], '77':[1,3,4,5], '88':[1,3,4,5], '4' :[1], '5' :[1], '6' :[1], '7' :[1], '8' :[1], '9' :[1,2], '10':[1,2], '11':[1,2], '12':[1], '13':[1], '14':[1,3,5], '15':[1,3,5], '16':[1,3,5], '17':[1,3,5], '18':[3], '19':[3], '20':[3], '21':[0], 'XX':[3] } self.SecondChoice = { 'A1': [1], 'A2': [1], 'A3': [1, 3], 'A4': [1, 3], 'A5': [1, 3], 'A6': [1, 3], 'A7': [1, 3], 'A8': [1, 3], 'A9': [1, 3], 'AX': [3], '77': [0], '88': [0], '4' : [0], '5' : [0], '6' : [1], '7' : [1], '8' : [1], '9' : [1], '10': [1], '11': [1], '12': [1], '13': [1], '14': [1, 3], '15': [1, 3], '16': [1, 3], '17': [1, 3], '18': [3], '19': [3], '20': [3], '21': [3], 'XX': [3] } def deriveHand(self, player: BJPlayer): """ derive hand cards and interpret them into face of hand return face of hand (in the form of 'XX') """ # case0 : exceed 21 if player.minPoint > 21: return 'XX' # case1 : at least an Ace in hand if player.maxPoint != player.minPoint: if player.total() > 21: return 'A' + str(player.minPoint - 1) elif player.total() == 21: if len(player.hand) == 2: return 'AX' return '21' elif player.minPoint < 11: return 'A' + str(player.minPoint -1) else: return str(player.total()) else: # case2 : 77 or 88 if player.hand[0].face == player.hand[1].face and player.hand[0].face in [6, 7]: if len(player.hand) == 2: return '77' if player.hand[0].face == 6 else '88' else: return str(player.total()) # case3 : not 77 or 88 and no Ace in hand else: return str(player.minPoint) def coach(self, hand, isFirstChoice): """ Base on hand and isFirstChoice, tell the according choice. return 1 ~ 5 representing the chose option return 0 when no option is chosen """ if isFirstChoice: return int(rn.choice(self.FirstChoice[hand])) else: return int(rn.choice(self.SecondChoice[hand])) def doCoach(self, option, game: BJGameMove): """ receive an option from coach, and actually do it if success, return True else, return False """ if option == 1: # more card # print("more") return game.moreCard() elif option == 2: # double more # print("double") return game.doubleMore() elif option == 3: # stop # print("stop") return game.stop() elif option == 4: # split # print("split") return game.split() elif option == 5: # give up # print("give up") return game.giveUp() elif option == 6: # split more # print("(split) more") return game.splitMoreCard() elif option == 7: # split double # print("(split) double") return game.splitDoubleMore() elif option == 8: # split stop # print("(split) stop") self.game.doneSplitHand = True return True else: return False def nextStep(self, game: BJGameMove): """ first check if it's first choice (and tell it to Coach) base on what the player has in his hand, try to do next step according to "Coach" if success, return True else, return False """ isFirstChoice = len(game.player.hand) == 2 and not game.splitting hand = self.deriveHand(game.player) if self.game.splitting: if not self.game.doneSplitHand: splitHand = self.deriveHand(game.splitPlayer) splitChoice = self.coach(splitHand, False) return self.doCoach(splitChoice+5, game) # small trick: +5 indicates split choices else: choice = self.coach(hand, False) return self.doCoach(choice, game) else: choice = self.coach(hand, isFirstChoice) return self.doCoach(choice, game) def play(self, showGame = False): while self.player.round < self.nRound or self.game.playing: if not self.game.playing: if not self.game.newGame(self.bet): # can't start newGame -> End print("can't start new round") break if not self.nextStep(self.game): # playing but can't start nextStep -> End print("next step failed.") break if self.game.playing: if showGame: self.game.print() else: if showGame: self.game.print(result=True) if self.pauseEachRound: input("Press any key to continue...") self.endPlay() def endPlay(self): print(self.player.cashRemain(), "dollar left.\tYou played", self.player.round,"rounds.")
class NNStrategy(): def __init__(self, initCapital, betPercent, round, pause=False, nDeck=1): self.player = BJPlayer(initCapital) self.dealer = BJDealer(nDeck) self.game = BJGameMove(self.player, self.dealer) self.bet = int(initCapital * betPercent) self.nRound = round self.pauseEachRound = pause self.playerMemory = KnownCards() def prepareFeature(self): features = [] # features.append(self.playerMemory.nCard) features.append(self.playerMemory.nTen) # features.append(self.playerMemory.nOne) # features.append(self.playerMemory.nAce) features.append(self.player.minPoint) features.append(self.player.maxPoint) features.append(1 if len(self.player.hand)==2 else 0) # features.append(CanSplitHand(self.player)) # features.append(FaceOfCard(self.dealer.hand[0])) features.append(self.dealer.nDeck) features.append( (16*self.dealer.nDeck - self.playerMemory.nTen) / (52*self.dealer.nDeck - self.playerMemory.nCard)) features.append( (4 * self.dealer.nDeck - self.playerMemory.nAce) / (52 * self.dealer.nDeck - self.playerMemory.nCard)) features.append( (32 * self.dealer.nDeck - self.playerMemory.nOne) / (52 * self.dealer.nDeck - self.playerMemory.nCard)) features.append(FaceOfCard(self.dealer.hand[0]) > 9) return features def doCoach(self, game:BJGameMove): move = nextMove(self.prepareFeature(), CanSplitHand(self.player)) if move == 1: # more card # print("\n\tMORE\n") result = game.moreCard() self.playerMemory.add(self.player.hand[-1]) return result elif move == 2: # stop # print("\n\tSTOP\n") result = game.stop() for card in self.dealer.hand[1:]: self.playerMemory.add(card) return result elif move == 3: # double # print("\n\tDOUBLE\n") result = game.doubleMore() self.playerMemory.add(self.player.hand[-1]) for card in self.dealer.hand[1:]: self.playerMemory.add(card) return result elif move == 4: # split # print("\n\tSPLIT\n") result = game.split() self.playerMemory.add(self.player.hand[-1]) self.playerMemory.add(self.game.splitPlayer.hand[-1]) return result elif move == 5: # give up # print("\n\tGIVEUP\n") result = game.giveUp() for card in self.dealer.hand[1:]: self.playerMemory.add(card) return result else: return False def doCoachAtSplit(self, game:BJGameMove): feature = self.prepareFeature() feature[6] = 0 feature[7] = 0 move = nextMove(feature) if move == 1: # print("\n\t(SPLIT) MORE\n") result = game.moreCard() self.playerMemory.add(self.player.hand[-1]) return result elif move == 2: # print("\n\t(SPLIT) STOP\n") result = game.stop() for card in self.dealer.hand[1:]: self.playerMemory.add(card) self.game.doneSplitHand = True return result elif move == 3: # print("\n\t(SPLIT) DOUBLE\n") result = game.splitDoubleMore() self.playerMemory.add(self.player.hand[-1]) for card in self.dealer.hand[1:]: self.playerMemory.add(card) return result else: return False def nextStep(self, game): if self.game.splitting: if not self.game.doneSplitHand: return self.doCoachAtSplit(game) else: return self.doCoach(game) else: return self.doCoach(game) def play(self, showGame = False): while self.player.round < self.nRound or self.game.playing: if not self.game.playing: if self.dealer.cardLeft < 17 * self.dealer.nDeck: self.playerMemory.reset() start_new_game = self.game.newGame(self.bet) self.playerMemory.add(self.dealer.hand[0]) self.playerMemory.add(self.player.hand[0]) self.playerMemory.add(self.player.hand[1]) if not start_new_game: # can't start newGame -> End print("can't start new round") break if not self.nextStep(self.game): # playing but can't start nextStep -> End print("next step failed.") break if self.game.playing: if showGame: self.game.print() else: if showGame: self.game.print(result=True) if self.pauseEachRound: input("Press ENTER to continue...") self.endPlay() def endPlay(self): print(self.player.cashRemain(), "dollar left.\tYou played", self.player.round,"rounds.")
def __init__(self, initCapital, betPercent, round, pause=False, nDeck=1): self.player = BJPlayer(initCapital) self.dealer = BJDealer(nDeck) self.game = BJGameMove(self.player, self.dealer) self.bet = int(initCapital * betPercent) self.nRound = round self.pauseEachRound = pause self.FirstChoice = { # Hard hand '5': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 5 }, '6': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 5 }, '7': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 5 }, '8': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '9': { '2': 1, '3': 2, '4': 2, '5': 2, '6': 2, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '10': { '2': 2, '3': 2, '4': 2, '5': 2, '6': 2, '7': 2, '8': 2, '9': 2, 'T': 1, 'A': 1 }, '11': { '2': 2, '3': 2, '4': 2, '5': 2, '6': 2, '7': 2, '8': 2, '9': 2, 'T': 1, 'A': 1 }, '12': { '2': 1, '3': 1, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 5 }, '13': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 5 }, '14': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 5, 'A': 5 }, '15': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 5, 'A': 5 }, '16': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 5, 'T': 5, 'A': 5 }, '17': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 5 }, '18': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, # Soft hand 'A2': { '2': 1, '3': 1, '4': 1, '5': 2, '6': 2, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A3': { '2': 1, '3': 1, '4': 1, '5': 2, '6': 2, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A4': { '2': 1, '3': 1, '4': 2, '5': 2, '6': 2, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A5': { '2': 1, '3': 1, '4': 2, '5': 2, '6': 2, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A6': { '2': 1, '3': 2, '4': 2, '5': 2, '6': 2, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A7': { '2': 3, '3': 2, '4': 2, '5': 2, '6': 2, '7': 3, '8': 3, '9': 1, 'T': 1, 'A': 1 }, 'A8': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, 'A9': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, # Pairs '22': { '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '33': { '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 1, '9': 1, 'T': 1, 'A': 5 }, '44': { '2': 1, '3': 1, '4': 1, '5': 4, '6': 4, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '55': { '2': 2, '3': 2, '4': 2, '5': 2, '6': 2, '7': 2, '8': 2, '9': 2, 'T': 1, 'A': 1 }, '66': { '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 5 }, '77': { '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 1, '9': 1, 'T': 5, 'A': 5 }, '88': { '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 4, '9': 4, 'T': 5, 'A': 5 }, '99': { '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 3, '8': 4, '9': 4, 'T': 3, 'A': 3 }, 'TT': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, 'AA': { '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 4, '9': 4, 'T': 4, 'A': 1 }, } self.SecondChoice = { # Hard hand '5': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '6': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '7': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '8': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '9': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '10': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '11': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '12': { '2': 1, '3': 1, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '13': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '14': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '15': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '16': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '17': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, '18': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, # Soft hand 'A2': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A3': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A4': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A5': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A6': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A7': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 1, 'T': 1, 'A': 1 }, 'A8': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, 'A9': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, # Pairs NOTE: second choice for Pairs are all as Hard hands '22': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '33': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '44': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '55': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '66': { '2': 1, '3': 1, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '77': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '88': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '99': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, 'TT': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, 'AA': { '2': 1, '3': 1, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, }
class BasicStrategy(): def __init__(self, initCapital, betPercent, round, pause=False, nDeck=1): self.player = BJPlayer(initCapital) self.dealer = BJDealer(nDeck) self.game = BJGameMove(self.player, self.dealer) self.bet = int(initCapital * betPercent) self.nRound = round self.pauseEachRound = pause self.FirstChoice = { # Hard hand '5': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 5 }, '6': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 5 }, '7': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 5 }, '8': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '9': { '2': 1, '3': 2, '4': 2, '5': 2, '6': 2, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '10': { '2': 2, '3': 2, '4': 2, '5': 2, '6': 2, '7': 2, '8': 2, '9': 2, 'T': 1, 'A': 1 }, '11': { '2': 2, '3': 2, '4': 2, '5': 2, '6': 2, '7': 2, '8': 2, '9': 2, 'T': 1, 'A': 1 }, '12': { '2': 1, '3': 1, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 5 }, '13': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 5 }, '14': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 5, 'A': 5 }, '15': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 5, 'A': 5 }, '16': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 5, 'T': 5, 'A': 5 }, '17': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 5 }, '18': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, # Soft hand 'A2': { '2': 1, '3': 1, '4': 1, '5': 2, '6': 2, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A3': { '2': 1, '3': 1, '4': 1, '5': 2, '6': 2, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A4': { '2': 1, '3': 1, '4': 2, '5': 2, '6': 2, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A5': { '2': 1, '3': 1, '4': 2, '5': 2, '6': 2, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A6': { '2': 1, '3': 2, '4': 2, '5': 2, '6': 2, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A7': { '2': 3, '3': 2, '4': 2, '5': 2, '6': 2, '7': 3, '8': 3, '9': 1, 'T': 1, 'A': 1 }, 'A8': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, 'A9': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, # Pairs '22': { '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '33': { '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 1, '9': 1, 'T': 1, 'A': 5 }, '44': { '2': 1, '3': 1, '4': 1, '5': 4, '6': 4, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '55': { '2': 2, '3': 2, '4': 2, '5': 2, '6': 2, '7': 2, '8': 2, '9': 2, 'T': 1, 'A': 1 }, '66': { '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 5 }, '77': { '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 1, '9': 1, 'T': 5, 'A': 5 }, '88': { '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 4, '9': 4, 'T': 5, 'A': 5 }, '99': { '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 3, '8': 4, '9': 4, 'T': 3, 'A': 3 }, 'TT': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, 'AA': { '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 4, '9': 4, 'T': 4, 'A': 1 }, } self.SecondChoice = { # Hard hand '5': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '6': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '7': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '8': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '9': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '10': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '11': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '12': { '2': 1, '3': 1, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '13': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '14': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '15': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '16': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '17': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, '18': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, # Soft hand 'A2': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A3': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A4': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A5': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A6': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, 'A7': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 1, 'T': 1, 'A': 1 }, 'A8': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, 'A9': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, # Pairs NOTE: second choice for Pairs are all as Hard hands '22': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '33': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '44': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '55': { '2': 1, '3': 1, '4': 1, '5': 1, '6': 1, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '66': { '2': 1, '3': 1, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '77': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '88': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, '99': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, 'TT': { '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3, '8': 3, '9': 3, 'T': 3, 'A': 3 }, 'AA': { '2': 1, '3': 1, '4': 3, '5': 3, '6': 3, '7': 1, '8': 1, '9': 1, 'T': 1, 'A': 1 }, } def deriveHand(self, player: BJPlayer): # case0: exceed 21 if player.total() > 21: return '18' # case1: Pairs twoTen = player.hand[0].face >= 9 and player.hand[1].face >= 9 if player.hand[0].face == player.hand[1].face or twoTen: if player.hand[0].face == 0: return 'AA' if player.hand[0].face >= 9: return 'TT' return str(11 * (player.hand[0].face + 1)) # case2: Soft total elif player.minPoint != player.maxPoint and player.minPoint < 11: return 'A' + str(player.minPoint - 1) # case3: Hard total else: if player.total() >= 18: return '18' else: return str(player.total()) def coach(self, hand, isFirstChoice): holeCard = self.game.dealer.hand[1].face if holeCard == 0: hole = 'A' elif holeCard >= 9: hole = 'T' else: hole = str(holeCard + 1) if isFirstChoice: return self.FirstChoice[hand][hole] return self.SecondChoice[hand][hole] def doCoach(self, option, game: BJGameMove): if option == 1: # more card # print("more") return game.moreCard() elif option == 2: # double more # print("double") return game.doubleMore() elif option == 3: # stop # print("stop") return game.stop() elif option == 4: # split # print("split") return game.split() elif option == 5: # give up # print("give up") return game.giveUp() elif option == 6: # split more # print("(split) more") return game.splitMoreCard() elif option == 7: # split double # print("(split) double") return game.splitDoubleMore() elif option == 8: # split stop # print("(split) stop") self.game.doneSplitHand = True return True else: return False def nextStep(self, game: BJGameMove): """ first check if it's first choice (and tell it to Coach) base on what the player has in his hand, try to do next step according to "Coach" if success, return True else, return False """ isFirstChoice = len(game.player.hand) == 2 and not game.splitting hand = self.deriveHand(game.player) if self.game.splitting: if not self.game.doneSplitHand: splitHand = self.deriveHand(game.splitPlayer) splitChoice = self.coach(splitHand, False) return self.doCoach( splitChoice + 5, game) # small trick: +5 indicates split choices else: choice = self.coach(hand, False) return self.doCoach(choice, game) else: choice = self.coach(hand, isFirstChoice) return self.doCoach(choice, game) def play(self, showGame=False): while self.player.round < self.nRound or self.game.playing: if not self.game.playing: if not self.game.newGame( self.bet): # can't start newGame -> End print("can't start new round") break if not self.nextStep( self.game): # playing but can't start nextStep -> End print("next step failed.") break if self.game.playing: if showGame: self.game.print() else: if showGame: self.game.print(result=True) if self.pauseEachRound: input("Press ENTER to continue...") self.endPlay() def endPlay(self): print(self.player.cashRemain(), "dollar left.\tYou played", self.player.round, "rounds.")
def resetPlayer(player: BJPlayer): player.hand = [] player.minPoint = 0 player.maxPoint = 0
player.addCard(c) memory.add(c) record.updateAverage(initHands[0], initHands[1], sum(bestResult) / len(bestResult)) for card in dealer.hand[1:]: memory.add(card) resetPlayer(player) resetPlayer(dealer) if __name__ == '__main__': rn.seed(600) # 1 deck, 1000 round dealer = BJDealer(1) player = BJPlayer(0) memory = KnownCards() record = Recorder('nn_deck_1_round_2000') for i in range(30000): oneRound(dealer, player, memory, record) if dealer.cardLeft < 17 * dealer.nDeck: memory.reset() dealer.shuffle() record.EndTask() # 6 deck, 1000 round dealer = BJDealer(6) player = BJPlayer(0) memory = KnownCards()
def __init__(self, initCapital, nDeck, seed): rn.seed(seed) self.dealer = BJDealer(nDeck) self.player = BJPlayer(initCapital) self.game = BJGameMove(self.player, self.dealer)