Exemplo n.º 1
0
 def available_move(self, board):
     res = []
     for c in range(self.col // 2, self.col):
         for r in range(self.row - 1, -1, -1):
             if board[r][c] == 0:
                 res.append(Move(c, r))
                 if self.g: break
     for c in range(self.col // 2 - 1, -1, -1):
         for r in range(self.row - 1, -1, -1):
             if board[r][c] == 0:
                 res.append(Move(c, r))
                 if self.g: break
     return res
Exemplo n.º 2
0
    def minimax(self, state, maxdepth, best_move_dict={}, depth=0, player=SELF, alpha=-INF, beta=INF):
        """
        Calculates the next possible states and calculates the optimal value
        using minimax with alpha beta pruning. If the state is a win state or
        at depth = number of rows, returns a heuristic score instead.
        """
        is_win = state.is_win()
        if is_win == SELF or is_win == -1:
            return INF
        if is_win == OPPONENT:
            return -INF

        if depth == maxdepth:
            return state.heuristic_score(SELF) - state.heuristic_score(OPPONENT)

        best_move = None
        next_player = SELF if player == OPPONENT else OPPONENT
        best_val = -INF if player == SELF else INF

        for r, c in state.get_moves():
            move = Move(c, r)
            if not self.g:
                state.available.remove((r, c))
            if best_move is None:
                best_move = move
            value = self.minimax(
                state=state.make_move(move, player),
                maxdepth=maxdepth,
                best_move_dict=best_move_dict,
                depth=depth + 1, player=next_player, alpha=alpha, beta=beta
            )
            if not self.g:
                state.available.add((r, c))

            if player == SELF:
                if value > best_val:
                    best_val = value
                    best_move = Move(c, r)
                alpha = max(alpha, best_val)
            else:
                if value < best_val:
                    best_val = value
                    best_move = Move(c, r)
                beta = min(beta, best_val)
            if beta <= alpha:
                break

        if depth == 0:
            best_move_dict['result'] = best_move
        return best_val
Exemplo n.º 3
0
    def best_move(self) -> Move:
        moves = self.board.get_all_possible_moves(self.color)
        smart_move = Move([])
        alpha = -math.inf
        beta = math.inf
        for checkers in moves:
            for move in checkers:
                self.board.make_move(move, self.color)
                heuristic = self.alpha_beta_prune(1, self.opponent[self.color],
                                                  alpha, beta)
                self.board.undo()
                if heuristic > alpha:
                    alpha = heuristic
                    smart_move = Move(move)

        return smart_move
Exemplo n.º 4
0
    def get_move(self, move):
        if len(move) != 0:
            self.board.make_move(move, self.opponent[self.color])
        else:
            self.color = 1

        moves = self.board.get_all_possible_moves(self.color)
        bestScore = -9999
        bestMove = Move([])
        for elem in moves:
            for move in elem:

                # for elem in move:
                # make deep copy of board
                # print("max making move: ", move)
                self.board.make_move(move, self.color)
                score = self.alphaBeta(self.board, 3, -9999, 9999, False)
                # print("score: ", score)
                if score >= bestScore:
                    bestScore = score
                    bestMove = move
                # print("undo: ", move)
                self.board.undo()
        # print("best move:", bestMove)
        print("best score: ", bestScore)
        self.board.make_move(bestMove, self.color)
        return bestMove
Exemplo n.º 5
0
    def get_move(self, move):
        if move.row == -1 and move.col == -1:
            move = Move(self.col // 2, self.row // 2)
            self.board = self.board.make_move(move, AI)
            return move

        self.board = self.board.make_move(move, OP)

        if self.g: move, _ = self.max_val(self.board.board, MIN, MAX, 6)
        else: move, _ = self.max_val(self.board.board, MIN, MAX, 4)

        while self.board.board[move.row][move.col] != 0:
            move.col = randint(0, self.col - 1)
            move.row = randint(0, self.row - 1)

        self.board = self.board.make_move(move, AI)
        return move
Exemplo n.º 6
0
 def get_move(self,move):
     self.communicator.send(str(move).encode())
     ai_move,err = self.communicator.recv(return_stderr=True)
     if len(err) > 1:
         print("exception")
         raise Exception(err.decode())
     ai_move = ai_move.decode().split("\n")[-1].rstrip()
     return Move.from_str(ai_move)
Exemplo n.º 7
0
    def get_move(self,move):
        """
        get_move function for NetworkAI called from the gameloop in the main module.
        @param move: A Move object describing the move.
        @return res_move: A Move object describing the move manualAI wants to make. This move is a random move from the set of valid moves.
        @raise :
        """

        sleep(0.3)
        #TODO: Combine two branches
        if self.mode == 'host':
            if move.seq:
                print('SENT:', str(move))
                sentence = str(move).encode()
                self.connectionSocket.send(sentence)

            response = self.connectionSocket.recv(1024).decode().rstrip()
            try:
                res_move = Move.from_str(response)
                if not res_move.seq:
                    raise Exception
            except:
                print("You win. Your peer crashed.")
                raise Exception
            print('GET:', res_move)
            return res_move
        else:
            sleep(0.1)
            if move.seq:
                print('SENT:', str(move))
                sentence = str(move).encode()
                self.topSocket.send(sentence)
            response = self.topSocket.recv(1024).decode().rstrip()
            try:
                res_move = Move.from_str(response)
                print(res_move.seq)
                if not res_move.seq:
                    raise Exception
            except:
                print("You win. Your peer crashed.")
                raise Exception
            print('GET:', res_move)
            return res_move
Exemplo n.º 8
0
    def max_val(self, board, alpha, beta, deep):
        if deep == 0: return Move(0, 0), self.heuristic(board, AI)
        val = MIN

        res = [Move(0, 0), 0]
        moves = self.available_move(board)

        for mv in moves:
            board[mv.row][mv.col] = AI
            _, score = self.min_val(board, alpha, beta, deep - 1)
            board[mv.row][mv.col] = 0

            if score > val:
                val = score
                res = [mv, score]
                if val >= self.win: break

            alpha = max(alpha, val)
            if alpha >= beta: break
        return res
Exemplo n.º 9
0
 def _get_move_ng(self, move: Move) -> Move:
     global _MAX_DEPTH
     _MAX_DEPTH = 4
     if Point(-1, -1) == move:
         result = Move(int(self.col / 2), int(self.row / 2))
     else:
         self.board.make_internal_move(move, Player.op)
         result = self.board.max_search(_MAX_DEPTH, self.board.MIN,
                                        self.board.MAX)[1]
     self.board.make_internal_move(result, Player.me)
     return result
Exemplo n.º 10
0
 def get_move(self, move):
     while True:
         try:
             c, r = map(lambda x: int(x), input("{col} {row}:").split(' '))
         except KeyboardInterrupt:
             raise KeyboardInterrupt
         except:
             print('invalid move')
             continue
         else:
             break
     return Move(c, r)
Exemplo n.º 11
0
    def min_val(self, board, alpha, beta, deep):
        if deep == 0: return Move(0, 0), self.heuristic(board, OP)
        val = MAX

        res = [Move(0, 0), 0]
        moves = self.available_move(board)

        for mv in moves:
            board[mv.row][mv.col] = OP
            _, score = self.max_val(board, alpha, beta, deep - 1)
            board[mv.row][mv.col] = 0

            if score < val:
                val = score
                res = [mv, score]
                if val <= -self.win:
                    break

            beta = min(beta, val)
            if alpha >= beta: break
        return res
Exemplo n.º 12
0
    def minimax(self,
                state,
                depth=0,
                player=SELF,
                alpha=float('-inf'),
                beta=float('inf')):
        """
        Calculates the next possible states and calculates the optimal value
        using minimax with alpha beta pruning. If the state is a win state or
        at depth = number of rows, returns a heuristic score instead.
        """
        is_win = state.is_win()
        if is_win == SELF or is_win == -1:
            return (float('inf'), Move(0, 0))
        if is_win == OPPONENT:
            return (float('-inf'), Move(0, 0))

        depth_reached = False
        if not self.g:
            if self.col >= 7 and depth == 4:
                depth_reached = True
            if depth == 5:
                depth_reached = True
        else:
            if depth == self.row:
                depth_reached = True

        if depth_reached:
            return (state.heuristic_score(SELF) -
                    state.heuristic_score(OPPONENT), Move(0, 0))

        best_move = None
        next_player = SELF if player == OPPONENT else OPPONENT
        best_val = float('-inf') if player == SELF else float('inf')

        for r, c in state.get_moves():
            move = Move(c, r)
            if not self.g:
                state.available.remove((r, c))
            if best_move is None:
                best_move = move
            value, _move = self.minimax(state.make_move(move, player),
                                        depth + 1, next_player, alpha, beta)
            if not self.g:
                state.available.add((r, c))

            if player == SELF:
                if value > best_val:
                    best_val = value
                    best_move = Move(c, r)
                alpha = max(alpha, best_val)
            else:
                if value < best_val:
                    best_val = value
                    best_move = Move(c, r)
                beta = min(beta, best_val)
            if beta <= alpha:
                break

        return best_val, best_move
Exemplo n.º 13
0
 def MiniMax(self):
     alpha = -inf
     beta = inf
     best_move = Move([])
     moves = self.board.get_all_possible_moves(self.color)
     for checker_index in range(0, len(moves)):
         for move_index in range(0, len(moves[checker_index])):
             move = moves[checker_index][move_index]
             if len(move) == 0:
                 pass
             depth = 0
             # *(1) start: undo later
             self.board.make_move(move, self.color)
             value = self.get_MinVal(depth + 1, alpha, beta)
             if value > alpha:
                 alpha = value
                 best_move = move
             # *(1) end
             self.board.undo()
     return best_move
Exemplo n.º 14
0
    def make_internal_move(self, move: Move, player: Player) -> None:
        for i in range(self.row - 1, -1, -1):
            if self.board[i][move.col] == Player.no:
                self.board[i][move.col] = player
                move.row = i
                self.move.append(move)
                self.move_player.append(player)
                break
            try:
                i > 0
            except InvalidMoveError:
                print("Invalid Move!")

        for i in range(8):
            tmp = move + all_dir[i]
            if self.is_inside(tmp):
                self.has_neighbor[i][tmp.row][tmp.col] = True
                tmp += all_dir[i]
                if self.is_inside(tmp):
                    self.has_indirect_neighbor[i][tmp.row][tmp.col] = True

        super().make_internal_move(move, player)
Exemplo n.º 15
0
 def get_move(self, move):
     if self.g == 0:
         return Move(randint(0, self.col - 1), randint(0, self.row - 1))
     else:
         return Move(randint(0, self.col - 1), 0)
Exemplo n.º 16
0
    def get_move(self, move):
        if self.g == 0:
            # we move first
            if (move.col == -1 and move.row == -1):
                # take middle element so that increases connect on many sides
                newCol = math.ceil((self.col - 1) / 2)
                newRow = math.ceil((self.row - 1) / 2)

            # subsequent moves
            else:
                #set recent move of player 2 on board
                self.objB.make_my_move(move.col, move.row, 2)

                # add all adjecent cells which are empty to possible moves to choose from
                # newCol, newRow = self.add_adj_cells(move)

                newCol, newRow = self.get_heuristic_moves_gravity_off()
                print("newCol: ", newCol, ", newRow: ", newRow)
                #self.objB.my_show_board();

                # check around this move if it makes it win for 2
                for r in range(0, self.row):
                    for c in range(0, self.col):

                        # if this move makes player2 to win then move to that position
                        if (self.check_next_win(c, r, 2)
                                | self.check_next_win(c, r, 1)):
                            self.objB.make_my_move(c, r, 1)
                            return Move(c, r)

                # # else if no such move makes player2 to win then make a random move
                # newCol = randint(0,self.col-1)
                # newRow = randint(0,self.row-1)

                # while(not self.objB.is_valid_move(newCol, newRow, True)):
                #     newCol = randint(0,self.col-1)
                #     newRow = randint(0,self.row-1)

            self.objB.make_my_move(newCol, newRow, 1)

            return Move(newCol, newRow)

        elif self.g == 1:
            if (move.col == -1 and move.row == -1):
                # take middle element so that increases connect on many sides
                newCol = math.ceil((self.col - 1) / 2)
                self.objB.make_my_move(newCol,
                                       self.possibleMovesForGravity[newCol], 1)
                self.possibleMovesForGravity[newCol] -= 1
                return Move(newCol, self.possibleMovesForGravity[newCol] + 1)

            else:
                #print("Opponent Move: ", move.col, self.possibleMovesForGravity[move.col])
                # print("Opponent Move: ", move.col, move.row)

                self.objB.make_my_move(move.col,
                                       self.possibleMovesForGravity[move.col],
                                       2)
                #print("Make Opponent Move")
                self.possibleMovesForGravity[move.col] -= 1
                # print(move.col, self.possibleMovesForGravity[move.col])

                # print(self.possibleMovesForGravity)
                for c in range(0, self.col):
                    if (self.possibleMovesForGravity[c] < 0):
                        continue

                    #print(c, self.possibleMovesForGravity[c])
                    #print(self.check_opponent_win(c, self.possibleMovesForGravity[c]))

                    if (self.check_next_win(c, self.possibleMovesForGravity[c],
                                            2)
                            | self.check_next_win(
                                c, self.possibleMovesForGravity[c], 1)):
                        self.objB.make_my_move(c,
                                               self.possibleMovesForGravity[c],
                                               1)
                        self.possibleMovesForGravity[c] -= 1
                        #print("My Move: ", c, self.possibleMovesForGravity[c]+1)
                        #print("Poss Move: ", self.possibleMovesForGravity)
                        return Move(c, self.possibleMovesForGravity[c] + 1)

                # sort by the evaluation result
                evalList = self.get_heuristic_moves()
                evalList.sort(key=lambda evalList: -evalList[1])

                for i in range(0, len(evalList)):
                    c = evalList[i][0]
                    if (self.possibleMovesForGravity[c] < 0):
                        continue

                    #print("c: ", c)
                    #print("Befroe Poss Move: ", self.possibleMovesForGravity)
                    self.objB.make_my_move(c, self.possibleMovesForGravity[c],
                                           1)
                    self.possibleMovesForGravity[c] -= 1
                    #print("After Poss Move: ", self.possibleMovesForGravity)

                    if (self.check_next_win(c, self.possibleMovesForGravity[c],
                                            2)):
                        #print("Here", c)
                        self.possibleMovesForGravity[c] += 1
                        self.objB.revert_my_move(
                            c, self.possibleMovesForGravity[c])
                        continue

                    #print("My Move: ", c, self.possibleMovesForGravity[c]+1)
                    #print("Poss Move: ", self.possibleMovesForGravity)
                    return Move(c, self.possibleMovesForGravity[c] + 1)

                # when got out of loop
                c = randint(0, self.col - 1)
                while (not self.objB.is_valid_move(
                        c, self.possibleMovesForGravity[c])):
                    c = randint(0, self.col - 1)

                self.objB.make_my_move(c, self.possibleMovesForGravity[c], 1)
                self.possibleMovesForGravity[c] -= 1

                return Move(c, self.possibleMovesForGravity[c] + 1)
Exemplo n.º 17
0
 def get_move(self,move):
     self.board.make_move(move,1)
     if self.g == 0:
         return Move(randint(0,self.col-1),randint(0,self.row-1))
     else:
         return Move(randint(0,self.col-1),0)