def possible(self): b = self.board.copy() for piece_type in chess.PIECE_TYPES: for sq in b.pieces(piece_type, not self.color): b.remove_piece_at(sq) pawn_capture_moves = [] no_opponents_board = b.copy() for pawn_square in self.board.pieces(chess.PAWN, self.color): for attacked_square in self.board.attacks(pawn_square): # skip this square if one of our own pieces are on the square if no_opponents_board.piece_at(attacked_square): continue pawn_capture_moves.append( chess.Move(pawn_square, attacked_square)) # add in promotion moves if attacked_square in chess.SquareSet(chess.BB_BACKRANKS): for piece_type in chess.PIECE_TYPES[1:-1]: pawn_capture_moves.append( chess.Move(pawn_square, attacked_square, promotion=piece_type)) return list(b.generate_pseudo_legal_moves()) + pawn_capture_moves
def move_verification_tester(move_legality_tester, board_creator_fn, fens_to_test=DEFAULT_TESTING_FENS, moves_to_test=DEFAULT_MOVES_TO_CHECK): """ A function to test a method of move legality verification. This is used to confirm that the move verification done for moves stored in the transposition table is correct. It uses the python-chess package to compute the correct legality of moves, and compares against that. :param move_legality_tester: A function accepting two parameters, the first being a board as returned by the given board_creator_fn, and the second being a size 3 ndarray representing a move. The function must return a boolean value, indicating if the move is legal :param board_creator_fn: A function which takes as input a Python-Chess Board object, and outputs the board in the representation to be used when testing move legality. :param fens_to_test: An iterable of strings, each a FEN representation of a board. :param moves_to_test: A uint8 ndarray of size [num_moves_to_test, 3], representing the moves to test for each testing fen :return: True if all tests were passed, False if not """ for cur_fen in fens_to_test: cur_board = chess.Board(cur_fen) cur_testing_board = board_creator_fn(cur_board) for j in range(len(moves_to_test)): if move_legality_tester(cur_testing_board, moves_to_test[j]) != cur_board.is_legal( chess.Move(*moves_to_test[j]) if moves_to_test[j, 2] != 0 else chess.Move(*moves_to_test[j, :2])): return False return True
def move(self): aux = self.board.copy() # print(self.piece) for i in range(len(self.piece)): # print(self.piece) if (str(self.piece[i]).upper() == 'P'): num = 1 elif (str(self.piece[i]).upper() == 'N'): num = 2 elif (str(self.piece[i]).upper() == 'B'): num = 3 elif (str(self.piece[i]).upper() == 'R'): num = 4 elif (str(self.piece[i]).upper() == 'Q'): num = 5 elif (str(self.piece[i]).upper() == 'K'): num = 6 mov = chess.Move(self.ini, self.ini, num) aux.push(mov) # print(self.board) mov = chess.Move.null() aux.push(mov) mov = chess.Move(self.ini, self.dest) #self.aux.push(mov) if (mov in aux.legal_moves): # print(self.ini) # print(self.dest) self.board.push(mov) # print(self.board) return True
def testIsPseudoLegalPromotion(self): self.boardWidget.setFen(None) a = chess.Move(chess.A7, chess.A8) b = chess.Move(chess.A2, chess.A1) c = chess.Move(chess.A3, chess.A4) d = chess.Move(chess.B7, chess.B8) e = chess.Move(chess.C7, chess.C8) self.assertFalse(self.boardWidget.isPseudoLegalPromotion(a)) self.assertFalse(self.boardWidget.isPseudoLegalPromotion(b)) self.assertFalse(self.boardWidget.isPseudoLegalPromotion(c)) self.boardWidget.addPieceAt(chess.A2, chess.Piece(chess.PAWN, chess.BLACK)) self.boardWidget.addPieceAt(chess.A7, chess.Piece(chess.PAWN, chess.WHITE)) self.boardWidget.addPieceAt(chess.B7, chess.Piece(chess.PAWN, chess.BLACK)) self.boardWidget.addPieceAt(chess.C7, chess.Piece(chess.ROOK, chess.WHITE)) self.assertTrue(self.boardWidget.isPseudoLegalPromotion(a)) self.assertTrue(self.boardWidget.isPseudoLegalPromotion(b)) self.assertFalse(self.boardWidget.isPseudoLegalPromotion(c)) self.assertFalse(self.boardWidget.isPseudoLegalPromotion(d)) self.assertFalse(self.boardWidget.isPseudoLegalPromotion(e))
def test__hw_detect_move_player_capture(self): """ Test detect normal capture """ # Set up board self.hc._board.push(chess.Move(chess.square(1, 1), chess.square(1, 3))) # b4 self.hc._board.push(chess.Move(chess.square(0, 6), chess.square(0, 4))) # a5 # Configure occupancy set_occupancy(self.hwi_mock, self.hc._board) self.hwi_mock.get_occupancy.return_value[1][3] = False self.hwi_mock.get_occupancy.return_value[0][4] = False # Play move itr 1, itr 2 terminate with patch.object(HardwareClient.HardwareClient, 'game_is_over') as game_over_mock: game_over_mock.side_effect = [False, True] self.hc._hw_detect_move_player() self.assertIsNotNone(self.hc._output_playResult, "Output move has not been processed") self.assertEqual(self.hc._output_playResult.move.from_square, chess.square(1, 3), "Detected from square was not b4") self.assertEqual(self.hc._output_playResult.move.to_square, chess.square(0, 4), "Detected to square was not a5")
def _pawn_on(self, board, turn): """ Generates all pawn captures on `board`, even if there is no piece to capture. All promotion moves are included. :param board: chess.Board -- a chess board where you want opponnet's pieces to be removed :param turn: bool - True(WHITE's turn) or False(BLACK's turn), the opponnet is the 'not turn' :return: List(chess.Move) """ pawn_capture_moves = [] no_opponents_board = self._no_opp_pieces(board, turn) for pawn_square in board.pieces(chess.PAWN, turn): for attacked_square in board.attacks(pawn_square): # skip this square if one of our own pieces are on the square if no_opponents_board.piece_at(attacked_square): continue pawn_capture_moves.append( chess.Move(pawn_square, attacked_square)) # add in promotion moves if attacked_square in chess.SquareSet(chess.BB_BACKRANKS): for piece_type in chess.PIECE_TYPES[1:-1]: pawn_capture_moves.append( chess.Move(pawn_square, attacked_square, promotion=piece_type)) return pawn_capture_moves
def _generate_posible_pawn_captures(self): possibilities = list() for square in list(self._board.pieces(chess.PAWN, self._board.turn)): for attacked in list(self._players_board.attacks(square)): if self._players_board.piece_at(attacked) is None: if chess.square_rank(attacked) in (0, 7): # If capture is promotion for pawn. possibilities.extend([ KSMove( QA.COMMON, chess.Move(square, attacked, promotion=chess.QUEEN)), KSMove( QA.COMMON, chess.Move(square, attacked, promotion=chess.BISHOP)), KSMove( QA.COMMON, chess.Move(square, attacked, promotion=chess.KNIGHT)), KSMove( QA.COMMON, chess.Move(square, attacked, promotion=chess.ROOK)) ]) else: # If capture is not promotion for pawn possibilities.append( KSMove(QA.COMMON, chess.Move(square, attacked))) return possibilities
def testPopAndUnpop(self): self.boardWidget.setFen(chess.STARTING_FEN) boardCopy = self.boardWidget.board.copy() self.boardWidget.push(chess.Move(chess.A2, chess.A4)) self.boardWidget.pop() self.assertEqual(self.boardWidget.board, boardCopy) self.boardWidget.reset() moves = [ chess.Move(chess.A2, chess.A4), chess.Move(chess.A4, chess.A6), chess.Move(chess.A6, chess.A8) ] self.boardWidget.makeMove(moves[0]) self.boardWidget.makeMove(moves[1]) self.boardWidget.makeMove(moves[2]) moveStack = self.boardWidget.board.move_stack.copy() boardCopy2 = self.boardWidget.board.copy() self.boardWidget.pop(3) self.assertEqual(self.boardWidget.board, boardCopy) self.assertListEqual(list(self.boardWidget.popStack), moveStack[::-1]) self.boardWidget.unpop(3) self.assertEqual(self.boardWidget.board, boardCopy2) self.assertFalse(self.boardWidget.popStack) self.assertListEqual(list(self.boardWidget.board.move_stack), moves)
def az_index_to_move(index): if index == -1: return chess.Move(None, None) move_coordinates = inflate_1d_coords_3d(index, AZ_SHAPE) from_file = move_coordinates[0] from_rank = move_coordinates[1] move_type = move_coordinates[2] promotion_piece = None if move_type >= 64: # Treat under-promotions as 3 x 3 array of [type of file movement, piece promoted to] underpromotion_type = inflate_1d_coords_2d(move_type - 64, UNDERPROMOTIONS_SHAPE) # Get under-promotion coords file_modifier = underpromotion_type[0] - 1 # shift from range 0,..2 to -1,..1 promotion_piece = underpromotion_type[1] + PROMOTION_PIECE_MODIFIER # Restore to python-chesspiece numbers to_file = from_file + file_modifier to_rank = 7 if from_rank == 6 else 0 # Under-promotions always move a rank ahead (player-relative) elif move_type >= 56: knight_delta = decode_knight_move_delta(move_type - 56) to_file = from_file + knight_delta[0] to_rank = from_rank + knight_delta[1] else: #its a queen move queen_delta = decode_queen_delta(move_type) to_file = from_file + queen_delta[0] to_rank = from_rank + queen_delta[1] return chess.Move(chess.square(from_file, from_rank), chess.square(to_file, to_rank), promotion_piece)
def get_uci_move(self, action, player): source = action // (self.n * self.n) target = action % (self.n * self.n) if player == -1: return chess.Move(chess.square_mirror(source), chess.square_mirror(target)) return chess.Move(source, target)
def main(): global move_array game = True engine = uci.popen_engine('./Engine/stockfish_8_x64') engine.uci() while game: SCREEN.blit(BACKGROUND, (0, 512)) button("Reset", 50, 520, 100, 30, BUTTON_BACK, BUTTON_BACK, resetBoard) button("<<", 200, 520, 50, 30, BUTTON_BACK, BUTTON_BACK, toBeginning) button("<", 270, 520, 50, 30, BUTTON_BACK, BUTTON_BACK, oneBack) button(">", 340, 520, 50, 30, BUTTON_BACK, BUTTON_BACK, pushOne) button(">>", 410, 520, 50, 30, BUTTON_BACK, BUTTON_BACK, toEnd) for row in range(8): for column in range(8): if (row, column) not in move_array: if (row + column) % 2 == 0: SCREEN.blit(SQUARE_DARK, (row * 64, column * 64)) else: SCREEN.blit(SQUARE_LIGHT, (row * 64, column * 64)) for event in pygame.event.get(): if event.type == pygame.QUIT: game = False if event.type == pygame.MOUSEBUTTONUP: pos = pygame.mouse.get_pos() x_val, y_val = int(pos[0] / 64), 7 - (int(pos[1] / 64)) if y_val >= 0: move_array.append((x_val, y_val)) if len(move_array) == 1: SCREEN.blit(SQUARE_CLICKED, (move_array[0][0] * 64, (7 - move_array[0][1]) * 64)) if len(move_array) == 2: square_x = chess.square(move_array[0][0], move_array[0][1]) square_y = chess.square(move_array[1][0], move_array[1][1]) if (str(BOARD.piece_at(square_x)) == 'P' or str(BOARD.piece_at(square_x)) == 'p') \ and chess.file_index(square_x) != chess.file_index(square_y) and \ (chess.rank_index(square_y) == 0 or chess.rank_index(square_y) == 7): cur_move = chess.Move(square_x, square_y, promotion=5) else: cur_move = chess.Move(square_x, square_y) if cur_move in BOARD.legal_moves: BOARD.push(cur_move) engine_position = engine.position(BOARD) engine_moves = engine.go() BOARD.push(engine_moves[0]) else: move_array = [] updateBoard() pygame.display.flip() CLOCK.tick(30)
def __init__(self, p, f, t, c=None): self.p = p self.f = int(f) self.t = int(t) self.c = c if c == None: self.move = chess.Move(self.f, self.t) else: self.move = chess.Move(self.f, self.t, self.c)
def _hw_detect_move_player(self): """ Detect move from player We compare the expected occupancy with the actual occupancy. If two squares are different then we set the square where the clients piece used to be as the from square and the other square as the too square. Using this we create a candidate move (from_square, to_square). If this is a legal move then we will place this move in the output field. Note that the chess library will detect any other side effects from the move like captures, promotions and en passant. The internal board will be updated correctly and the diff will be marked on the board. """ draw_offer = False while not self.game_is_over(): occupancy = self._hwi.get_occupancy() diff = self._diff_occupancy_board(occupancy) self._hwi.mark_squares(diff) offers = self._hwi.game_end_offers() if offers is HardwareInterface.Offer.RESIGN: self._resigned = True return engine.PlayResult(None, None, resigned=True) if offers is HardwareInterface.Offer.DRAW: draw_offer = True # Detect all changed squares squares = [] for file in range(8): for rank in range(8): if diff[file][rank]: squares.append(chess.square(file, rank)) if len(squares) == 2: # Try to convert changed squares to legal move with self._board_lock: # Promotion not implemented if self._board.piece_at(squares[0]) is not None and \ self._board.piece_at(squares[0]).color == self.color: move = chess.Move(squares[0], squares[1]) elif self._board.piece_at(squares[1]) is not None and \ self._board.piece_at(squares[1]).color == self.color: move = chess.Move(squares[1], squares[0]) else: continue if self._board.piece_at(move.from_square).piece_type == chess.PAWN and \ ((self.color == chess.WHITE and chess.square_rank(move.to_square) == 7) or (self.color == chess.BLACK and chess.square_rank(move.to_square) == 0)): move.promotion = chess.QUEEN move_is_legal = move in self._board.legal_moves # save result to not use two locks if move_is_legal and move.promotion is not None: move.promotion = self._hwi.promotion_piece() if move_is_legal: with self._board_lock: self._board.push(move) with self._playResult_lock: self._output_playResult = engine.PlayResult(move, None, draw_offered=draw_offer) return self._update_display() sleep(SLEEP_TIME)
def _add_move(labels, v, f, r, f_new, r_new, promotion=None): if f_new in range(0, 8) and r_new in range(0, 8): labels[chess.Move(r * 8 + f, r_new * 8 + f_new, promotion)] = v * 64 + r * 8 + f if promotion is None and (r == 6 and r_new == 7 and abs(f_new - f) <= 1 or r == 1 and r_new == 0 and abs(f_new - f) <= 1): labels[chess.Move( r * 8 + f, r_new * 8 + f_new, 5)] = v * 64 + r * 8 + f # add a default queen promotion.
def make_move(board, x, y, last_x, last_y, promotion_type): # make a move. Move must be valid if promotion_type != 0: board.push( chess.Move(get_grid_id(last_x, last_y), get_grid_id(x, y), promotion_type)) else: board.push(chess.Move(get_grid_id(last_x, last_y), get_grid_id(x, y))) return board.is_game_over(), board.result()
def move(self): # Extract source and target square. to_square = self.raw_move & 0x3f from_square = (self.raw_move >> 6) & 0x3f # Replace non standard castling moves. if from_square == chess.E1: if to_square == chess.H1: return chess.Move(chess.E1, chess.G1) elif to_square == chess.A1: return chess.Move(chess.E1, chess.C1) elif from_square == chess.E8: if to_square == chess.H8: return chess.Move(chess.E8, chess.G8) elif to_square == chess.A8: return chess.Move(chess.E8, chess.C8) # Extract the promotion type. promotion_part = (self.raw_move >> 12) & 0x7 if promotion_part == 4: return chess.Move(from_square, to_square, chess.QUEEN) elif promotion_part == 3: return chess.Move(from_square, to_square, chess.ROOK) elif promotion_part == 2: return chess.Move(from_square, to_square, chess.BISHOP) elif promotion_part == 1: return chess.Move(from_square, to_sqaure, chess.KNIGHT) else: return chess.Move(from_square, to_square)
def evaluate_board(fen): chess_piece_value = {'Q': 14, 'R': 5, 'B': 3.25, 'K': 3, 'N': 3, 'P': 1} center = set([chess.D4, chess.D5, chess.E4, chess.E5]) current_value = 0.0 total_value = 0.0 for ch in fen.split(' ')[0]: if not ch.isalpha(): continue if ch.isupper(): current_value += chess_piece_value[ch] total_value += chess_piece_value[ch] else: current_value -= chess_piece_value[ch.upper()] total_value += chess_piece_value[ch.upper()] chess_board = chess.Board(fen) move_to_square_weight = 0.05 for move in chess_board.legal_moves: if move.to_square in center: current_value += (1 if chess_board.turn == chess.WHITE else -1) * move_to_square_weight total_value += move_to_square_weight chess_board.push(chess.Move(None, None)) for move in chess_board.legal_moves: if move.to_square in center: current_value += (1 if chess_board.turn == chess.WHITE else -1) * move_to_square_weight total_value += move_to_square_weight chess_board.pop() mobility = len(list(chess_board.legal_moves)) * (1 if chess_board.turn == chess.WHITE else -1) current_mobility = mobility total_mobility = abs(mobility) chess_board.push(chess.Move(None, None)) mobility = len(list(chess_board.legal_moves)) * (1 if chess_board.turn == chess.WHITE else -1) chess_board.pop() current_mobility += mobility total_mobility += abs(mobility) current_value += 1.5 * current_mobility / total_mobility total_value += 1.5 value_rate = current_value / total_value '''if is_black_turn(fen): value_rate = -value_rate''' return np.tanh(value_rate * 3)
def undo(game: Game) -> None: """ wait for correct reversed move. show player 2 reversed moves (1 computer, 1 player) remove moves from GAME.board.movestack but keep a copy in the GAME.move_stack_copy keep the old movestack until a new move/confirmation computer move has been made (in case of "redo" call) :return: """ LOG.debug('BUTTON_EVENT undo') # (led indicators) make frame show computer move in reverse move1 = game.board.pop() # pop function from chess.Board move2 = game.board.pop() # copy the move stack fir when the redo function is called game.move_stack_copy.append(move1) game.move_stack_copy.append(move2) # reverse moves move1 = chess.Move(move1.to_square, move1.from_square) move2 = chess.Move(move2.to_square, move2.from_square) text0 = epaper.FrameText(pos=(214, 15), content='Undo move:', fill=config.WHITE) text1 = epaper.FrameText(pos=(30, 40), content=''.join([str(move2), str(move1)]), font=config.FONT_BIG) epaper_screen.update_frame(button_panel, epaper.game_player_turn( button_panel=button_panel, content=(text0, text1), partial_frame=True), important=False) # Interrupt active on buttons 'undo' 'redo' # Undo 1 computer move while True: button_panel.wait_for_move() if validate_computer_move(game, move1): break # Undo 1 player move while True: button_panel.wait_for_move() if validate_computer_move(game, move2): break epaper_screen.update_frame( button_panel, epaper.game_player_turn(button_panel=button_panel)) epaper_screen.update_frame(button_panel, epaper.game_player_turn( button_panel=button_panel, content=epaper.PLAYER_WAIT, partial_frame=True), important=False)
def read_move(data): to_sq = int(data & 0x003F) from_sq = int((data >> 6) & 0x003F) promotion = int((data >> 12) & 0x0003) special = (data >> 14) & 0x0003 if special == 1: move = chess.Move(from_sq, to_sq, promotion+2) else: move = chess.Move(from_sq, to_sq) return move
def findmove(): # Find available moves in sorted order l = [] # Start with last best moves follow up ✓ # With current scoring, this is slower # Prioritize capture of last moved piece ✓ if len(board.move_stack) > 0: last = str(board.peek()) piece = chess.parse_square(last[2:4]) froms = board.attackers(board.turn, piece) move = [chess.Move(i, piece) for i in froms] l.extend([m for m in move if board.is_legal(m)]) ours = [board.pieces(j, board.turn) for j in range(1, 7)] for ptypes in ours: for froms in ptypes: # Killer moves: capture threatining pieces ✓ attackers = board.attackers(not board.turn, froms) attacks = board.attacks(froms) moves = [ chess.Move(froms, to) for to in attacks if attackers.__contains__(to) ] # Other captures: if you can capture do it ✓ moves.extend([ chess.Move(froms, to) for to in attacks if not attackers.__contains__(to) ]) l.extend([move for move in moves if board.is_legal(move)]) # Pawn promotion: try to promte pawn ✓/✓ if board.turn: moves = [ chess.Move(pawn, pawn + 8, 5) for pawn in ours[0] if pawn >= 8 * 6 ] else: moves = [ chess.Move(pawn, pawn - 8, 5) for pawn in ours[0] if pawn < 8 * 2 ] l.extend([m for m in moves if board.is_legal(m)]) # All other moves ✓ ll = list(board.legal_moves) l.extend(ll) l = list(OrderedDict.fromkeys(l)) if len(l) is not len(ll): # Checks if list has illegal moves print("Illigal move detected", len(ll), len(l)) l = [i for i in l if board.is_legal(i)] return l
def choose_move(self, possible_moves, seconds_left): """ Choose a move to enact from a list of possible moves. :param possible_moves: List(chess.Moves) -- list of acceptable moves based only on pieces :param seconds_left: float -- seconds left to make a move :return: chess.Move -- object that includes the square you're moving from to the square you're moving to :example: choice = chess.Move(chess.F2, chess.F4) :condition: If you intend to move a pawn for promotion other than Queen, please specify the promotion parameter :example: choice = chess.Move(chess.G7, chess.G8, promotion=chess.KNIGHT) *default is Queen """ if self.color == chess.WHITE: if self.move_counter == 0: self.move_counter += 1 return chess.Move(chess.B1, chess.C3) elif self.move_counter == 1: self.move_counter += 1 return chess.Move(chess.C3, chess.E4) elif self.move_counter == 2: self.move_counter += 1 return chess.Move(chess.E4, chess.D6) elif self.move_counter == 3: self.move_counter += 1 return chess.Move(chess.C2, chess.D3) elif self.move_counter == 4: return chess.Move(chess.D6, chess.E8) else: self.move_counter += 1 return self.test_algo(possible_moves, seconds_left) else: if self.move_counter == 0: self.move_counter += 1 return chess.Move(chess.B8, chess.C6) elif self.move_counter == 1: self.move_counter += 1 return chess.Move(chess.C6, chess.E5) elif self.move_counter == 2: self.move_counter += 1 return chess.Move(chess.E5, chess.D3) elif self.move_counter == 3: self.move_counter += 1 return chess.Move(chess.C7, chess.D6) elif self.move_counter == 4: return chess.Move(chess.D3, chess.E1) else: self.move_counter += 1 return self.test_algo(possible_moves, seconds_left)
def human(board): move = input("Move (e9 k0): ") start, end = move.split(' ') start = letters[start[0]] + (int(start[1]) - 1) * 8 end = letters[end[0]] + (int(end[1]) - 1) * 8 move = chess.Move(start, end) while move not in board.legal_moves: print("That move was ILLEGAL! Try again.") move = input("Move (e9 k0): ") start, end = move.split(' ') start = letters[start[0]] + (int(start[1]) - 1) * 8 end = letters[end[0]] + (int(end[1]) - 1) * 8 move = chess.Move(start, end) return move
def move(self, Row1, Col1, Row2, Col2): """ Used for generating a `movestring` to be used with `pass_msg` in `ur_socket_connection` Also updates board state and prints the unicode representation of the current board. `Col` ranges from 0 to 7 starting at A and moving to H on the chessboard `Row` ranges from 0 to 7 starting at 1 and moving to 8 on the chessboard """ self.source_square = self.convert_square(Row1, Col1) self.target_square = self.convert_square(Row2, Col2) self.occupied_flag = str(self.check_occupied(self.target_square)) self.source_xy = self.get_xy(Row1, Col1) self.target_xy = self.get_xy(Row2, Col2) self.source_x = str(self.source_xy[0]) self.source_y = str(self.source_xy[1]) self.target_x = str(self.target_xy[0]) self.target_y = str(self.target_xy[1]) self.tuple = self.occupied_flag, self.source_x, self.source_y, self.target_x, self.target_y self.move_string = '(' + ', '.join(self.tuple) + ')' self.desired_move = chess.Move(self.source_square, self.target_square) self.board.push(self.desired_move) print(self.desired_move) print(self.move_string + "\n") print(self.board.unicode() + "\n") return self.move_string
def __getitem__(self, index: int) -> Entry: if self.mmap is None: raise IndexError() if index < 0: index = len(self) + index try: key, raw_move, weight, learn = ENTRY_STRUCT.unpack_from(self.mmap, index * ENTRY_STRUCT.size) # type: ignore except struct.error: raise IndexError() # Extract source and target square. to_square = raw_move & 0x3f from_square = (raw_move >> 6) & 0x3f # Extract the promotion type. promotion_part = (raw_move >> 12) & 0x7 promotion = promotion_part + 1 if promotion_part else None # Piece drop. if from_square == to_square: promotion, drop = None, promotion else: drop = None # Entry with move (not normalized). move = chess.Move(from_square, to_square, promotion, drop) return Entry(key, raw_move, weight, learn, move)
def move_coordinates(): if not s.board.is_game_over(): source = int(request.args.get('from', default='')) target = int(request.args.get('to', default='')) promotion = True if request.args.get('promotion', default='') == 'true' else False move = s.board.san( chess.Move(source, target, promotion=chess.QUEEN if promotion else None)) if move is not None and move != "": print("human moves", move) try: s.board.push_san(move) computer_move(s, v) except Exception: traceback.print_exc() response = app.response_class(response=s.board.fen(), status=200) return response print("GAME IS OVER") response = app.response_class(response="game over", status=200) return response
def test_get_move_planes_given_queen_promotion_moves_expect_correct_plane_selection( self): col = 4 row = 6 aggregated_selected_boards = np.zeros(56) for x_direction in [-1, 0, 1]: movement_vector = [1, x_direction] from_idx = get_board_position_index(row, col) to_idx = get_board_position_index(row + movement_vector[0], col + movement_vector[1]) selected_boards = np.sum(get_move_planes( chess.Move(from_idx, to_idx, "Q"))[0:56, :, :], axis=(1, 2)) # test that only a single position is selected self.assertTrue( np.sum(selected_boards) == 1, "more than one board was selected") aggregated_selected_boards += selected_boards # test that 3 ids where selected once selected = aggregated_selected_boards[aggregated_selected_boards > 0] self.assertTrue( len(selected) == 3, "more or less than 3 boards where selected") self.assertTrue(np.all(selected == 1), "some boards where selected never or more than once")
def compute_move(self,new_state,promotion=None): #only checks for white propertly diff = self.state-new_state diff = np.rot90(diff,2,(0,1)) print("this is diff") print(diff) if self.turn == chess.WHITE: #check castling if len(np.where(diff==2)[0])==2: assert np.where(diff[0][0]==2) == 0 if diff[0][0] == 2: from_ind = 4 to_ind = 2 elif diff[0][7] == 2: from_ind = 4 to_ind = 6 else: assert False else: from_ind = np.where(diff==2)[0][0]*8+np.where(diff==2)[1][0] try: to_ind = np.where(diff==-2)[0][0]*8+np.where(diff==-2)[1][0] except IndexError: print("white took a piece") to_ind = np.where(diff==-1)[0][0]*8+np.where(diff==-1)[1][0] else: from_ind = np.where(diff == 1)[0][0] * 8 + np.where(diff == 1)[1][0] to_ind = np.where(diff == -1)[0][0] * 8 + np.where(diff == -1)[1][0] self.state = new_state move = chess.Move(from_ind,to_ind) #eventually introduce promotion return move
def test_get_move_planes_given_knight_moves_expect_correct_plane_selection( self): # place the knight in the center of the board # and test all combinations col = 4 row = 4 aggregated_selected_boards = np.zeros(8) for x in [-1, 1]: for y in [-1, 1]: for x_dominates in [True, False]: movement_vector = [ y * (1 if x_dominates else 2), x * (2 if x_dominates else 1) ] from_idx = get_board_position_index(row, col) to_idx = get_board_position_index(row + movement_vector[0], col + movement_vector[1]) selected_boards = np.sum(get_move_planes( chess.Move(from_idx, to_idx))[56:64, :, :], axis=(1, 2)) # test that only a single position is selected self.assertTrue( np.sum(selected_boards) == 1, "more than one board was selected") aggregated_selected_boards += selected_boards # test that all ids where selected once self.assertTrue(np.all(aggregated_selected_boards == 1), "some boards where selected never or more than once")
def generate_pseudo_legal_moves(self, from_mask: chess.Bitboard = chess.BB_ALL, to_mask: chess.Bitboard = chess.BB_ALL) -> Iterator[chess.Move]: for move in super().generate_pseudo_legal_moves(from_mask, to_mask): # Add king promotions. if move.promotion == chess.QUEEN: yield chess.Move(move.from_square, move.to_square, chess.KING) yield move
def test_get_move_planes_given_underpromotions_moves_expect_correct_plane_selection( self): col = 4 row = 6 aggregated_selected_boards = np.zeros(9) for piece in ["n", "b", "r"]: for x_direction in [-1, 0, 1]: movement_vector = [1, x_direction] from_idx = get_board_position_index(row, col) to_idx = get_board_position_index(row + movement_vector[0], col + movement_vector[1]) selected_boards = np.sum(get_move_planes( chess.Move(from_idx, to_idx, piece))[64:73, :, :], axis=(1, 2)) # test that only a single position is selected self.assertTrue( np.sum(selected_boards) == 1, "more than one board was selected") aggregated_selected_boards += selected_boards # test that all ids where selected once self.assertTrue(np.all(aggregated_selected_boards == 1), "some boards where selected never or more than once")