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
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
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
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
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
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)
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
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
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
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)
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
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
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
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)
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)
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)
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)