Skip to content
This repository was archived by the owner on Jul 2, 2024. It is now read-only.

Commit fda605e

Browse files
committed
Applied enhancements to "chess" package structure
Signed-off-by: Serhii Horodilov <sgorodil@gmail.com>
1 parent 7b0488a commit fda605e

File tree

5 files changed

+239
-211
lines changed

5 files changed

+239
-211
lines changed

src/chess/__init__.py

Lines changed: 15 additions & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -3,199 +3,18 @@
33
44
"""
55

6-
import logging
7-
from typing import List, Tuple
8-
9-
logger = logging.getLogger(__name__)
10-
11-
12-
class Piece:
13-
"""Chess piece model
14-
15-
:ivar name: the name of a piece (e.g. "king", "pawn")
16-
:type name: str
17-
:ivar position: the position on a chess board
18-
:type position: tuple
19-
:ivar is_white: a flag indicating if a chess piece is white
20-
:type is_white: bool
21-
22-
"""
23-
24-
name: str = "piece"
25-
26-
def __init__(self,
27-
is_white: bool = True,
28-
position: Tuple[int, int] = (0, 0)) -> None:
29-
"""Initialize instance
30-
31-
:param is_white: indicating if a piece is white. Defaults to True.
32-
:type is_white: bool
33-
:param position: initial piece position. Defaults to (0, 0).
34-
:type position: tuple
35-
36-
"""
37-
38-
self.is_white = is_white
39-
self.position = position
40-
41-
def __repr__(self) -> str:
42-
"""Return a string representation of an instance"""
43-
44-
return f"{self.__class__.__name__}({self.is_white}, {self.position})"
45-
46-
def __str__(self) -> str:
47-
"""Return a string version of an instance"""
48-
49-
color = "white" if self.is_white else "black"
50-
51-
return f"{color} {self.name} at {self.position}"
52-
53-
def swap_color(self) -> None:
54-
"""Change the piece color to the opposite one"""
55-
56-
self.is_white = not self.is_white
57-
58-
def set_position(self, position: Tuple[int, int]) -> None:
59-
"""Change piece position to a specified one
60-
61-
:param position: new position for a piece
62-
:type position: tuple
63-
64-
"""
65-
66-
if within_board(position):
67-
self.position = position
68-
return
69-
70-
logger.warning("Position %s is outside the board", position)
71-
72-
def can_move(self, position: Tuple[int, int]) -> bool:
73-
"""Check if a move to a specified position is valid
74-
75-
:param position: a position to check
76-
:type position: tuple
77-
78-
:return: True if move is valid, otherwise False
79-
:rtype: bool
80-
81-
"""
82-
83-
raise NotImplementedError
84-
85-
def get_delta(self, position: Tuple[int, int]) -> Tuple[int, int]:
86-
"""Return the deltas between current position and the specified one
87-
88-
:param position: a position to calculate delta with
89-
:type position: tuple
90-
:return: a pair of delta x and delta y values
91-
:rtype: tuple
92-
93-
"""
94-
95-
position_x, position_y = position
96-
current_x, current_y = self.position
97-
98-
return position_x - current_x, position_y - current_y
99-
100-
101-
class King(Piece): # pylint: disable=C0115
102-
name = "king"
103-
104-
def can_move(self, position: Tuple[int, int]) -> bool:
105-
delta_x, delta_y = self.get_delta(position)
106-
if not -1 <= delta_x <= 1 or not -1 <= delta_y <= 1:
107-
return False
108-
109-
return within_board(position)
110-
111-
112-
class Queen(Piece): # pylint: disable=C0115
113-
name = "queen"
114-
115-
def can_move(self, position: Tuple[int, int]) -> bool:
116-
delta_x, delta_y = self.get_delta(position)
117-
if abs(delta_x) != abs(delta_y) and delta_x != 0 and delta_y != 0:
118-
return False
119-
120-
return within_board(position)
121-
122-
123-
class Bishop(Piece): # pylint: disable=C0115
124-
name = "bishop"
125-
126-
def can_move(self, position: Tuple[int, int]) -> bool:
127-
delta_x, delta_y = self.get_delta(position)
128-
if abs(delta_x) != abs(delta_y):
129-
return False
130-
131-
return within_board(position)
132-
133-
134-
class Knight(Piece): # pylint: disable=C0115
135-
name = "knight"
136-
137-
def can_move(self, position: Tuple[int, int]) -> bool:
138-
delta_x, delta_y = self.get_delta(position)
139-
if (abs(delta_x), abs(delta_y)) not in ((2, 1), (1, 2)):
140-
return False
141-
142-
return within_board(position)
143-
144-
145-
class Rook(Piece): # pylint: disable=C0115
146-
name = "rook"
147-
148-
def can_move(self, position: Tuple[int, int]) -> bool:
149-
delta_x, delta_y = self.get_delta(position)
150-
if delta_x != 0 and delta_y != 0:
151-
return False
152-
153-
return within_board(position)
154-
155-
156-
class Pawn(Piece): # pylint: disable=C0115
157-
name = "pawn"
158-
159-
def can_move(self, position: Tuple[int, int]) -> bool:
160-
delta_x, delta_y = self.get_delta(position)
161-
if delta_x != 0:
162-
return False
163-
if self.is_white and delta_y != 1:
164-
return False
165-
if not self.is_white and delta_y != -1:
166-
return False
167-
168-
return within_board(position)
169-
170-
171-
def within_board(position: Tuple[int, int]) -> bool:
172-
"""Check if position is within a chess board
173-
174-
:param position: a position to check
175-
:type position: tuple
176-
177-
:return: True if position is within a chess board, otherwise False
178-
:rtype: bool
179-
180-
"""
181-
182-
position_x, position_y = position
183-
184-
return 0 <= position_x <= 7 and 0 <= position_y <= 7
185-
186-
187-
def filter_can_move(pieces: List[Piece],
188-
position: Tuple[int, int]) -> List[Piece]:
189-
"""Filter the list of chess piece
190-
191-
:param pieces: a list of chess pieces
192-
:type pieces: list
193-
:param position: a position to check piece move
194-
:type position: tuple
195-
196-
:return: a list of pieces that can move to specified position
197-
:rtype: list
198-
199-
"""
200-
201-
return [piece for piece in pieces if piece.can_move(position)]
6+
__author__ = "Serhii Horodilov <sgorodil@gmail.com>"
7+
__all__ = [
8+
"filter_can_move",
9+
"within_board",
10+
"Piece",
11+
"King",
12+
"Queen",
13+
"Bishop",
14+
"Knight",
15+
"Rook",
16+
"Pawn",
17+
]
18+
19+
from chess.func import filter_can_move, within_board
20+
from chess.piece import Bishop, King, Knight, Pawn, Piece, Queen, Rook

src/chess/func.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"""
2+
Chess board functions
3+
4+
"""
5+
6+
from __future__ import annotations
7+
8+
from typing import List, Tuple, TYPE_CHECKING
9+
10+
if TYPE_CHECKING:
11+
from chess.piece import Piece
12+
13+
14+
def within_board(position: Tuple[int, int]) -> bool:
15+
"""Check if position is within a chess board
16+
17+
:param position: a position to check
18+
:type position: tuple
19+
20+
:return: True if position is within a chess board, otherwise False
21+
:rtype: bool
22+
23+
"""
24+
25+
position_x, position_y = position
26+
27+
return 0 <= position_x <= 7 and 0 <= position_y <= 7
28+
29+
30+
def filter_can_move(pieces: List[Piece],
31+
position: Tuple[int, int]) -> List[Piece]:
32+
"""Filter the list of chess piece
33+
34+
:param pieces: a list of chess pieces
35+
:type pieces: list
36+
:param position: a position to check piece move
37+
:type position: tuple
38+
39+
:return: a list of pieces that can move to specified position
40+
:rtype: list
41+
42+
"""
43+
44+
return [piece for piece in pieces if piece.can_move(position)]

0 commit comments

Comments
 (0)