from easyAI import TwoPlayersGame class Nim(TwoPlayersGame): """ The game starts with 4 piles of 5 pieces. In turn the players remove as much pieces as they want, but from one pile only. The player that removes the last piece loses. Arguments: - players: the players... - piles: the piles the game starts with. With piles=[2,3,4,4] the game will start with 1 pile of 2 pieces, 1 pile of 3 pieces, and 2 piles of 4 pieces. If set to None, the default will be [5,5,5,5] """ def __init__(self, players, piles = None): """ Default for `piles` is 5 piles of 5 pieces. """ self.players = players self.piles = piles if (piles != None) else [5, 5, 5, 5] self.nplayer = 1 # player 1 starts. def possible_moves(self): return ["%d,%d" % (i + 1, j) for i in range(len(self.piles)) for j in range(1, self.piles[i] + 1)] def make_move(self, move): move = list(map(int, move.split(','))) self.piles[move[0] - 1] -= move[1] def unmake_move(self, move): # optional, speeds up the AI move = list(map(int, move.split(','))) self.piles[move[0] - 1] += move[1] def show(self): print(" ".join(map(str, self.piles))) def win(self): return max(self.piles) == 0 def is_over(self): return self.win() def scoring(self): return 100 if self.win() else 0 def ttentry(self): return tuple(self.piles) #optional, speeds up AI if __name__ == "__main__": # IN WHAT FOLLOWS WE SOLVE THE GAME AND START A MATCH AGAINST THE AI from easyAI import AI_Player, Human_Player, Negamax, DictTT, id_solve # we first solve the game w, d, m, tt = id_solve(Nim, range(5, 20), win_score = 80) print w, d, len(tt.d) # the previous line prints -1, 16 which shows that if the # computer plays second with an AI depth of 16 (or 15) it will # always win in 16 (total) moves or less. # Now let's play (and lose !) against the AI ai = Negamax(16, tt = DictTT()) game = Nim([Human_Player(), AI_Player(tt)]) game.play() # You will always lose this game ! print("player %d wins" % game.nplayer) # Note that with the transposition table tt generated by id_solve # we can setup a perfect AI which doesn't have to think: # >>> game = Nim( [ Human_Player(), AI_Player( tt )]) # >>> game.play() # You will always lose this game too!