Example #1
0
        def minimax(board,currentDepth,isOdd):
            # Note: bool isOdd basically tells us we want the max

            #checking this here REALLY boosts efficiency (due to getLegalMoves getting skipped)
            if currentDepth == self.maxDepth:
                return super(MinimaxPlayer,self).h1(board,self.symbol)

            moves = None
            if isOdd:
                moves = game_rules.getLegalMoves(board,self.symbol)
            else:
                symbol = 'x' if self.symbol == 'o' else 'o'
                moves = game_rules.getLegalMoves(board,symbol)

            # check for end state
            if len(moves) == 0:
                return super(MinimaxPlayer,self).h1(board,self.symbol)
            
            # want max
            if isOdd:
                optimalEval = NEG_INF
                for move in moves:
                    newBoard = game_rules.makeMove(board,move)
                    optimalEval = max(optimalEval,minimax(newBoard,currentDepth+1,False))
                return optimalEval
            # want min
            else:
                optimalEval = POS_INF
                for move in moves:
                    newBoard = game_rules.makeMove(board,move)
                    optimalEval = min(optimalEval,minimax(newBoard,currentDepth+1,True))
                return optimalEval
Example #2
0
    def minimax(self, symbol, board, depth):
        legalMoves = game_rules.getLegalMoves(board, symbol)
        next_move = Move()
        if depth == 0 or len(legalMoves) == 0:
            next_move.cost = self.h1(board, symbol)
            return next_move

        if symbol == "x":
            new_symbol = "o"
        else:
            new_symbol = "x"

        if symbol == self.symbol:
            next_move.cost = NEG_INF
            for move in legalMoves:
                val = self.minimax(new_symbol,
                                   game_rules.makeMove(board, move), depth - 1)
                if val.cost > next_move.cost:
                    next_move.cost = val.cost
                    next_move.move = move
            return next_move
        else:
            next_move.cost = POS_INF
            for move in legalMoves:
                val = self.minimax(new_symbol,
                                   game_rules.makeMove(board, move), depth - 1)
                if val.cost < next_move.cost:
                    next_move.cost = val.cost
                    next_move.move = move
            return next_move
Example #3
0
 def _handleTurnO(self, playerBoard, board, move_pair):
     move = move_pair if isinstance(
         self.p2, HumanPlayer) else self.p2.getMove(playerBoard)
     if not move: self.state = X_VICTORY
     elif game_rules.isLegalMove(board, 'o', move, False):
         self.board = game_rules.makeMove(board, move)
         self.state = X_TURN
Example #4
0
 def _handleTurnO(self, playerBoard, board):
   self.state = X_TURN
   move = self.p2.getMove(playerBoard)
   if game_rules.isLegalMove(board, 'o', move, False):
     self.board = game_rules.makeMove(board, move)
   else:
     self.state = X_VICTORY
Example #5
0
    def max_value(self, board, player, curr_depth):

        #check if the max depth is reached - then return the utility function
        if curr_depth == 0:
            new_utility = self.h1(board, player)
            new_utility_move = [new_utility, None]
            return new_utility_move
        curr_depth = curr_depth - 1
        available_moves = game_rules.getLegalMoves(board, player)
        #check if it is a leaf node -> return utility function
        if len(available_moves) == 0:
            new_utility = self.h1(board, player)
            new_utility_move = [new_utility, None]
            return new_utility_move

        check_utility = [NEG_INF, None]
        for move in available_moves:

            new_player = self.change_player(player)
            new_board = game_rules.makeMove(board, move)
            new_utility = self.min_value(new_board, new_player, curr_depth)

            #check if the utility returned is greater than the current utility
            #update the utility and the move associated with that
            if new_utility[0] > check_utility[0]:
                check_utility[0] = new_utility[0]
                check_utility[1] = move

        return check_utility
Example #6
0
    def min_value(self, board, player, curr_depth):

        if curr_depth == 0:
            new_utility = self.h1(board, player)
            new_utility_move = [new_utility, None]
            return new_utility_move
        curr_depth = curr_depth - 1

        available_moves = game_rules.getLegalMoves(board, player)
        if len(available_moves) == 0:
            new_utility = self.h1(board, player)
            new_utility_move = [new_utility, None]
            return new_utility_move

        check_utility = [POS_INF, None]
        for move in available_moves:
            new_player = self.change_player(player)
            new_board = game_rules.makeMove(board, move)
            new_utility = self.max_value(new_board, new_player, curr_depth)

            if new_utility[0] < check_utility[0]:
                check_utility[0] = new_utility[0]
                check_utility[1] = move

        return check_utility
Example #7
0
    def min_valuealpha_beta(self, board, player, curr_depth, alpha, beta):

        if curr_depth == 0:
            new_utility = self.h1(board, player)
            new_utility_move = [new_utility, None]
            return new_utility_move
        curr_depth = curr_depth - 1

        available_moves = game_rules.getLegalMoves(board, player)
        if len(available_moves) == 0:
            new_utility = self.h1(board, player)
            new_utility_move = [new_utility, None]
            return new_utility_move

        check_utility = [POS_INF, None]
        for move in available_moves:
            new_player = self.change_player(player)
            new_board = game_rules.makeMove(board, move)
            new_utility = self.max_value_alpha_beta(new_board, new_player,
                                                    curr_depth, alpha, beta)

            if new_utility[0] < check_utility[0]:
                check_utility[0] = new_utility[0]
                check_utility[1] = move

            beta = min(beta, new_utility[0])
            if alpha >= beta:
                break

        return check_utility
Example #8
0
 def Max_Value(self, board, a, b, depth, symbol):
     # set initial max value to minus infinity
     #val = -1000000000
     # get legalmoves
     legalMoves = game_rules.getLegalMoves(board,symbol)
     best = (-1000000000, None)
     # return utility when no more legalmoves
     if (len(legalMoves) == 0 or depth == 0):
         return (self.h1(board, symbol), None)
     
     for i in range(len(legalMoves)):
         nextBoard = game_rules.makeMove(board, legalMoves[i])
         #nextBoard = game_rules.makeMove(board, legalMoves[i])
         # when meet depth limit, then use heuristic function to replace the val Min_Value
         if symbol == 'x':
             val = self.Min_Value(nextBoard, a, b, depth - 1, 'o')[0]
         else:
             val = self.Min_Value(nextBoard, a, b, depth - 1, 'x')[0]
         if best[0] < val:
            best = (val,legalMoves[i])
         if (best[0] >= b):
             return best
         if (a < best[0]):
             a = best[0]
     return best
Example #9
0
 def _handleTurnX(self, playerBoard, board, move_pair):
     #move = move_pair if isinstance(self.p1, HumanPlayer) else self.p1.getMove(playerBoard)
     move = move_pair if move_pair is not None else self.p1.getMove(
         playerBoard)
     if not move: self.state = O_VICTORY
     elif game_rules.isLegalMove(board, 'x', move, False):
         self.log.write(str(move) + '\n')
         self.board = game_rules.makeMove(board, move)
         self.state = O_TURN
Example #10
0
 def _minValue(self, board, depth, symbol):
   legalMoves = game_rules.getLegalMoves(board, symbol)
   if depth == 0 or len(legalMoves) == 0:
     return (self._assessBoard(board, symbol), None)
   best = (1000000000, None)
   for move in legalMoves:
     child = game_rules.makeMove(board, move)
     (score, _) = self._minValue(child, depth-1, 'o' if symbol == 'x' else 'x')
     best = min(best, (score, move))
   return best
Example #11
0
        def minimax_recur(depth, board, turn, currsymbol):
            #            print('**minimax_recur board: ', board)
            #            print('**current player: ', currsymbol)
            legalMoves = game_rules.getLegalMoves(board,
                                                  currsymbol)  #self.symbol)
            #            print('**all legal moves: ', legalMoves)

            if len(legalMoves) == 0 or depth == 0:
                #                print('**case1')
                #                print('**heuristic: ', self.h1(board, currsymbol))
                return None, self.h1(board, currsymbol)

            val = (POS_INF, NEG_INF)[turn]
            #            print('**val = ', val)
            move = None

            tmpmove = (None, None)

            for eachmove in legalMoves:
                #                print('**now move: ', eachmove)

                if tmpmove[0] != None:
                    board = self.originalboard(board, tmpmove[0], tmpmove[1],
                                               currsymbol)

#                print('board: ', board)

                tmpmove = (eachmove[0], eachmove[len(eachmove) - 1]
                           )  #start -> end
                #                print('**tmpmove: ', tmpmove)

                board = game_rules.makeMove(board, eachmove)
                #                print('**nowboard: ', board)
                succmove, succval = minimax_recur(depth - 1, board, not turn,
                                                  self.changeturn(currsymbol))
                #                print('*****now val:', succval)

                #                print('current move: ', eachmove)
                #                print('bestval: ', val)
                #                print('bestmove: ', move)
                a, b = (((move, val), (eachmove, succval))[succval < val],
                        ((move, val), (eachmove,
                                       succval))[succval > val])[turn]
                move = a
                val = b
#                print('**bestmove: ', move)
#                print('**bestval: ', val)

            board = self.originalboard(board, tmpmove[0], tmpmove[1],
                                       currsymbol)

            #            print('then return bestmove: ', move)
            #            print('then return bestval: ', val)
            return move, val
Example #12
0
 def decision(board,moves):
     cloneBoard = deepcopy(board)
     optimalMove = moves[0]
     optimalEval = NEG_INF
     for move in moves:
         newBoard = game_rules.makeMove(cloneBoard,move)
         val = minimax(newBoard,1,False) #send with depth 1, as this is depth 0, the root
         if val > optimalEval: #final max check
             optimalMove = move
             optimalEval = val
     return optimalMove
Example #13
0
 def decision(board,moves):
     cloneBoard = deepcopy(board) # clone used for simulation
     optimalMove = moves[0]
     alpha = NEG_INF
     beta = POS_INF
     for move in moves:
         newBoard = game_rules.makeMove(cloneBoard,move)
         val = alphabeta(newBoard,1,False,alpha,beta) #send with depth 1, as this is depth 0, the root
         if val > alpha: #final max check
             optimalMove = move
             alpha = val
     return optimalMove
Example #14
0
        def alphabeta(board,currentDepth,isOdd,alpha,beta):
            # Note: bool isOdd basically tells us we want the max

            #checking this here REALLY boosts efficiency (due to getLegalMoves getting skipped)
            if currentDepth == self.maxDepth:
                return super(AlphaBetaPlayer,self).h1(board,self.symbol)

            moves = None
            symbol = None
            if isOdd:
                moves = game_rules.getLegalMoves(board,self.symbol)
            else:
                symbol = 'x' if self.symbol == 'o' else 'o'
                moves = game_rules.getLegalMoves(board,symbol)

            # check for end state
            if len(moves) == 0:
                # so actually, I ran this using self.h1 and super(...).h1, and super gave me quicker test results... weird
                return super(AlphaBetaPlayer,self).h1(board,self.symbol)
            
            # want max
            if isOdd:
                loc_alpha = alpha
                for move in moves:
                    # check if b <= a; if so exit loop
                    if beta <= loc_alpha:
                        return loc_alpha
                    newBoard = game_rules.makeMove(board,move)
                    loc_alpha = max(loc_alpha,alphabeta(newBoard,currentDepth+1,False,loc_alpha,beta))
                return loc_alpha
            # want min
            else:
                loc_beta = beta
                for move in moves:
                    # check if b <= a; if so exit loop
                    if loc_beta <= alpha:
                        return loc_beta
                    newBoard = game_rules.makeMove(board,move)
                    loc_beta = min(loc_beta,alphabeta(newBoard,currentDepth+1,True,alpha,loc_beta))
                return loc_beta
Example #15
0
    def ab_pruning(self, symbol, board, alpha, beta, depth):
        legalMoves = game_rules.getLegalMoves(board, symbol)
        next_move = Move()
        if depth == 0 or len(legalMoves) == 0:
            next_move.cost = self.h1(board, symbol)
            return next_move

        if symbol == "x":
            new_symbol = "o"
        else:
            new_symbol = "x"

        if symbol == self.symbol:
            next_move.cost = NEG_INF
            for move in legalMoves:
                val = self.ab_pruning(new_symbol,
                                      game_rules.makeMove(board, move), alpha,
                                      beta, depth - 1)
                if val.cost > next_move.cost:
                    next_move.cost = val.cost
                    next_move.move = move

                alpha = max(alpha, val.cost)
                if beta <= alpha:
                    break
            return next_move
        else:
            next_move.cost = POS_INF
            for move in legalMoves:
                val = self.ab_pruning(new_symbol,
                                      game_rules.makeMove(board, move), alpha,
                                      beta, depth - 1)
                if val.cost < next_move.cost:
                    next_move.cost = val.cost
                    next_move.move = move
                beta = min(beta, val.cost)
                if beta <= alpha:
                    break
            return next_move
Example #16
0
 def Min_Value(self, board, depth, symbol):
     legalMoves = game_rules.getLegalMoves(board, symbol)
     if depth == 0 or len(legalMoves) == 0:
         return (self.h1(board, symbol), None)
     best = (POS_INF, None)
     for i in range(len(legalMoves)):
         nextBoard = game_rules.makeMove(board, legalMoves[i])
         if symbol == 'x':
             val = self.Max_Value(nextBoard, depth - 1, 'o')[0]
         else:
             val = self.Max_Value(nextBoard, depth - 1, 'x')[0]
         if best[0] > val:
             best = (val, legalMoves[i])
     return best
Example #17
0
    def get_min(self, board, symbol, depth):
        legal_moves = game_rules.getLegalMoves(board, symbol)

        if depth == 0 or len(legal_moves) == 0:
            result = [self.h1(board, symbol), None]
            return result

        else:
            our_move = None
            min_val = float('inf')
            for move in legal_moves:
                new_board = game_rules.makeMove(board, move)
                val = self.get_max(new_board, self.opposite_symbol(symbol),
                                   depth - 1)[0]
                if val < min_val:
                    min_val = val
                    our_move = move
            result = [min_val, our_move]
            return result
Example #18
0
    def get_max(self, board, symbol, depth, alpha, beta):
        legal_moves = game_rules.getLegalMoves(board, symbol)

        if depth == 0 or len(legal_moves) == 0:
            result = [self.h1(board, symbol), None]
            return result

        else:
            our_move = None
            max_val = float('-inf')
            for move in legal_moves:
                new_board = game_rules.makeMove(board, move)
                val = self.get_min(new_board, self.opposite_symbol(symbol),
                                   depth - 1, alpha, beta)[0]
                if val > max_val:
                    max_val = val
                    our_move = move
                if val > alpha:
                    alpha = val
                if alpha >= beta:
                    break
            result = [max_val, our_move]
            return result
Example #19
0
        def alphabeta_recur(depth, board, turn, currsymbol, alpha, beta):
            #            print('** now board: ', board)
            #            print('** now player: ', currsymbol)
            legalMoves = game_rules.getLegalMoves(board, currsymbol)
            #            print('all legal moves: ', legalMoves)

            if len(legalMoves) == 0 or depth == 0:
                #                print('case1')
                #                print('h1: ', self.h1(board, currsymbol))
                # only return heuristic
                # self.printCurrentInfo(depth, self.heuristic(board, self), None)
                return None, self.h1(board, currsymbol)

#            print('turn: ', turn)
            val = (POS_INF, NEG_INF)[turn]
            #            print('val: ', val)

            move = None

            tmpmove = (None, None)

            # judge every nodes possible, select the biggest/smallest one
            for eachmove in legalMoves:
                #                print('now eachmove: ', eachmove)

                if tmpmove[0] != None:
                    board = self.originalboard(board, tmpmove[0], tmpmove[1],
                                               currsymbol)

                tmpmove = (eachmove[0], eachmove[len(eachmove) - 1])
                #                print('new move: ', tmpmove)

                board = game_rules.makeMove(board, eachmove)
                #                print('board: ', board)

                succmove, succval = alphabeta_recur(
                    depth - 1, board, not turn, self.changeturn(currsymbol),
                    alpha, beta)
                #                print('now succval: ', succval)

                #                print('check a,b: ')
                #                print('succval: ', succval)
                #                print('val: ', val)
                #                print('eachmove: ', eachmove)
                #                print('move: ', move)
                #                print('turn: ', turn)
                a, b = (((move, val), (eachmove, succval))[succval < val],
                        ((move, val), (eachmove,
                                       succval))[succval > val])[turn]
                move = a
                val = b

                #                print('move: ', move)
                #                print('val: ', val)

                if turn:
                    alpha = (alpha, val)[alpha <= val]
#                    print('alpha: ', alpha)
                else:
                    beta = (beta, val)[beta >= val]


#                    print('beta: ', beta)
                if beta <= alpha:
                    #                    print('beta < alpha, break', beta, alpha)
                    break

            board = self.originalboard(board, tmpmove[0], tmpmove[1],
                                       currsymbol)

            #            print('then return move: ', move)
            #            print('then return bestval: ', val)
            return move, val