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, id_solve
    from easyAI.AI import TT
    # 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 = TT())
    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!
