def chess_to_coordinate(pos: str) -> Union[Coordinate, Move]: """ Arguments: """ if len(pos) == 2: return Coordinate(int(pos[1]) - 1, file_dict[pos[0]]) else: if len(pos) == 5: if pos[4] == 'n': return Move(Coordinate(int(pos[1]) - 1, file_dict[pos[0]]), Coordinate(int(pos[3]) - 1, file_dict[pos[2]]), False, MoveType.N_PROMO) elif pos[4] == 'b': return Move(Coordinate(int(pos[1]) - 1, file_dict[pos[0]]), Coordinate(int(pos[3]) - 1, file_dict[pos[2]]), False, MoveType.B_PROMO) elif pos[4] == 'r': return Move(Coordinate(int(pos[1]) - 1, file_dict[pos[0]]), Coordinate(int(pos[3]) - 1, file_dict[pos[2]]), False, MoveType.R_PROMO) elif pos[4] == 'q': return Move(Coordinate(int(pos[1]) - 1, file_dict[pos[0]]), Coordinate(int(pos[3]) - 1, file_dict[pos[2]]), False, MoveType.Q_PROMO) else: return Move(Coordinate(int(pos[1]) - 1, file_dict[pos[0]]), Coordinate(int(pos[3]) - 1, file_dict[pos[2]]))
def test_get_winner_spade(self): moves: List[Move] = [ Move(Player("Ann"), Card("10", "C")), Move(Player("Betsy"), Card("K", "C")), Move(Player("Caroline"), Card("3", "C")), Move(Player("Diane"), Card("2", "S")), ] t: Trick = Trick(moves) self.assertEqual(t.get_winner(), Player("Diane"))
def get_diagonal_moves(self, piece: Piece, board: List[List[Piece]]) -> List[Move]: """ returns a list of all diagonal moves arguments: piece -- piece to generate moves board -- board to validate moves """ if piece.piece_type != Type.BISHOP and piece.piece_type != Type.QUEEN: return [] directions: List[Tuple[int, int]] = [(1, 1), (-1, 1), (-1, -1), (1, -1)] moves: List[Move] = [] for direction in directions: destination: Coordinate = Coordinate( piece.coordinate.get_rank() + direction[0], piece.coordinate.get_file() + direction[1], ) while self.in_board(destination): moves.append( Move(piece.coordinate, destination, self.piece_at(destination, board))) if self.piece_at(destination, board): break destination = Coordinate( destination.get_rank() + direction[0], destination.get_file() + direction[1], ) return moves
def test_to_dict(self): ann_card: Card = Card("10", "C") betsy_card: Card = Card("K", "C") caroline_card: Card = Card("3", "C") diane_card: Card = Card("2", "S") moves: List[Move] = [ Move(Player("Ann", [ann_card]), ann_card), Move(Player("Betsy", [betsy_card]), betsy_card), Move(Player("Caroline", [caroline_card]), caroline_card), Move(Player("Diane", [diane_card]), diane_card), ] t: Trick = Trick(moves) self.assertEqual( t.to_dict(), { "moves": [ { "player": { "name": "Ann", "cards": [{"value": "10", "int": 10, "suit": "C"}], }, "card": {"value": "10", "int": 10, "suit": "C"}, }, { "player": { "name": "Betsy", "cards": [{"value": "K", "int": 13, "suit": "C"}], }, "card": {"value": "K", "int": 13, "suit": "C"}, }, { "player": { "name": "Caroline", "cards": [{"value": "3", "int": 3, "suit": "C"}], }, "card": {"value": "3", "int": 3, "suit": "C"}, }, { "player": { "name": "Diane", "cards": [{"value": "2", "int": 2, "suit": "S"}], }, "card": {"value": "2", "int": 2, "suit": "S"}, }, ] }, )
def chess_to_move(move_str: str) -> Move: """ Arguments: """ move = Move() return move
def get_move(self, opponent: "Player") -> Move: if self.firing_locations is None: self.firing_locations = opponent.ship_board.get_ship_coordinates() self.firing_locations.reverse() coord = self.firing_locations[-1] #print(f'coord = {coord} from firing locations = {self.firing_locations}') self.firing_locations.pop() return Move(*coord)
def get_ship_start_coords(self, ship_: Ship, orientation_: Orientation): while True: str_cell = input( f'{self.name}, enter the starting position for your {ship_.name} ship ,which is {ship_.length} long, in the form row, column:' ) try: move = Move.from_str(str_cell) return move.row, move.col except MoveError as err: print(err)
def list_children(self): children = [] for x in range(6): for y in range(6): for quarter in range(4): for rotation in (2): if self.is_valid_move(): temp_board = self.copy() move = Move(x, y, quarter, rotation) temp_board.make_move(move, self._color_AI) children.append(temp_board) return children
def test_create_window_seq(self): content = "(;GM[1]FF[4] SZ[19] GN[韩国女?围甲?赛] DT[2017-05-07] PB[藤泽里?] PW[?유진] BR[P3段] WR[P1段] KM[0]HA[0]RU[Japanese]AP[GNU Go:3.8]RE[B+7.5]TM[3600]TC[5]TT[40]AP[foxwq] ;B[aa];B[bb];B[cc])" game = file_to_sgf(content) seq = create_window_seq(game) # without influence of normalization self.assertEqual( seq[0], [Move(Player.b, 0, 0), Move(Player.b, 1, 1), Move(Player.b, 2, 2)]) # with prefixes self.assertEqual(seq[1], [Move(Player.b, 0, 0)], 'Prefis is missing!') self.assertEqual(seq[2], [Move(Player.b, 0, 0), Move(Player.b, 1, 1)]) # with normalization (the second window self.assertEqual( seq[3], [Move(Player.b, 1, 0), Move(Player.b, 2, 1)], 'Maybe normalization is wrong?') self.assertEqual(seq[4], [Move(Player.b, 1, 0)]) self.assertEqual(seq[5], [Move(Player.b, 2, 0)])
def get_move(self, opponent: "Player") -> Move: coord = None if self.mode == "search" or not self.destroy_locations: coord = random.choice(self.firing_locations) elif self.mode == "destroy": coord = self.destroy_locations.popleft() if coord not in self.firing_locations: print( f'mode = {self.mode}, coord = {coord}, firing locations = {self.firing_locations}' ) try: self.firing_locations.remove(coord) except ValueError: pass return None if coord is None else Move(*coord)
def file_to_sgf(content): moves = content.split(';') start_of_moves = 2 game = [] for move in moves[start_of_moves:start_of_moves + max_nr_of_moves]: if (len(move) < 4): continue if (move[0] == 'A'): continue if (move[0] not in [item.value for item in Player]): continue player = Player(move[0]) x = ord(move[2]) - ord('a') y = ord(move[3]) - ord('a') game.append(Move(player, x, y)) return game
def create_window_seq(game): sequences = [] # a sliding window is defined by a starting point and length for i in range(0, (board_size - 1) - window_size): for j in range(0, (board_size - 1) - window_size): # for all windows get all moves that were made inside the window starting at (i,j) and put them into a sequence. seq = filter( lambda move: move.x >= i and move.x < i + window_size and move. y >= j and move.y < j + window_size, game) # Normalize moves, so that they start at (0,0) seq = list( map(lambda move: Move(move.player, move.x - i, move.y - j), seq)) if (len(seq) == 0): continue seq_in_one_pos = [seq] if append_prefix: seq_in_one_pos += all_prefix(seq) if append_only_one_point_in_time: seq_in_one_pos = random.choice(seq_in_one_pos) sequences.append(seq_in_one_pos) return sequences
def get_knight_moves(self, piece: Piece, board: List[List[Piece]]) -> List[Move]: """ returns a list of all knight moves arguments: piece -- piece to generate moves board -- board to validate moves """ if piece.piece_type != Type.KNIGHT: return [] offsets: List[Tuple[int, int]] = [ (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1), ] moves: List[Move] = [] for offset in offsets: destination: Coordinate = Coordinate( piece.coordinate.get_rank() + offset[0], piece.coordinate.get_file() + offset[1], ) if self.in_board(destination): moves.append( Move(piece.coordinate, destination, self.piece_at(destination, board))) return moves
def _determine_moves(moves: str) -> List[Move]: return [Move(move) for move in moves]
def get_move(self, board_: Board) -> Move: str_move = input( f'{self.name}, enter the location you want to fire at in the form row, column: ' ) return Move.from_str(str_move)
def get_move(self, opponent: "Player") -> Move: coord = random.choice(self.firing_locations) self.firing_locations.remove(coord) return Move(*coord)
def get_pawn_moves(self, piece: Piece, board: List[List[Piece]]) -> List[Move]: """ returns a list of all pawn moves arguments: piece -- piece to generate moves board -- board to validate moves """ if piece.piece_type != Type.PAWN: return [] direction: int = 1 if piece.color == Color.WHITE else -1 moves: List[Move] = [] # Add one square move destination: Coordinate = Coordinate( piece.coordinate.get_rank() + 1 * direction, piece.coordinate.get_file()) if self.in_board(destination) and not self.piece_at( destination, board): if (piece.color == Color.WHITE and destination.get_rank() == self.HEIGHT - 1) or (piece.color == Color.BLACK and destination.get_rank() == 0): moves.append( Move(piece.coordinate, destination, False, MoveType.N_PROMO)) moves.append( Move(piece.coordinate, destination, False, MoveType.B_PROMO)) moves.append( Move(piece.coordinate, destination, False, MoveType.R_PROMO)) moves.append( Move(piece.coordinate, destination, False, MoveType.Q_PROMO)) else: moves.append(Move(piece.coordinate, destination)) # Add two square move destination = Coordinate( piece.coordinate.get_rank() + 2 * direction, piece.coordinate.get_file()) if (not piece.moved and self.in_board(destination) and not self.piece_at(destination, board) and ((piece.coordinate.get_rank() == 1 and piece.color == Color.WHITE) or (piece.coordinate.get_rank() == self.HEIGHT - 2 and piece.color == Color.BLACK))): moves.append( Move(piece.coordinate, destination, False, MoveType.DOUBLE)) # Add capturing moves (default and en passant) for offset in [-1, 1]: destination = Coordinate( piece.coordinate.get_rank() + 1 * direction, piece.coordinate.get_file() + offset, ) # Add en passant moves if (self.in_board(destination) and self.en_passant_target and destination == self.en_passant_target): moves.append( Move(piece.coordinate, destination, False, MoveType.EN_PASSANT)) # Add default capturing moves elif self.in_board(destination) and self.piece_at( destination, board): if (piece.color == Color.WHITE and destination.get_rank() == self.HEIGHT - 1) or (piece.color == Color.BLACK and destination.get_rank() == 0): moves.append( Move(piece.coordinate, destination, True, MoveType.N_PROMO)) moves.append( Move(piece.coordinate, destination, True, MoveType.B_PROMO)) moves.append( Move(piece.coordinate, destination, True, MoveType.R_PROMO)) moves.append( Move(piece.coordinate, destination, True, MoveType.Q_PROMO)) else: moves.append(Move(piece.coordinate, destination, True)) return moves
def move(self, board, row, col, quarter, rotation): self._prev_move = Move(row, col, quarter, rotation) board.make_move(self._prev_move, self._color)
def get_move(player: Player, lead_suit: Optional[str]) -> Move: # TODO: can dispatch to different strategy play methods here card: Card = play_random_card(player, lead_suit) return Move(player, card)
def get_king_moves(self, piece: Piece, board: List[List[Piece]], check_moves: bool = False) -> List[Move]: """ returns a list of all king moves arguments: piece -- piece to generate moves board -- board to validate moves """ if piece.piece_type != Type.KING: return [] moves: List[Move] = [] # Get default king moves for rank_offset in [-1, 0, 1]: for file_offset in [-1, 0, 1]: if rank_offset == 0 and file_offset == 0: continue destination: Coordinate = Coordinate( piece.coordinate.get_rank() + rank_offset, piece.coordinate.get_file() + file_offset, ) if self.in_board(destination): moves.append( Move( piece.coordinate, destination, self.piece_at(destination, board), )) # Get castling moves if (not piece.moved and not check_moves and not self.in_check(piece.color, board)): rook: Piece rook_rank = 0 if piece.color == Color.WHITE else self.HEIGHT - 1 # Queen side rook rook = self.piece_at(Coordinate(rook_rank, 0), board) if rook and rook.piece_type == Type.ROOK and not rook.moved: if (not self.piece_at(Coordinate(rook_rank, 1), board) and not self.piece_at(Coordinate(rook_rank, 2), board) and not self.piece_at(Coordinate(rook_rank, 3), board)): candidate_board: List[List[Piece]] = deepcopy(board) candidate_board[rook_rank][2] = candidate_board[ piece.coordinate.get_rank()][ piece.coordinate.get_file()] candidate_board[piece.coordinate.get_rank()][ piece.coordinate.get_file()] = None if not self.in_check(piece.color, candidate_board): moves.append( Move( piece.coordinate, Coordinate(rook_rank, 2), False, MoveType.CASTLE, )) # King side rook rook = self.piece_at(Coordinate(rook_rank, self.WIDTH - 1), board) if rook and rook.piece_type == Type.ROOK and not rook.moved: if not self.piece_at(Coordinate(rook_rank, self.WIDTH - 2), board) and not self.piece_at( Coordinate(rook_rank, self.WIDTH - 3), board): candidate_board: List[List[Piece]] = deepcopy(board) candidate_board[rook_rank][ self.WIDTH - 2] = candidate_board[piece.coordinate.get_rank()][ piece.coordinate.get_file()] candidate_board[piece.coordinate.get_rank()][ piece.coordinate.get_file()] = None if not self.in_check(piece.color, candidate_board): moves.append( Move( piece.coordinate, Coordinate(rook_rank, self.WIDTH - 2), False, MoveType.CASTLE, )) return moves
def test_file_to_sgf(self): content = "(;GM[1]FF[4] SZ[19] GN[韩国女?围甲?赛] DT[2017-05-07] PB[藤泽里?] PW[?유진] BR[P3段] WR[P1段] KM[0]HA[0]RU[Japanese]AP[GNU Go:3.8]RE[B+7.5]TM[3600]TC[5]TT[40]AP[foxwq] ;B[ab];B[bb];B[cc];W[cf];B[ss];W[as])" game = file_to_sgf(content) self.assertEquals(Move(Player.w, 0, 18), game[5]) self.assertEquals(Move(Player.b, 0, 1), game[0])
def test_eq(self): self.assertEquals(Move(Player.w, 0, 0), Move(Player.w, 0, 0)) self.assertNotEqual(Move(Player.w, 0, 1), Move(Player.w, 1, 0)) self.assertNotEqual(Move(Player.w, 0, 1), Move(Player.b, 0, 1))