fisch-chess 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,144 @@
1
+ Metadata-Version: 2.4
2
+ Name: fisch-chess
3
+ Version: 0.1.0
4
+ Summary: A lightweight terminal chess game written in Python.
5
+ Requires-Python: >=3.11
6
+ Description-Content-Type: text/markdown
7
+
8
+ # FISCH CHESS
9
+
10
+ > chess built from scratch, for the terminal.
11
+
12
+ This is a lightweight chess game written in Python and played entirely inside the terminal(v1).
13
+
14
+ ## ✦ Features
15
+ ```
16
+ [-] local two-player chess
17
+ [-] simple computer opponent
18
+ [-] legal move validation
19
+ [-] check + checkmate
20
+ [-] castling
21
+ [-] en passant
22
+ [-] pawn promotion
23
+ [-] stalemate + draw detection
24
+ [-] undo / redo
25
+ [-] move history
26
+ [-] FEN loading
27
+ [-] puzzle mode
28
+ ```
29
+
30
+ chess logic is implemented inside the project itself insetad of relying on Stockish, Lichess, Chess(dot)com or another chess library/service
31
+
32
+ ## ✦ Installation
33
+
34
+ You need:
35
+ `Python 3.11+`
36
+
37
+ Clone the repo:
38
+
39
+ > `git clone https://github.com/noxindeed/fisch-chess/`
40
+ > `cd fisch-chess`
41
+
42
+ Optional, but recommended is to run it in a venv
43
+
44
+ ## ✦ Run
45
+
46
+ From the project root:
47
+
48
+ `python3 -m src.main`
49
+
50
+ You should get:
51
+ ```
52
+ FISCH CHESS
53
+ ===========
54
+
55
+ 1. New Game (two players, offline)
56
+ 2. New Game (vs not so smart AI)
57
+ 3. Load Position (FEN)
58
+ 4. Puzzle Mode
59
+ 5. Quit
60
+ ```
61
+
62
+ ## moves
63
+
64
+ Fisch uses coordinate notation.
65
+ So,
66
+
67
+ `e2e4` means: `e2 → e4`
68
+
69
+ Knight example: `g1f3`
70
+
71
+ Promotion: `e7e8q`
72
+
73
+ Promotion pieces:
74
+
75
+ - q queen
76
+ - r rook
77
+ - b bishop
78
+ - n knight
79
+
80
+ ## ✦ Commands
81
+
82
+ While playing:
83
+
84
+ u - undo
85
+ r - redo
86
+ h - move history
87
+ f - show FEN
88
+ n - new game
89
+ q - back to menu
90
+
91
+ ## ✦ Project structure
92
+ ```
93
+ fisch-chess/
94
+
95
+ └── src/
96
+ ├── main.py
97
+ ├── engine.py
98
+ ├── board.py
99
+ ├── moves.py
100
+ ├── pieces.py
101
+ └── __init__.py
102
+ ```
103
+
104
+ - main.py
105
+
106
+ Terminal UI, menus, commands, puzzles and the computer player.
107
+
108
+ - engine.py
109
+
110
+ Game state, legal move filtering, checks, draws, FEN, history and move application.
111
+
112
+ - board.py
113
+
114
+ Board representation, coordinates and attack detection.
115
+
116
+ - moves.py
117
+
118
+ Pseudo-legal move generation for every piece.
119
+
120
+ - pieces.py
121
+
122
+ Piece/color helpers.
123
+
124
+ ## ✦ Future plans
125
+ V2
126
+ ```
127
+ ├── online multiplayer
128
+ ├── create / join game codes
129
+ ├── real-time moves
130
+ ├── reconnecting
131
+ ├── resignation
132
+ └── draw offers
133
+ ```
134
+ later
135
+ ```
136
+ ├── rematches
137
+ ├── chess clocks
138
+ ├── spectators
139
+ ├── saved games
140
+ ├── better puzzles
141
+ ├── stronger AI
142
+ ├── game history
143
+ └── web client
144
+ ```
@@ -0,0 +1,137 @@
1
+ # FISCH CHESS
2
+
3
+ > chess built from scratch, for the terminal.
4
+
5
+ This is a lightweight chess game written in Python and played entirely inside the terminal(v1).
6
+
7
+ ## ✦ Features
8
+ ```
9
+ [-] local two-player chess
10
+ [-] simple computer opponent
11
+ [-] legal move validation
12
+ [-] check + checkmate
13
+ [-] castling
14
+ [-] en passant
15
+ [-] pawn promotion
16
+ [-] stalemate + draw detection
17
+ [-] undo / redo
18
+ [-] move history
19
+ [-] FEN loading
20
+ [-] puzzle mode
21
+ ```
22
+
23
+ chess logic is implemented inside the project itself insetad of relying on Stockish, Lichess, Chess(dot)com or another chess library/service
24
+
25
+ ## ✦ Installation
26
+
27
+ You need:
28
+ `Python 3.11+`
29
+
30
+ Clone the repo:
31
+
32
+ > `git clone https://github.com/noxindeed/fisch-chess/`
33
+ > `cd fisch-chess`
34
+
35
+ Optional, but recommended is to run it in a venv
36
+
37
+ ## ✦ Run
38
+
39
+ From the project root:
40
+
41
+ `python3 -m src.main`
42
+
43
+ You should get:
44
+ ```
45
+ FISCH CHESS
46
+ ===========
47
+
48
+ 1. New Game (two players, offline)
49
+ 2. New Game (vs not so smart AI)
50
+ 3. Load Position (FEN)
51
+ 4. Puzzle Mode
52
+ 5. Quit
53
+ ```
54
+
55
+ ## moves
56
+
57
+ Fisch uses coordinate notation.
58
+ So,
59
+
60
+ `e2e4` means: `e2 → e4`
61
+
62
+ Knight example: `g1f3`
63
+
64
+ Promotion: `e7e8q`
65
+
66
+ Promotion pieces:
67
+
68
+ - q queen
69
+ - r rook
70
+ - b bishop
71
+ - n knight
72
+
73
+ ## ✦ Commands
74
+
75
+ While playing:
76
+
77
+ u - undo
78
+ r - redo
79
+ h - move history
80
+ f - show FEN
81
+ n - new game
82
+ q - back to menu
83
+
84
+ ## ✦ Project structure
85
+ ```
86
+ fisch-chess/
87
+
88
+ └── src/
89
+ ├── main.py
90
+ ├── engine.py
91
+ ├── board.py
92
+ ├── moves.py
93
+ ├── pieces.py
94
+ └── __init__.py
95
+ ```
96
+
97
+ - main.py
98
+
99
+ Terminal UI, menus, commands, puzzles and the computer player.
100
+
101
+ - engine.py
102
+
103
+ Game state, legal move filtering, checks, draws, FEN, history and move application.
104
+
105
+ - board.py
106
+
107
+ Board representation, coordinates and attack detection.
108
+
109
+ - moves.py
110
+
111
+ Pseudo-legal move generation for every piece.
112
+
113
+ - pieces.py
114
+
115
+ Piece/color helpers.
116
+
117
+ ## ✦ Future plans
118
+ V2
119
+ ```
120
+ ├── online multiplayer
121
+ ├── create / join game codes
122
+ ├── real-time moves
123
+ ├── reconnecting
124
+ ├── resignation
125
+ └── draw offers
126
+ ```
127
+ later
128
+ ```
129
+ ├── rematches
130
+ ├── chess clocks
131
+ ├── spectators
132
+ ├── saved games
133
+ ├── better puzzles
134
+ ├── stronger AI
135
+ ├── game history
136
+ └── web client
137
+ ```
@@ -0,0 +1,144 @@
1
+ Metadata-Version: 2.4
2
+ Name: fisch-chess
3
+ Version: 0.1.0
4
+ Summary: A lightweight terminal chess game written in Python.
5
+ Requires-Python: >=3.11
6
+ Description-Content-Type: text/markdown
7
+
8
+ # FISCH CHESS
9
+
10
+ > chess built from scratch, for the terminal.
11
+
12
+ This is a lightweight chess game written in Python and played entirely inside the terminal(v1).
13
+
14
+ ## ✦ Features
15
+ ```
16
+ [-] local two-player chess
17
+ [-] simple computer opponent
18
+ [-] legal move validation
19
+ [-] check + checkmate
20
+ [-] castling
21
+ [-] en passant
22
+ [-] pawn promotion
23
+ [-] stalemate + draw detection
24
+ [-] undo / redo
25
+ [-] move history
26
+ [-] FEN loading
27
+ [-] puzzle mode
28
+ ```
29
+
30
+ chess logic is implemented inside the project itself insetad of relying on Stockish, Lichess, Chess(dot)com or another chess library/service
31
+
32
+ ## ✦ Installation
33
+
34
+ You need:
35
+ `Python 3.11+`
36
+
37
+ Clone the repo:
38
+
39
+ > `git clone https://github.com/noxindeed/fisch-chess/`
40
+ > `cd fisch-chess`
41
+
42
+ Optional, but recommended is to run it in a venv
43
+
44
+ ## ✦ Run
45
+
46
+ From the project root:
47
+
48
+ `python3 -m src.main`
49
+
50
+ You should get:
51
+ ```
52
+ FISCH CHESS
53
+ ===========
54
+
55
+ 1. New Game (two players, offline)
56
+ 2. New Game (vs not so smart AI)
57
+ 3. Load Position (FEN)
58
+ 4. Puzzle Mode
59
+ 5. Quit
60
+ ```
61
+
62
+ ## moves
63
+
64
+ Fisch uses coordinate notation.
65
+ So,
66
+
67
+ `e2e4` means: `e2 → e4`
68
+
69
+ Knight example: `g1f3`
70
+
71
+ Promotion: `e7e8q`
72
+
73
+ Promotion pieces:
74
+
75
+ - q queen
76
+ - r rook
77
+ - b bishop
78
+ - n knight
79
+
80
+ ## ✦ Commands
81
+
82
+ While playing:
83
+
84
+ u - undo
85
+ r - redo
86
+ h - move history
87
+ f - show FEN
88
+ n - new game
89
+ q - back to menu
90
+
91
+ ## ✦ Project structure
92
+ ```
93
+ fisch-chess/
94
+
95
+ └── src/
96
+ ├── main.py
97
+ ├── engine.py
98
+ ├── board.py
99
+ ├── moves.py
100
+ ├── pieces.py
101
+ └── __init__.py
102
+ ```
103
+
104
+ - main.py
105
+
106
+ Terminal UI, menus, commands, puzzles and the computer player.
107
+
108
+ - engine.py
109
+
110
+ Game state, legal move filtering, checks, draws, FEN, history and move application.
111
+
112
+ - board.py
113
+
114
+ Board representation, coordinates and attack detection.
115
+
116
+ - moves.py
117
+
118
+ Pseudo-legal move generation for every piece.
119
+
120
+ - pieces.py
121
+
122
+ Piece/color helpers.
123
+
124
+ ## ✦ Future plans
125
+ V2
126
+ ```
127
+ ├── online multiplayer
128
+ ├── create / join game codes
129
+ ├── real-time moves
130
+ ├── reconnecting
131
+ ├── resignation
132
+ └── draw offers
133
+ ```
134
+ later
135
+ ```
136
+ ├── rematches
137
+ ├── chess clocks
138
+ ├── spectators
139
+ ├── saved games
140
+ ├── better puzzles
141
+ ├── stronger AI
142
+ ├── game history
143
+ └── web client
144
+ ```
@@ -0,0 +1,14 @@
1
+ README.md
2
+ pyproject.toml
3
+ fisch_chess.egg-info/PKG-INFO
4
+ fisch_chess.egg-info/SOURCES.txt
5
+ fisch_chess.egg-info/dependency_links.txt
6
+ fisch_chess.egg-info/entry_points.txt
7
+ fisch_chess.egg-info/top_level.txt
8
+ src/__init__.py
9
+ src/__main__.py
10
+ src/board.py
11
+ src/engine.py
12
+ src/main.py
13
+ src/moves.py
14
+ src/pieces.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ fisch = src.main:main
@@ -0,0 +1,17 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "fisch-chess"
7
+ version = "0.1.0"
8
+ description = "A lightweight terminal chess game written in Python."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ dependencies = []
12
+
13
+ [project.scripts]
14
+ fisch = "src.main:main"
15
+
16
+ [tool.setuptools]
17
+ packages = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
File without changes
@@ -0,0 +1,164 @@
1
+ from .pieces import EMPTY, WHITE, BLACK, color_of, opponent
2
+
3
+ STARTING_FEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
4
+
5
+ # directions and offsets for mvmt
6
+ KNIGHT_OFFSETS = [
7
+ (-2,-1), (-2,1),(-1,-2),(-1,2),(1,-2),(1,2),
8
+ (2,-1),(2,1),
9
+ ]
10
+
11
+ KING_OFFSETS = [
12
+ (-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1),
13
+
14
+ ]
15
+
16
+ BISHOP_DIRECTIONS = [(-1,-1),(-1,1),(1,-1),(1,1)]
17
+ ROOK_DIRECTIONS = [(-1,0),(1,0),(0,-1),(0,1)]
18
+
19
+ QUEEN_DIRECTIONS = BISHOP_DIRECTIONS + ROOK_DIRECTIONS
20
+
21
+ def on_board(row, col):
22
+ return 0 <= row < 8 and 0 <= col < 8
23
+
24
+ def square_name(r,c):
25
+ # converts (r,c) to algebraic names
26
+ return chr(ord("a")+c) + str(8-r)
27
+
28
+ def parse_square(name):
29
+ # converts algebraic names to row,col pair
30
+ if len(name) != 2:
31
+ return None
32
+
33
+ file_ch, rank_ch = name[0], name[1]
34
+ if file_ch < "a" or file_ch > "h" or rank_ch < "1" or rank_ch > "8":
35
+ return None
36
+ return (8-int(rank_ch), ord(file_ch) - ord("a"))
37
+
38
+ class Board:
39
+ def __init__(self):
40
+ self.grid = [[EMPTY]*8 for _ in range(8)]
41
+
42
+ def get(self, row, col):
43
+ return self.grid[row][col]
44
+
45
+ def set(self, row,col,piece):
46
+ self.grid[row][col] = piece
47
+
48
+ def find_king(self, color):
49
+ target = "K" if color == WHITE else "k"
50
+ for row in range(8):
51
+ for col in range(8):
52
+ if self.grid[row][col] == target:
53
+ return (row,col)
54
+ return None
55
+
56
+ # attack detection
57
+
58
+ def is_square_attacked(self, row, col, by_color):
59
+
60
+ # pawns
61
+ pawn = "P" if by_color == WHITE else "p"
62
+ pawn_offset = 1 if by_color == WHITE else -1
63
+ for dc in (-1, 1):
64
+ r,c = row + pawn_offset, col+dc
65
+ if on_board(r, c) and self.grid[r][c] == pawn:
66
+ return True
67
+
68
+ # knights
69
+ knight = "N" if by_color == WHITE else "n"
70
+ for dr, dc in KNIGHT_OFFSETS:
71
+ r, c = row + dr, col + dc
72
+ if on_board(r,c) and self.grid[r][c] == knight:
73
+ return True
74
+
75
+ diagonals = ("B" if by_color == WHITE else "b",
76
+ "Q" if by_color == WHITE else "q")
77
+ straights = ("R" if by_color == WHITE else "r",
78
+ "Q" if by_color == WHITE else "q")
79
+
80
+ #kings
81
+ king = "K" if by_color == WHITE else "k"
82
+ for dr,dc in KING_OFFSETS:
83
+ r,c = row + dr, col + dc
84
+ if on_board(r,c) and self.grid[r][c] == king:
85
+ return True
86
+
87
+ diagonals= (
88
+ "B" if by_color == WHITE else "b",
89
+ "Q" if by_color == WHITE else "q",
90
+ )
91
+
92
+ straights = (
93
+ "R" if by_color == WHITE else "r",
94
+ "Q" if by_color == WHITE else "q",
95
+ )
96
+
97
+ if self._ray_attacks(row, col, BISHOP_DIRECTIONS, diagonals):
98
+ return True
99
+ if self._ray_attacks(row, col, ROOK_DIRECTIONS, straights):
100
+ return True
101
+ return False
102
+
103
+ def _ray_attacks(self, row, col, directions, attackers):
104
+ for dr, dc in directions:
105
+ r,c = row+dr, col+dc
106
+ while on_board(r,c):
107
+ piece = self.grid[r][c]
108
+ if piece != EMPTY:
109
+ if piece in attackers:
110
+ return True
111
+ break
112
+ r += dr
113
+ c += dc
114
+ return False
115
+
116
+ # FEN
117
+
118
+ def to_fen_board(self):
119
+ rows = []
120
+ for r in range(8):
121
+ empty = 0
122
+ out = ""
123
+ for col in range(8):
124
+ piece = self.grid[r][col]
125
+ if piece == EMPTY:
126
+ empty += 1
127
+ else:
128
+ if empty:
129
+ out += str(empty)
130
+ empty = 0
131
+ out += piece
132
+ if empty:
133
+ out += str(empty)
134
+ rows.append(out)
135
+ return "/".join(rows)
136
+
137
+ def load_fen_board(self, placement):
138
+ self.grid = [[EMPTY]*8 for _ in range(8)]
139
+ ranks = placement.split("/")
140
+
141
+ if len(ranks) != 8:
142
+ raise ValueError("FEN board must have 8 ranks")
143
+ for row, rank in enumerate(ranks):
144
+ col = 0
145
+ for ch in rank:
146
+ if ch.isdigit():
147
+ col += int(ch)
148
+ elif ch in "PNBRQKpnbrqk":
149
+ if col >= 8:
150
+ raise ValueError("FEN rank too long")
151
+ self.grid[row][col] = ch
152
+ col += 1
153
+ else:
154
+ raise ValueError(f"Invalid FEN character: {ch!r}")
155
+ if col != 8:
156
+ raise ValueError("FEN rank too short")
157
+
158
+
159
+
160
+
161
+
162
+
163
+
164
+