def get_player_move() -> Move: player_move: Move = Move(-1) while player_move not in board.legal_moves: play: int = int(input("Enter a legal square (0-8):")) player_move = Move(play) return player_move
def test_diagonal_win(self): self.test_board.place_move(Move(2, 0, PlayerType.CIRCLE)) self.test_board.place_move(Move(1, 1, PlayerType.CIRCLE)) win_move = Move(0, 2, PlayerType.CIRCLE) self.test_board.place_move(win_move) assert self.test_board.is_winning_move(win_move) == True
def test_is_winning_move_horizontal(self): test_moves = [Move(i, 0, PlayerType.CIRCLE) for i in range(4)] for move in test_moves: self.test_board.place_move(move) winning_move = Move(4, 0, PlayerType.CIRCLE) self.test_board.place_move(winning_move) self.assertTrue(self.test_board.is_winning_move(winning_move))
def test_is_winning_move_diagonal_trivial(self): test_moves = [Move(i, i, PlayerType.CIRCLE) for i in range(4)] for move in test_moves: self.test_board.place_move(move) winning_move = Move(4, 4, PlayerType.CIRCLE) self.test_board.place_move(winning_move) self.assertTrue(self.test_board.is_winning_move(winning_move))
def get_player_move() -> Move: # initialise Move to a negative number player_move: Move = Move(-1) # as for a move. condition will be satisfied as Move(-1) # is not a legal move while player_move not in board.legal_moves: play: int = int(input("Enter a legal square (0-8): ")) player_move = Move(play) return player_move
def select_move(self, game_state): candidates = [] for r in range(1, BOARD_SIZE + 1): for c in range(1, BOARD_SIZE + 1): candidate = Point(row=r, col=c) if game_state.is_valid_move(Move(candidate)): candidates.append(candidate) if not candidates: print('Game over') return Move(random.choice(candidates))
def test_is_pawn_jump(self): board = Board() board.move(E2, E4) board.move(D2, D3) board.move(H7, H5) self.assertTrue(is_pawn_jump(board, Move(E2, E4), WHITE)) self.assertFalse(is_pawn_jump(board, Move(D2, D3), WHITE)) self.assertTrue(is_pawn_jump(board, Move(H7, H5), BLACK)) with self.assertRaises(InternalError): is_pawn_jump(board, Move(H6, H4), BLACK)
def test_is_winning_move_diagonal_complex(self): test_moves = [ Move(x, y, PlayerType.CIRCLE) for x, y in [(5, 5), (7, 3), (8, 2), (9, 1)] ] for move in test_moves: self.test_board.place_move(move) winning_move = Move(6, 4, PlayerType.CIRCLE) self.test_board.place_move(winning_move) self.assertTrue(self.test_board.is_winning_move(winning_move))
def test_is_winning_move_diagonal_inter(self): test_moves = [Move(i, i, PlayerType.CIRCLE) for i in range(2)] for move in test_moves: self.test_board.place_move(move) test_moves = [Move(i, i, PlayerType.CIRCLE) for i in range(3, 5)] for move in test_moves: self.test_board.place_move(move) winning_move = Move(2, 2, PlayerType.CIRCLE) self.test_board.place_move(winning_move) self.assertTrue(self.test_board.is_winning_move(winning_move))
def _drawSquareHighlights(self): size = ChessGui.SQR_SIZE app = self._app id = self._canvas if self._from != None: (mx, my) = self._from my = 7 - my color = "#ee0" app.addCanvasRectangle(id, mx * size, my * size, size, size, width=3, outline=color, fill=None) if self._mouseOverSqr != None: (mx, my) = self._mouseOverSqr color = "#090" if self._from != None and Move( self._from, self._mouseOverSqr) in self._board.possibleMoves(): color = "#ee0" # Possible move elif self._board.get(mx, my) == self._currentColor: color = "#cc0" # Possible piece to move app.addCanvasRectangle(id, mx * size, (7 - my) * size, size, size, width=2, outline=color, fill=None)
def _do_aimove(self): ts = self.train_settings while not self.board.current_move.analysis_ready: self.info.text = "Thinking..." time.sleep(0.05) # select move current_move = self.board.current_move pos_moves = [ (d["move"], float(d["scoreLead"]), d["evaluation"]) for i, d in enumerate(current_move.ai_moves) if i == 0 or int(d["visits"]) >= ts["balance_play_min_visits"] ] sel_moves = pos_moves[:1] # don't play suicidal to balance score - pass when it's best if self.ai_balance.active and pos_moves[0][0] != "pass": sel_moves = [ (move, score, move_eval) for move, score, move_eval in pos_moves if move_eval > ts["balance_play_randomize_eval"] and -current_move.player_sign * score > 0 or move_eval > ts["balance_play_min_eval"] and -current_move.player_sign * score > ts["balance_play_target_score"] ] or sel_moves aimove = Move(player=self.board.current_player, gtpcoords=random.choice(sel_moves)[0], robot=True) if len(sel_moves) > 1: aimove.x_comment[ "ai"] = "AI Balance on, moves considered: " + ", ".join( f"{move} ({aimove.format_score(score)})" for move, score, _ in sel_moves) + "\n" self.play(aimove)
def test_init(self): b1 = Board() self.assertEqual(WHITE, b1._player) self.assertNotEqual(WHITE, b1[4][2]) self.assertEqual(4, len(b1)) self.assertEqual(4, len(b1._moves)) self.assertEqual(2, b1.count(WHITE)) self.assertEqual(2, b1.count(BLACK)) m2 = Move(WHITE, 4, 2) b2 = Board(b1, m2) self.assertEqual(BLACK, b2._player) self.assertEqual(WHITE, b2[4][2]) self.assertEqual(WHITE, b2[4][3]) self.assertEqual(5, len(b2)) self.assertEqual(3, len(b2._moves)) self.assertEqual(4, b2.count(WHITE)) self.assertEqual(1, b2.count(BLACK)) b0 = Board(b1, None) b0._p[3][3] = None b0._p[3][4] = None b0._p[4][3] = None b0._p[4][4] = None b0._moves = [] self.assertNotEqual(WHITE, b0[3][3]) self.assertEqual(0, len(b0)) self.assertEqual(0, len(b0._moves)) self.assertEqual(0, b0.count(WHITE)) self.assertEqual(0, b0.count(BLACK))
def handleUserInput(self, event): for i in range(9): for j in range(9): pixel_x = (i + 1) * CELL_PIXELS pixel_y = (j + 1) * CELL_PIXELS square_x = math.pow((event.x - pixel_x), 2) square_y = math.pow((event.y - pixel_y), 2) distance = math.sqrt(square_x + square_y) # since there is noly one intersection such that the distance between it # and where the user clicks is less than 15, it is not necessary to find # the actual least distance if (distance < 15): print(f"board pos {i},{j}") if self.board.get(i, j) != 0: print( f"board pos {i},{j} already has piece {self.board.get( i,j) }" ) return move = Move(i, j) print(f"User's move is {move}") self.board.makeMove(move) invalid_pos = False row, col = i, j self.boardCanvas.drawState() self.master.update() print(self.board) self.unbind('<Button-1>') self.master.after(100, self.gameLoop)
def __make_my_move(self): if self.client.winner: print("winner: ", self.client.winner) return True move = self.board.decision() if not move: move = Move(0, 0, is_pass=True) result, _ = self.board.try_move(move) if result == ILLEGAL_MOVE: raise Exception("illegal move") print("me: ", move) try: if move.is_pass: self.client.make_move("pass") else: self.client.make_move(str(move)) except gthclient.MoveError as e: if e.cause == e.ILLEGAL: print("me: made illegal move, passing") self.client.make_move("pass") except gthclient.ProtocolError as e: # python library doesn't handle game draw, so manually # handle it here if e.expression == 325 or e.expression == 326: print("game drawn") return True return False
def play(user): board = user.start_board() board.print_board() move_input = '' quit_check = '' while board.status.lower() == 'play': move_input = str('Available moves: l/r/u/d/q : ').lower() while move_input not in ('l', 'r', 'u', 'd', 'q'): move_input = input('Available moves: (l/r/u/d/q) : ') if move_input == 'q': quit_check = str( input('Are you sure you want to quit? Y/N : ')).lower() if quit_check == 'y': exit else: continue Move(board, move_input) board.print_board() user.update_userplayhist() if board.status == 'won': print('Congratulations. You won!!!') elif board.status == 'lost': print('Sorry. Better luck next game!') another_game = str(input('Would you like to play another game? ')).lower() if another_game == 'y': play(user) else: print('Thanks for playing,', user.name, '. See you again!') user.update_userplayhist()
def test_moves_1(self): b1 = Board() b1._moves = [] b1._p[7][0] = WHITE b1._p[5][1] = BLACK b1._p[6][1] = WHITE b1._p[1][2] = BLACK b1._p[2][2] = BLACK b1._p[3][2] = BLACK b1._p[4][2] = BLACK b1._p[5][2] = BLACK b1._p[6][2] = BLACK b1._p[2][3] = BLACK b1._p[3][3] = BLACK b1._p[4][3] = BLACK b1._p[5][3] = BLACK b1._p[6][3] = BLACK b1._p[7][3] = BLACK b1._p[3][4] = BLACK b1._p[4][4] = BLACK b1._p[5][4] = BLACK b1._p[5][5] = BLACK b1._p[5][6] = BLACK print(b1.show()) b2 = Board(b1, Move(WHITE, 2, 5)) print(b2.show()) self.assertEqual(6, len(b2._moves))
def test_e_p(self): board = empty_board() wp1 = Figure(WHITE, PAWN) wp2 = Figure(WHITE, PAWN) bp = Figure(BLACK, PAWN) board.put(E4, wp1) board.put(E5, wp2) board.put(D4, bp) self.assertTrue(is_e_p(Move(E4, D5), board)) self.assertFalse(is_e_p(Move(D4, E5), board)) self.assertTrue(board.figure_on_position(D5) is None) make_e_p(board, Move(E4, D5)) wp = board.figure_on_position(D5) self.assertTrue(wp is not None) self.assertEqual(wp.type, PAWN) self.assertEqual(wp.color, WHITE)
def find_best_move(board: Board, max_depth: int = 8) -> Move: best_eval: float = float("-inf") best_move: Move = Move(-1) for move in board.legal_moves: result: float = alphabeta(board.move(move), False, board.turn, max_depth) if result > best_eval: best_eval = result best_move = move return best_move
def create_move(start, end, board, player_color,figure_to_create=None): figure = board.figure_on_position(start) if figure is None or figure.color != player_color: raise InvalidMove("No valid figure at {0}".format(start)) if is_castling(start, end, board): rook_move = CASTLING_DATA[(start, end)]['rook_move'] extra_move = Move(*rook_move) return Move(start, end, type=CASTLING_MOVE, extra_move=extra_move) eaten_position = Coordinates(end.x, start.y) if is_e_p(start, end, board): return Move(start, end, type=E_P_MOVE, eaten_position=eaten_position) if board.figure_on_position(end) is not None: eaten_position = end else: eaten_position = None return Move(start, end, type=COMMON_MOVE, eaten_position=eaten_position,after_conversion=figure_to_create)
def selectSquare(self, x, y): if self.selectedSquare is None: self.selectedSquare = (x, y) elif self.selectedSquare == (x, y): self.selectedSquare = None else: move = Move(self.selectedSquare[0], self.selectedSquare[1], x, y) self.selectedSquare = None self.onBoardMove(move) self.delete("all") self.drawBoard()
def find_best_move(board: Board, max_depth: int = 8) -> Move: best_eval: float = float('-inf') best_move: Move = Move(-1) for move in board.legal_moves: # result: float = minimax(board.move(move),False,board.turn,max_depth) # 我把上面的minimax换成了它的升级版alphabeta,性能得到了优化 result: float = alphabeta(board.move(move), False, board.turn, max_depth) if result > best_eval: best_eval = result best_move = move return best_move
def test_winning_move(self): game = Game() game.start() # set winning status to board board = Board() [board.place_move(Move(0, i, PlayerType.CIRCLE)) for i in range(4)] winning_move = 0, 4 game._board = board game.move(*winning_move) self.assertTrue(game.is_finished)
def setMove(self, value): mx, my = value player_move = (my // CELL_HEIGHT * 3) + (mx // CELL_WIDTH) if player_move in self._board.legal_moves: self._board = self._board.move(Move(player_move)) self._grid.pic(PLAYER, player_move) if self._board.is_win: self._game_over = True self._msgBox.active = STATUS.WIN elif self._board.is_draw: self._game_over = True self._msgBox.active = STATUS.DRAW if not self._game_over: computer_move = find_best_move(self._board) self._board = self._board.move(Move(computer_move)) self._grid.pic(COMPUTER, computer_move) if self._board.is_win: self._game_over = True self._msgBox.active = STATUS.LOS elif self._board.is_draw: self._game_over = True self._msgBox.active = STATUS.DRAW
def find_best_move(board: Board, max_depth: int = 8) -> Move: # initialise values to negative numbers best_eval: float = float("-inf") best_move: Move = Move(-1) # go through the possible moves and update not only the best_eval # but also the best_move for move in board.legal_moves: # result: float = minimax(board.move(move), False, board.turn, max_depth) result: float = alphabeta(board.move(move), False, board.turn, max_depth) if result > best_eval: best_eval = result best_move = move return best_move
def find_best_move(board: Board, max_depth: int = 8) -> Move: best_eval: float = float("-inf") best_move: Move = Move(-1) for move in board.legal_moves: result: float = alphabeta(board.move(move), False, board.turn, max_depth) if result > best_eval: best_eval = result best_move = move global count print(f"Nodes visited: {count}") count = 0 return best_move
def move(self, x, y): if self.is_finished: raise GameAlreadyFinishedException() move = Move(x, y, self._player_move) self._board.place_move(move) if self._board.is_winning_move(move): self.is_finished = True self.winning_player = move.player_type elif len(self._board.available_moves) == 0: self.is_finished = True # draw self.winning_player = None else: self._set_next_player_move()
def test_csv(self): b1 = Board() csv1 = b1.csv_line() b1a = Board(csv=csv1) self.assertEqual(b1.__hash__(), b1a.__hash__()) m2 = Move(WHITE, 4, 2) b2 = Board(b1, m2) csv2 = b2.csv_line() b2a = Board(csv=csv2) self.assertEqual(b2.__hash__(), b2a.__hash__()) b3 = Board(b1, Move(WHITE, 2, 4)) b3 = Board(b3, Move(BLACK, 2, 5)) b3 = Board(b3, Move(WHITE, 5, 3)) b3 = Board(b3, Move(BLACK, 5, 2)) b3 = Board(b3, Move(WHITE, 4, 2)) b3 = Board(b3, Move(BLACK, 5, 4)) b3 = Board(b3, Move(WHITE, 6, 3)) b3 = Board(b3, Move(BLACK, 3, 2)) csv3 = b3.csv_line() b3a = Board(csv=csv3) self.assertEqual(b3.__hash__(), b3a.__hash__())
def onBoardClicked(self, color, event): (cx, cy) = pos = self._eventSquare(event) piece = self._board.get(cx, cy) if self._from == None: # Select if piece == self._currentColor: self._from = pos return True else: theMove = Move(self._from, pos) if theMove in self._board.possibleMoves(): self._moveAction(theMove) self._from = None return True else: # Unselect self._from = None return True
def RootOfAlphaBetaSearch(board, piecestack, piece, turn, max_depth, search_time): global iter iter = 0 best = -100000 piecelist = piecestack.GetPieceList() piecestack.show() move_list = [ Move(x, y, piece, p, 0) for p in piecelist for x in range(ROWS) for y in range(COLS) if board.pieces[x][y] is EMPTY ] # Deepen search by 1 every iteration until time is up t = time.time() elapsed = 0 for depth in range(2, max_depth): print('Depth:' + str(depth)) for move in move_list: (x, y, piece, p, score) = move.get_move() board.place_piece(piece, x, y) turn.change() score = -AlphaBetaSearch(board, piecestack, p, turn, depth - 1, -10000, 10000) move.set_score(score) if score > best: best = score bestx = x besty = y bestpiece = p # piecestack.PutPieceBack(p) turn.change() board.unplace_piece(piece, x, y) # Stop if time is over elapsed = time.time() - t if elapsed > search_time: break move_list.sort(key=lambda m: m.get_score(), reverse=True) if best == WIN: break if elapsed > search_time: break return bestx, besty, bestpiece, best
def getMove(self, player, board, pieces): import random # Get a list of unique (x, y) points that might be legal # Check for all legal diagonal points and consider all points in a # radius-2 box around them xy_list = [] for x in range(0, 20): for y in range(0, 20): if not board.checkTileLegal(player, x, y): continue if board.checkTileAttached(player, x, y): min_x = max(0, x-2) max_x = min(20, x+3) min_y = max(0, y-2) max_y = min(20, y+3) for xi in range(min_x, max_x): for yi in range(min_y, max_y): xy_list.append((xi, yi)) xy_list = sorted(set(xy_list)) # Generate all legal moves move_list = [] for piece in range(0, 21): if not pieces[player][piece]: continue for (x, y) in xy_list: for rot in range(0, 4): for flip in [False, True]: new_move = Move(piece, x, y, rot, flip) if board.checkMoveValid(player, new_move): move_list.append(new_move) # Pass if there are none if len(move_list) == 0: return None # Otherwise, pick a random move else: n = random.randint(0, len(move_list) - 1) return move_list[n]