示例#1
0
class Brain(object):
    """This is our min max guy"""
    def __init__(self, scratch_board, token):
        self.scratch_board = scratch_board
        self.scratch_judge = Judge(self.scratch_board)
        self.opponent = { 'O':'X', 'X':'O' }
        self.token = token
        self.best_move = None


    def evaluateMove(self, p=None, board=None, depth=10):
        """Do the min max evaluation"""
        if board is None:
            board = [' '] * 9
        depth += 1
        scores = []
        moves = []
        #First off are we at the endgame state?
        #if ' ' not in board: #The board is full the game must be done.
        self.scratch_judge.board.tokens = board
        winner, state = self.scratch_judge.evalGame()
        if winner is None and state == 'done':
            return 0
        elif winner == self.token:
            return 10 + depth
        elif winner == self.opponent[self.token]:
            return 10 - depth
        #winner and state are both None

        #Now we build up our moves
        for next_move in self.scratch_judge.board.getPossibleMoves():
            #do the move
            self.scratch_judge.board.addToken(p, next_move)
            #get the new game state

            new_board = self.scratch_judge.board.getBoard()
            #re-evaluate
            score = self.evaluateMove(p=self.opponent[p], board=new_board, depth=depth)
            scores.append(score)
            moves.append(next_move)
            self.scratch_judge.board.tokens[next_move] = ' '

        #now fix the messed up min max that cannot work.
        if p == self.token: #Calc the max.
            max_score = max(scores)
            idx = scores.index(max_score)
            self.best_move = moves[idx]
            return scores[idx]
        else: #Calc the min
            min_score = min(scores)
            idx = scores.index(min_score)
            self.best_move = moves[idx]
            return scores[idx]
示例#2
0
class Board(object):

    def __init__(self, player=None, computer=None):
        """

        :rtype: object
        """
        self.tokens = [' '] * 9
        self.player_token = player
        self.computer_token = computer
        self.judge = Judge(self)

    def playAgain(self):
        """Find out if we want another go"""
        print('Do you want to play again? (yes or no)')
        return self._raw_input().lower().startswith('y')

    def isWinner(self):
        """Did a win just happen?"""
        result = self.judge.evalGame()
        if result[0] is not None:
            return 'win'
        elif result == [None, None]:
           return False
        else:
            return 'draw'

    def makeComputerMove(self, brain):
        """Make the computer's move"""
        results = []
        tokens = copy.copy(self.tokens)
        if self.take_center():
            best = 4
        else:
            brain.evaluateMove(p=self.computer_token, board=tokens)
            best = brain.best_move
        self.addToken(self.computer_token, int(best))
        print(self.drawBoard())

    def take_center(self):
        """figure out if we can have the center square
        rather than calculating the whole tree our first
        move"""
        token_count = self.tokens.count(' ')
        if token_count == 9:
            return True
        elif token_count == 8 and self.tokens[4] == ' ':
            return True
        return False

    def getPlayerMove(self):
        """Get the player's move"""
        move = ' '
        while move not in self.getPossibleMoves():
            print('What is your next move? (1-9)')
            move = self._raw_input()
            try:
                int(move)
            except:
                print("Please enter a digit")
                print(self.drawBoard())
                continue
            try:
                self.addToken(self.player_token, int(move) - 1)#make the move into an index of the board
                print(self.drawBoard())
                break
            except TokenPlacementException:
                print("please select an empty spot")
                print(self.drawBoard())


    def firstMove(self):
        """Computer goes first"""
        which = random.randint(1, 2)
        if which == 1:
            return 'computer'
        else:
            return 'player'

    def drawBoard(self):
        """Draw a tic-tac-toe board"""

        b = '\n\n%s|%s|%s\n' % tuple(self.tokens[:3])
        b += '_____\n'
        b += '%s|%s|%s\n' % tuple(self.tokens[3:6])
        b += '_____\n'
        b += '%s|%s|%s\n\n' % tuple(self.tokens[6:])

        return b

    def addToken(self, token, idx):
        """Add a token to the board or raise an exception

        str token  "x" or "o"
        int idx    0-8"""

        idx = int(idx)
        if  idx > 8 or idx < 0:
            msg = "Invalid index %s " % idx
            raise TokenPlacementException(msg)

        if self.tokens[idx] == ' ':
            self.tokens[idx] = token
        else:
            msg = "Token at %s" % idx
            raise TokenPlacementException(msg)

    def getBoard(self):
        return copy.copy(self.tokens)

    def getPossibleMoves(self):
        """Return the indexes of possible moves"""
        result = list()
        for i in range(9):
            if self.tokens[i] == ' ':
                result.append(i)
        return result

    def inputPlayerLetter(self):
        """Allow the player to choose a letter"""
        letter = ''
        while not (letter == 'X' or letter == 'O'):
            print('Do you want to be X or O?')
            letter = self._raw_input()
            letter = letter.upper()
            if letter == 'X':
                self.player_token = letter
                self.computer_token = 'O'
                break
            elif letter == 'O':
                self.player_token = letter
                self.computer_token = 'X'
                break

    def _raw_input(self):
        return input()