def setUp(self): self.piece_repr = "..XXX\n" + \ "..XX.\n" + \ "..X..\n" + \ ".....\n" + \ ".....\n" self.piece = Piece(self.piece_repr)
class APieceOf5x5Blocks(unittest.TestCase): def setUp(self): self.piece_repr = "..XXX\n" + \ "..XX.\n" + \ "..X..\n" + \ ".....\n" + \ ".....\n" self.piece = Piece(self.piece_repr) def test_consists_of_many_blocks(self): self.assertEqual(self.piece_repr, str(self.piece)) def test_can_be_rotated_right(self): piece = self.piece.rotate_right() expected_piece = ".....\n" + \ ".....\n" + \ "..XXX\n" + \ "...XX\n" + \ "....X\n" self.assertEqual(expected_piece, str(piece)) def test_can_be_rotated_left(self): piece = self.piece.rotate_left() expected_piece = "X....\n" + \ "XX...\n" + \ "XXX..\n" + \ ".....\n" + \ ".....\n" self.assertEqual(expected_piece, str(piece))
def setUp(self): self.board = Board(3, 3) self.board.drop(Piece('X')) self.board.tick() self.board.tick() self.board.tick() self.board.drop(Piece('Y')) self.board.tick() self.expected_board = "...\n" + ".Y.\n" + ".X.\n"
def draw(self, square = None): sq_pad = 8 font_size = 14 fen_model = fromFEN(START_BOARD) if(len(self.squares) == 0): for r in range(0, len(fen_model)): rank = fen_model[r] row = [] for s in range(0, len(rank)): sq = rank[s] _x = sq['_x'] _y = sq['_y'] tx = self.sq_size*_x ty = self.sq_size*_y toggle_color = is_even(_x+1) ^ is_even(_y+1) sq_piece = None if(sq['piece']): sq_piece = Piece({ '_x' : _x, '_y' : _y, 'x': tx, 'y': ty, 'size': self.sq_size - (sq_pad*2), 'role': sq['piece']['role'], 'color': sq['piece']['color'], 'path': [] }) square = Square({ 'size': self.sq_size, '_x' : _x, '_y' : _y, 'x' : tx, 'y' : ty, 'pad': sq_pad, 'font_size': font_size, 'piece': sq_piece, 'color': DARK if toggle_color else LIGHT, 'text_color': LIGHT if toggle_color else DARK, 'label': str(chr(73-(_y+1))) + str(_x+1), 'file': str(_x+1) if _y == 7 else None, 'rank': str(chr(73-(_y+1))) if _x == 0 else None, 'settings': { 'draw_coords': False, 'draw_rankfile': True } }) square.draw() row.append(square) self.squares.append(row) row_blits = list(map(lambda s: (s.surface, (s.x, s.y)), row)) self.surface.blits(row_blits) return self.surface
def create_board(position: Point, size: Size, columns: int, rows: int, tile_size: Size) -> MatchThreeBoard: if columns < 0: raise AttributeError(f'The number of columns must be positive') if rows < 0: raise AttributeError(f'The number of rows must be positive') offset = Point(int((size.width - tile_size.width * columns) / 2), int((size.height - tile_size.height * rows) / 2)) board = MatchThreeBoard(position.to_tuple(), size.to_tuple()) type_board: List[List[PieceType]] = [] for index in range(0, columns): position = Point(index * tile_size.height, 0) + offset column = Column(position, Size(tile_size.width, tile_size.height * rows)) for row in range(0, rows): if len(type_board) <= row: type_board.append([]) position = Point(0, row * tile_size.width) piece = Piece(position.to_tuple(), tile_size.to_tuple()) is_match = True new_piece = PieceType.BLACK while is_match: new_piece = PieceType.get_random_piece() is_match = src.piece.is_column_combination(board=type_board, column=index, row=row, new_piece=new_piece) is_match = is_match or src.piece.is_row_combination( board=type_board, column=index, row=row, new_piece=new_piece) piece.sprite = GraphicResource(new_piece.value, tile_size) piece.type = new_piece type_board[row].append(new_piece) column.children.append(piece) board.children.append(column) return board
def test_read_type_from_encoding(): assert Piece("0p").type == Piece.PAWN assert Piece("0r").type == Piece.ROOK assert Piece("0b").type == Piece.BISHOP assert Piece("0n").type == Piece.KNIGHT assert Piece("0q").type == Piece.QUEEN assert Piece("0k").type == Piece.KING
def setUp(self): self.board = Board(3, 3) self.board.drop(Piece('X')) self.board.tick() self.board.tick()
def test_at_most_one_block_may_be_falling_at_a_time(self): with self.assertRaises(IllegalStateException): self.board.drop(Piece('Y')) expected_board = ".X.\n" + 2 * "...\n" self.assertEqual(expected_board, str(self.board))
def _new_piece() -> Piece: piece = Piece((0, -Piece.PIECE_SIZE.height), Piece.PIECE_SIZE.to_tuple()) piece.type = PieceType.get_random_piece() return piece
def add_many_pieces(self, number_of_pieces, colour, location): for _ in range(number_of_pieces): self.__pieces.append(Piece(colour, location))
def move(self, move: Move, board: List[List[Piece]], en_passant_target: Coordinate) -> None: """ makes specified move on given board arguments: move -- move to make board -- board to make move on """ piece = self.piece_at(move.origin, board) # Remove captured pieces from piece sets if move.capture: board[move.dest.get_rank()][move.dest.get_file()] = None if move.move_type == MoveType.EN_PASSANT: if piece.color == Color.WHITE: board[move.origin.get_rank() - 1][move.origin.get_file()] = None elif piece.color == Color.BLACK: board[move.origin.get_rank() + 1][move.origin.get_file()] = None # Move piece on board board[move.dest.get_rank()][move.dest.get_file()] = piece board[move.origin.get_rank()][move.origin.get_file()] = None piece.coordinate = move.dest piece.moved = True # Castling moves if move.move_type == MoveType.CASTLE: rook: Piece direction = int( (move.dest.get_file() - move.origin.get_file()) / abs( (move.dest.get_file() - move.origin.get_file()))) if direction < 0 and piece.color == Color.WHITE: rook = self.piece_at(Coordinate(0, 0), board) board[0][3] = rook board[0][0] = None rook.coordinate = Coordinate(0, 3) elif direction > 0 and piece.color == Color.WHITE: rook = self.piece_at(Coordinate(0, self.WIDTH - 1), board) board[0][self.WIDTH - 3] = rook board[0][self.WIDTH - 1] = None rook.coordinate = Coordinate(0, self.WIDTH - 3) elif direction < 0 and piece.color == Color.BLACK: rook = self.piece_at(Coordinate(self.HEIGHT - 1, 0), board) board[self.HEIGHT - 1][3] = rook board[self.HEIGHT - 1][0] = None rook.coordinate = Coordinate(self.HEIGHT - 1, 3) elif direction > 0 and piece.color == Color.BLACK: rook = self.piece_at( Coordinate(self.HEIGHT - 1, self.WIDTH - 1), board) board[self.HEIGHT - 1][self.WIDTH - 3] = rook board[self.HEIGHT - 1][self.WIDTH - 1] = None rook.coordinate = Coordinate(self.HEIGHT - 1, self.WIDTH - 3) rook.moved = True # Pawn promotion moves if move.move_type == MoveType.N_PROMO: board[move.dest.get_rank()][move.dest.get_file()] = Piece( piece.color, move.dest, Type.KNIGHT, True) elif move.move_type == MoveType.B_PROMO: board[move.dest.get_rank()][move.dest.get_file()] = Piece( piece.color, move.dest, Type.BISHOP, True) elif move.move_type == MoveType.R_PROMO: board[move.dest.get_rank()][move.dest.get_file()] = Piece( piece.color, move.dest, Type.ROOK, True) elif move.move_type == MoveType.Q_PROMO: board[move.dest.get_rank()][move.dest.get_file()] = Piece( piece.color, move.dest, Type.QUEEN, True) # Update en-passant target if move.move_type == MoveType.DOUBLE: en_passant_target = (Coordinate(move.dest.get_rank() - 1, move.dest.get_file()) if piece.color == Color.WHITE else Coordinate( move.dest.get_rank() + 1, move.dest.get_file())) else: en_passant_target = None
def __init__( self, fen_string: Union[ str, None] = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", ) -> None: """ initialize the board object arguments: fen_string -- game specifications using Forsyth–Edwards Notation https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation """ # Build empty board self.board = [[]] * self.HEIGHT for row in range(self.HEIGHT): self.board[row] = [None] * self.WIDTH # Parse fen string board_specs: List = fen_string.split(" ") board_placement: List = board_specs[0].split("/") self.current_move = Color.WHITE if board_specs[ 1] == "w" else Color.BLACK self.en_passant_target = (chess_to_coordinate(board_specs[3]) if board_specs[3] != "-" else None) # Populate board from fen specification for board_rank in range(self.HEIGHT): board_file: int = 0 i: int = 0 while board_file < self.WIDTH: if board_placement[self.HEIGHT - 1 - board_rank][i].isnumeric(): board_file += int(board_placement[self.HEIGHT - 1 - board_rank][i]) i += 1 if board_file >= self.WIDTH: break piece_char: str = board_placement[self.HEIGHT - 1 - board_rank][i] if piece_char == "P": self.board[board_rank][board_file] = Piece( Color.WHITE, Coordinate(board_rank, board_file), Type.PAWN) elif piece_char == "N": self.board[board_rank][board_file] = Piece( Color.WHITE, Coordinate(board_rank, board_file), Type.KNIGHT) elif piece_char == "B": self.board[board_rank][board_file] = Piece( Color.WHITE, Coordinate(board_rank, board_file), Type.BISHOP) elif piece_char == "R": self.board[board_rank][board_file] = Piece( Color.WHITE, Coordinate(board_rank, board_file), Type.ROOK) elif piece_char == "Q": self.board[board_rank][board_file] = Piece( Color.WHITE, Coordinate(board_rank, board_file), Type.QUEEN) elif piece_char == "K": self.board[board_rank][board_file] = Piece( Color.WHITE, Coordinate(board_rank, board_file), Type.KING) elif piece_char == "p": self.board[board_rank][board_file] = Piece( Color.BLACK, Coordinate(board_rank, board_file), Type.PAWN) elif piece_char == "n": self.board[board_rank][board_file] = Piece( Color.BLACK, Coordinate(board_rank, board_file), Type.KNIGHT) elif piece_char == "b": self.board[board_rank][board_file] = Piece( Color.BLACK, Coordinate(board_rank, board_file), Type.BISHOP) elif piece_char == "r": self.board[board_rank][board_file] = Piece( Color.BLACK, Coordinate(board_rank, board_file), Type.ROOK) elif piece_char == "q": self.board[board_rank][board_file] = Piece( Color.BLACK, Coordinate(board_rank, board_file), Type.QUEEN) elif piece_char == "k": self.board[board_rank][board_file] = Piece( Color.BLACK, Coordinate(board_rank, board_file), Type.KING) i += 1 board_file += 1 # Set castling eligibility rook: Piece rook = self.piece_at(Coordinate(0, 0), self.board) if rook and rook.piece_type == Type.ROOK and not "Q" in board_specs[2]: rook.moved = True rook = self.piece_at(Coordinate(0, self.WIDTH - 1), self.board) if rook and rook.piece_type == Type.ROOK and not "K" in board_specs[2]: rook.moved = True rook = self.piece_at(Coordinate(self.HEIGHT - 1, 0), self.board) if rook and rook.piece_type == Type.ROOK and not "q" in board_specs[2]: rook.moved = True rook = self.piece_at(Coordinate(self.HEIGHT - 1, self.WIDTH - 1), self.board) if rook and rook.piece_type == Type.ROOK and not "k" in board_specs[2]: rook.moved = True
def test_read_color_from_encoding(): assert Piece("0p").color == Piece.WHITE assert Piece("1p").color == Piece.BLACK