seks 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.
- seks-0.1.0/CHANGELOG.md +54 -0
- seks-0.1.0/LICENSE +21 -0
- seks-0.1.0/PKG-INFO +231 -0
- seks-0.1.0/README.md +203 -0
- seks-0.1.0/pyproject.toml +148 -0
- seks-0.1.0/pyproject.toml.orig +93 -0
- seks-0.1.0/seks/__init__.py +5 -0
- seks-0.1.0/seks/__main__.py +3 -0
- seks-0.1.0/seks/app.py +50 -0
- seks-0.1.0/seks/game.py +276 -0
- seks-0.1.0/seks/grid.py +230 -0
- seks-0.1.0/seks/main.py +37 -0
- seks-0.1.0/seks/renderer.py +143 -0
- seks-0.1.0/seks/resources.pyxres +0 -0
- seks-0.1.0/seks/style.py +103 -0
- seks-0.1.0/seks/themes.py +270 -0
- seks-0.1.0/seks/types.py +174 -0
- seks-0.1.0/seks/utils.py +15 -0
- seks-0.1.0/tests/test_game.py +347 -0
- seks-0.1.0/tests/test_grid.py +149 -0
- seks-0.1.0/tests/test_main.py +19 -0
- seks-0.1.0/tests/test_renderer.py +42 -0
- seks-0.1.0/tests/test_themes.py +118 -0
- seks-0.1.0/tests/test_types.py +90 -0
seks-0.1.0/CHANGELOG.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] - 2026-09-29
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- First public release on PyPI, with a `seks` command to start the game.
|
|
15
|
+
- Color themes, selected with `seks --theme NAME`: `felt` (the new default),
|
|
16
|
+
`classic` (the original colors), `wood`, `azulejo`, `paper`, `nord`,
|
|
17
|
+
`catppuccin-mocha`, `catppuccin-latte`, `dracula`, `gruvbox`, `solarized`,
|
|
18
|
+
`tokyo-night` and `rose-pine`.
|
|
19
|
+
- Rules manual with screenshots in the README.
|
|
20
|
+
- Test suite, linting, type checking and CI on GitHub Actions.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- A die now wins when it reaches the opponent's back row instead of its own.
|
|
25
|
+
- A winning move now ends the game and shows the victory screen.
|
|
26
|
+
- Clicking after a victory starts a new game.
|
|
27
|
+
- Undoing a move that captured dice no longer crashes.
|
|
28
|
+
- The victory screen no longer crashes when it is drawn.
|
|
29
|
+
- Clicking a selected die that already shows 6 now cancels the selection.
|
|
30
|
+
- Game sprites load from the installed package, not from the working directory.
|
|
31
|
+
- Clicking the board margin no longer selects a die on the opposite edge, and
|
|
32
|
+
the first gutter pixel after a cell no longer counts as part of the cell.
|
|
33
|
+
- A die on the board edge no longer captures dice on the opposite edge.
|
|
34
|
+
- Undo gives the turn back to the player who made the play, also after a
|
|
35
|
+
winning move, and clears the current selection.
|
|
36
|
+
- Loading a board (`Ctrl+L`) clears the undo history, and an invalid save file
|
|
37
|
+
is rejected with a warning instead of crashing the game.
|
|
38
|
+
- The victory screen overlay stays inside the board and its banner is centered.
|
|
39
|
+
- Save files also record whose turn it is, so loading a game restores the
|
|
40
|
+
player to move. Files that only contain the board are rejected.
|
|
41
|
+
- Errors while reading or writing the save file are logged instead of closing
|
|
42
|
+
the game.
|
|
43
|
+
- A player who cannot play (no dice left, or only blocked 6s) now loses,
|
|
44
|
+
instead of the game getting stuck.
|
|
45
|
+
- Holding the undo button no longer undoes several plays in a row: presses
|
|
46
|
+
less than one second apart are ignored.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- With a die selected, clicking another of your dice now selects it instead
|
|
51
|
+
of cancelling the selection.
|
|
52
|
+
|
|
53
|
+
[Unreleased]: https://github.com/fabiommendes/seks/compare/v0.1.0...HEAD
|
|
54
|
+
[0.1.0]: https://github.com/fabiommendes/seks/releases/tag/v0.1.0
|
seks-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Fábio Macêdo Mendes
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
seks-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: seks
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Seks: an abstract strategy game played with dice on an 11x11 board.
|
|
5
|
+
Keywords: game,board-game,abstract-strategy,dice,pyxel
|
|
6
|
+
Author: Fábio Macêdo Mendes
|
|
7
|
+
Author-email: Fábio Macêdo Mendes <fabiomacedomendes@gmail.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: X11 Applications
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Games/Entertainment :: Board Games
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Dist: pyxel>=2.3
|
|
22
|
+
Requires-Python: >=3.12
|
|
23
|
+
Project-URL: Homepage, https://github.com/fabiommendes/seks
|
|
24
|
+
Project-URL: Repository, https://github.com/fabiommendes/seks
|
|
25
|
+
Project-URL: Issues, https://github.com/fabiommendes/seks/issues
|
|
26
|
+
Project-URL: Changelog, https://github.com/fabiommendes/seks/blob/main/CHANGELOG.md
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# Seks
|
|
30
|
+
|
|
31
|
+
[](https://github.com/fabiommendes/seks/actions/workflows/ci.yml)
|
|
32
|
+
[](https://pypi.org/project/seks/)
|
|
33
|
+
[](https://pypi.org/project/seks/)
|
|
34
|
+
[](https://github.com/fabiommendes/seks/blob/main/LICENSE)
|
|
35
|
+
|
|
36
|
+
**Seks** is a two-player abstract strategy game played with dice on an 11×11
|
|
37
|
+
board. Every die is a piece whose face tells how far it can travel. Moving
|
|
38
|
+
spends that strength, so a player keeps choosing between advancing now and
|
|
39
|
+
charging dice up for later. It is built with [Pyxel](https://github.com/kitao/pyxel).
|
|
40
|
+
|
|
41
|
+
<p align="center">
|
|
42
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/01-setup.png" width="320" alt="The initial position">
|
|
43
|
+
</p>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
Seks needs Python 3.12 or newer. The easiest way to install the game is as a
|
|
49
|
+
standalone tool:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
uv tool install seks # or: pipx install seks
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
A plain `pip install seks` works too.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
Start the game with:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
seks
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`python -m seks` does the same thing. To run it from a clone of this
|
|
67
|
+
repository, use `uv run seks`.
|
|
68
|
+
|
|
69
|
+
| Action | Control |
|
|
70
|
+
|-------------------------------|------------------------------------------------|
|
|
71
|
+
| Select one of your dice | Left click on it |
|
|
72
|
+
| Move the selected die | Left click on a highlighted cell |
|
|
73
|
+
| Increment the selected die | Left click on it again |
|
|
74
|
+
| Switch the selection | Left click on another of your dice |
|
|
75
|
+
| Cancel the selection | Left click anywhere else |
|
|
76
|
+
| Undo the last play | Click the ↺ button in a corner of the screen (at most once per second; holding it undoes a single play) |
|
|
77
|
+
| Save / load the board | `Ctrl+S` / `Ctrl+L` (uses `game.save` in the current directory) |
|
|
78
|
+
| Start a new game after a win | Left click anywhere |
|
|
79
|
+
| Quit | `Esc` |
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
## Themes
|
|
83
|
+
|
|
84
|
+
Pick a color theme with `--theme`:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
seks --theme catppuccin-mocha
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The default theme is `felt`, and `classic` has the original colors of the
|
|
91
|
+
game. Run `seks --help` to list all themes.
|
|
92
|
+
|
|
93
|
+
<table>
|
|
94
|
+
<tr>
|
|
95
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/felt.png" width="160" alt="felt theme"><br><code>felt</code></td>
|
|
96
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/classic.png" width="160" alt="classic theme"><br><code>classic</code></td>
|
|
97
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/wood.png" width="160" alt="wood theme"><br><code>wood</code></td>
|
|
98
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/azulejo.png" width="160" alt="azulejo theme"><br><code>azulejo</code></td>
|
|
99
|
+
</tr>
|
|
100
|
+
<tr>
|
|
101
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/paper.png" width="160" alt="paper theme"><br><code>paper</code></td>
|
|
102
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/nord.png" width="160" alt="nord theme"><br><code>nord</code></td>
|
|
103
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/catppuccin-mocha.png" width="160" alt="catppuccin-mocha theme"><br><code>catppuccin-mocha</code></td>
|
|
104
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/catppuccin-latte.png" width="160" alt="catppuccin-latte theme"><br><code>catppuccin-latte</code></td>
|
|
105
|
+
</tr>
|
|
106
|
+
<tr>
|
|
107
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/dracula.png" width="160" alt="dracula theme"><br><code>dracula</code></td>
|
|
108
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/gruvbox.png" width="160" alt="gruvbox theme"><br><code>gruvbox</code></td>
|
|
109
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/solarized.png" width="160" alt="solarized theme"><br><code>solarized</code></td>
|
|
110
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/tokyo-night.png" width="160" alt="tokyo-night theme"><br><code>tokyo-night</code></td>
|
|
111
|
+
</tr>
|
|
112
|
+
<tr>
|
|
113
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/rose-pine.png" width="160" alt="rose-pine theme"><br><code>rose-pine</code></td>
|
|
114
|
+
</tr>
|
|
115
|
+
</table>
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
## Rules
|
|
119
|
+
|
|
120
|
+
### Setup
|
|
121
|
+
|
|
122
|
+
The board has 11 columns and 11 rows. Each player starts with 16 dice:
|
|
123
|
+
|
|
124
|
+
* 6 dice showing **1** on their back row, on every other cell;
|
|
125
|
+
* 10 dice showing **2** on the row in front of it, which is full except for the
|
|
126
|
+
center column.
|
|
127
|
+
|
|
128
|
+
White starts at the bottom of the screen and Black at the top. **White plays
|
|
129
|
+
first**, and the players take turns after that.
|
|
130
|
+
|
|
131
|
+
### Your turn
|
|
132
|
+
|
|
133
|
+
On your turn, click one of your dice to select it, then do **exactly one** of
|
|
134
|
+
the following.
|
|
135
|
+
|
|
136
|
+
**1. Move.** A die moves in a straight line in any of the 8 directions
|
|
137
|
+
(orthogonal or diagonal) by **at most as many cells as its value**. It cannot
|
|
138
|
+
jump over other dice or land on an occupied cell. After the move, **the die
|
|
139
|
+
shows the number of cells it traveled**: a 4 that moves 2 cells becomes a 2.
|
|
140
|
+
|
|
141
|
+
When you select a die, every cell it can reach is highlighted, and the number
|
|
142
|
+
shown on each cell is the value the die will have if it lands there. The
|
|
143
|
+
selected die itself shows a preview of its incremented value (see below).
|
|
144
|
+
|
|
145
|
+
<p align="center">
|
|
146
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/02-select.png" width="300" alt="A selected die and its possible moves">
|
|
147
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/04-move.png" width="300" alt="The die after moving three cells">
|
|
148
|
+
</p>
|
|
149
|
+
|
|
150
|
+
*Left: a white 2 is selected and can move one or two cells. Right: later on,
|
|
151
|
+
a white 3 moved three cells forward and still shows 3.*
|
|
152
|
+
|
|
153
|
+
**2. Increment.** Click the selected die again to add 1 to its value. This uses
|
|
154
|
+
up your turn. A die can reach at most **6**. Clicking a selected 6 again only
|
|
155
|
+
cancels the selection.
|
|
156
|
+
|
|
157
|
+
<p align="center">
|
|
158
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/03-increment.png" width="300" alt="A white die incremented from 2 to 3">
|
|
159
|
+
</p>
|
|
160
|
+
|
|
161
|
+
*White spent its first turn turning a 2 into a 3.*
|
|
162
|
+
|
|
163
|
+
### Captures
|
|
164
|
+
|
|
165
|
+
Captures are **custodial**: after you move a die, every enemy die that sits
|
|
166
|
+
orthogonally next to the cell where it landed (up, down, left or right) and
|
|
167
|
+
has one of your dice directly on its other side is captured and removed from
|
|
168
|
+
the board.
|
|
169
|
+
|
|
170
|
+
* A single move can capture in several directions at once.
|
|
171
|
+
* Diagonal neighbors are never captured.
|
|
172
|
+
* Only the player who moves captures: moving a die between two enemy dice is
|
|
173
|
+
safe.
|
|
174
|
+
* Incrementing a die never captures.
|
|
175
|
+
|
|
176
|
+
<p align="center">
|
|
177
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/05-before-capture.png" width="300" alt="Before the capture">
|
|
178
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/06-capture.png" width="300" alt="After the capture">
|
|
179
|
+
</p>
|
|
180
|
+
|
|
181
|
+
*The black 2 is flanked on its right by a white 3. White moves the other 3
|
|
182
|
+
up to the left of the black die and captures it.*
|
|
183
|
+
|
|
184
|
+
The counters on the left side of the screen show how many dice each player
|
|
185
|
+
has lost. The top counter counts White's losses and the bottom one counts
|
|
186
|
+
Black's.
|
|
187
|
+
|
|
188
|
+
### Winning
|
|
189
|
+
|
|
190
|
+
You win as soon as **one of your dice moves onto the opponent's back row**:
|
|
191
|
+
the top row for White, the bottom row for Black.
|
|
192
|
+
|
|
193
|
+
You also win when, after your play, **your opponent cannot play**: they have
|
|
194
|
+
lost every die, or each of their dice is a 6 with no free cell to move to.
|
|
195
|
+
|
|
196
|
+
<p align="center">
|
|
197
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/07-before-victory.png" width="300" alt="A white 3 with a free path to the top row">
|
|
198
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/08-victory.png" width="300" alt="White wins">
|
|
199
|
+
</p>
|
|
200
|
+
|
|
201
|
+
*The center column starts with a gap in the second row. This white 3 uses it
|
|
202
|
+
to reach the top row and win.*
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
## Development
|
|
206
|
+
|
|
207
|
+
The project uses [uv](https://docs.astral.sh/uv/) and
|
|
208
|
+
[taskipy](https://github.com/taskipy/taskipy):
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
git clone https://github.com/fabiommendes/seks.git
|
|
212
|
+
cd seks
|
|
213
|
+
uv sync
|
|
214
|
+
uv run task --list
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The main tasks are `task test`, `task lint`, `task docs`, `task ci` and
|
|
218
|
+
`task release`. `task screenshots` plays a scripted game and regenerates the
|
|
219
|
+
images in this README. See [CONTRIBUTING.md](https://github.com/fabiommendes/seks/blob/main/CONTRIBUTING.md)
|
|
220
|
+
for details.
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
## About the name
|
|
224
|
+
|
|
225
|
+
*Seks* means "six" in Danish, Norwegian and Faroese, after the highest face of
|
|
226
|
+
a die.
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
## License
|
|
230
|
+
|
|
231
|
+
Seks is released under the [MIT License](https://github.com/fabiommendes/seks/blob/main/LICENSE).
|
seks-0.1.0/README.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# Seks
|
|
2
|
+
|
|
3
|
+
[](https://github.com/fabiommendes/seks/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/seks/)
|
|
5
|
+
[](https://pypi.org/project/seks/)
|
|
6
|
+
[](https://github.com/fabiommendes/seks/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
**Seks** is a two-player abstract strategy game played with dice on an 11×11
|
|
9
|
+
board. Every die is a piece whose face tells how far it can travel. Moving
|
|
10
|
+
spends that strength, so a player keeps choosing between advancing now and
|
|
11
|
+
charging dice up for later. It is built with [Pyxel](https://github.com/kitao/pyxel).
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/01-setup.png" width="320" alt="The initial position">
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
Seks needs Python 3.12 or newer. The easiest way to install the game is as a
|
|
21
|
+
standalone tool:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
uv tool install seks # or: pipx install seks
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
A plain `pip install seks` works too.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
Start the game with:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
seks
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`python -m seks` does the same thing. To run it from a clone of this
|
|
39
|
+
repository, use `uv run seks`.
|
|
40
|
+
|
|
41
|
+
| Action | Control |
|
|
42
|
+
|-------------------------------|------------------------------------------------|
|
|
43
|
+
| Select one of your dice | Left click on it |
|
|
44
|
+
| Move the selected die | Left click on a highlighted cell |
|
|
45
|
+
| Increment the selected die | Left click on it again |
|
|
46
|
+
| Switch the selection | Left click on another of your dice |
|
|
47
|
+
| Cancel the selection | Left click anywhere else |
|
|
48
|
+
| Undo the last play | Click the ↺ button in a corner of the screen (at most once per second; holding it undoes a single play) |
|
|
49
|
+
| Save / load the board | `Ctrl+S` / `Ctrl+L` (uses `game.save` in the current directory) |
|
|
50
|
+
| Start a new game after a win | Left click anywhere |
|
|
51
|
+
| Quit | `Esc` |
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
## Themes
|
|
55
|
+
|
|
56
|
+
Pick a color theme with `--theme`:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
seks --theme catppuccin-mocha
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The default theme is `felt`, and `classic` has the original colors of the
|
|
63
|
+
game. Run `seks --help` to list all themes.
|
|
64
|
+
|
|
65
|
+
<table>
|
|
66
|
+
<tr>
|
|
67
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/felt.png" width="160" alt="felt theme"><br><code>felt</code></td>
|
|
68
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/classic.png" width="160" alt="classic theme"><br><code>classic</code></td>
|
|
69
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/wood.png" width="160" alt="wood theme"><br><code>wood</code></td>
|
|
70
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/azulejo.png" width="160" alt="azulejo theme"><br><code>azulejo</code></td>
|
|
71
|
+
</tr>
|
|
72
|
+
<tr>
|
|
73
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/paper.png" width="160" alt="paper theme"><br><code>paper</code></td>
|
|
74
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/nord.png" width="160" alt="nord theme"><br><code>nord</code></td>
|
|
75
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/catppuccin-mocha.png" width="160" alt="catppuccin-mocha theme"><br><code>catppuccin-mocha</code></td>
|
|
76
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/catppuccin-latte.png" width="160" alt="catppuccin-latte theme"><br><code>catppuccin-latte</code></td>
|
|
77
|
+
</tr>
|
|
78
|
+
<tr>
|
|
79
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/dracula.png" width="160" alt="dracula theme"><br><code>dracula</code></td>
|
|
80
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/gruvbox.png" width="160" alt="gruvbox theme"><br><code>gruvbox</code></td>
|
|
81
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/solarized.png" width="160" alt="solarized theme"><br><code>solarized</code></td>
|
|
82
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/tokyo-night.png" width="160" alt="tokyo-night theme"><br><code>tokyo-night</code></td>
|
|
83
|
+
</tr>
|
|
84
|
+
<tr>
|
|
85
|
+
<td align="center"><img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/themes/rose-pine.png" width="160" alt="rose-pine theme"><br><code>rose-pine</code></td>
|
|
86
|
+
</tr>
|
|
87
|
+
</table>
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
## Rules
|
|
91
|
+
|
|
92
|
+
### Setup
|
|
93
|
+
|
|
94
|
+
The board has 11 columns and 11 rows. Each player starts with 16 dice:
|
|
95
|
+
|
|
96
|
+
* 6 dice showing **1** on their back row, on every other cell;
|
|
97
|
+
* 10 dice showing **2** on the row in front of it, which is full except for the
|
|
98
|
+
center column.
|
|
99
|
+
|
|
100
|
+
White starts at the bottom of the screen and Black at the top. **White plays
|
|
101
|
+
first**, and the players take turns after that.
|
|
102
|
+
|
|
103
|
+
### Your turn
|
|
104
|
+
|
|
105
|
+
On your turn, click one of your dice to select it, then do **exactly one** of
|
|
106
|
+
the following.
|
|
107
|
+
|
|
108
|
+
**1. Move.** A die moves in a straight line in any of the 8 directions
|
|
109
|
+
(orthogonal or diagonal) by **at most as many cells as its value**. It cannot
|
|
110
|
+
jump over other dice or land on an occupied cell. After the move, **the die
|
|
111
|
+
shows the number of cells it traveled**: a 4 that moves 2 cells becomes a 2.
|
|
112
|
+
|
|
113
|
+
When you select a die, every cell it can reach is highlighted, and the number
|
|
114
|
+
shown on each cell is the value the die will have if it lands there. The
|
|
115
|
+
selected die itself shows a preview of its incremented value (see below).
|
|
116
|
+
|
|
117
|
+
<p align="center">
|
|
118
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/02-select.png" width="300" alt="A selected die and its possible moves">
|
|
119
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/04-move.png" width="300" alt="The die after moving three cells">
|
|
120
|
+
</p>
|
|
121
|
+
|
|
122
|
+
*Left: a white 2 is selected and can move one or two cells. Right: later on,
|
|
123
|
+
a white 3 moved three cells forward and still shows 3.*
|
|
124
|
+
|
|
125
|
+
**2. Increment.** Click the selected die again to add 1 to its value. This uses
|
|
126
|
+
up your turn. A die can reach at most **6**. Clicking a selected 6 again only
|
|
127
|
+
cancels the selection.
|
|
128
|
+
|
|
129
|
+
<p align="center">
|
|
130
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/03-increment.png" width="300" alt="A white die incremented from 2 to 3">
|
|
131
|
+
</p>
|
|
132
|
+
|
|
133
|
+
*White spent its first turn turning a 2 into a 3.*
|
|
134
|
+
|
|
135
|
+
### Captures
|
|
136
|
+
|
|
137
|
+
Captures are **custodial**: after you move a die, every enemy die that sits
|
|
138
|
+
orthogonally next to the cell where it landed (up, down, left or right) and
|
|
139
|
+
has one of your dice directly on its other side is captured and removed from
|
|
140
|
+
the board.
|
|
141
|
+
|
|
142
|
+
* A single move can capture in several directions at once.
|
|
143
|
+
* Diagonal neighbors are never captured.
|
|
144
|
+
* Only the player who moves captures: moving a die between two enemy dice is
|
|
145
|
+
safe.
|
|
146
|
+
* Incrementing a die never captures.
|
|
147
|
+
|
|
148
|
+
<p align="center">
|
|
149
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/05-before-capture.png" width="300" alt="Before the capture">
|
|
150
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/06-capture.png" width="300" alt="After the capture">
|
|
151
|
+
</p>
|
|
152
|
+
|
|
153
|
+
*The black 2 is flanked on its right by a white 3. White moves the other 3
|
|
154
|
+
up to the left of the black die and captures it.*
|
|
155
|
+
|
|
156
|
+
The counters on the left side of the screen show how many dice each player
|
|
157
|
+
has lost. The top counter counts White's losses and the bottom one counts
|
|
158
|
+
Black's.
|
|
159
|
+
|
|
160
|
+
### Winning
|
|
161
|
+
|
|
162
|
+
You win as soon as **one of your dice moves onto the opponent's back row**:
|
|
163
|
+
the top row for White, the bottom row for Black.
|
|
164
|
+
|
|
165
|
+
You also win when, after your play, **your opponent cannot play**: they have
|
|
166
|
+
lost every die, or each of their dice is a 6 with no free cell to move to.
|
|
167
|
+
|
|
168
|
+
<p align="center">
|
|
169
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/07-before-victory.png" width="300" alt="A white 3 with a free path to the top row">
|
|
170
|
+
<img src="https://raw.githubusercontent.com/fabiommendes/seks/main/assets/screenshots/08-victory.png" width="300" alt="White wins">
|
|
171
|
+
</p>
|
|
172
|
+
|
|
173
|
+
*The center column starts with a gap in the second row. This white 3 uses it
|
|
174
|
+
to reach the top row and win.*
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
## Development
|
|
178
|
+
|
|
179
|
+
The project uses [uv](https://docs.astral.sh/uv/) and
|
|
180
|
+
[taskipy](https://github.com/taskipy/taskipy):
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
git clone https://github.com/fabiommendes/seks.git
|
|
184
|
+
cd seks
|
|
185
|
+
uv sync
|
|
186
|
+
uv run task --list
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
The main tasks are `task test`, `task lint`, `task docs`, `task ci` and
|
|
190
|
+
`task release`. `task screenshots` plays a scripted game and regenerates the
|
|
191
|
+
images in this README. See [CONTRIBUTING.md](https://github.com/fabiommendes/seks/blob/main/CONTRIBUTING.md)
|
|
192
|
+
for details.
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
## About the name
|
|
196
|
+
|
|
197
|
+
*Seks* means "six" in Danish, Norwegian and Faroese, after the highest face of
|
|
198
|
+
a die.
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
Seks is released under the [MIT License](https://github.com/fabiommendes/seks/blob/main/LICENSE).
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "seks"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Seks: an abstract strategy game played with dice on an 11x11 board."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
requires-python = ">=3.12"
|
|
9
|
+
dependencies = ["pyxel>=2.3"]
|
|
10
|
+
keywords = [
|
|
11
|
+
"game",
|
|
12
|
+
"board-game",
|
|
13
|
+
"abstract-strategy",
|
|
14
|
+
"dice",
|
|
15
|
+
"pyxel",
|
|
16
|
+
]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Environment :: X11 Applications",
|
|
20
|
+
"Intended Audience :: End Users/Desktop",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Programming Language :: Python :: 3.14",
|
|
27
|
+
"Topic :: Games/Entertainment :: Board Games",
|
|
28
|
+
"Typing :: Typed",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[[project.authors]]
|
|
32
|
+
name = "Fábio Macêdo Mendes"
|
|
33
|
+
email = "fabiomacedomendes@gmail.com"
|
|
34
|
+
|
|
35
|
+
[project.urls]
|
|
36
|
+
Homepage = "https://github.com/fabiommendes/seks"
|
|
37
|
+
Repository = "https://github.com/fabiommendes/seks"
|
|
38
|
+
Issues = "https://github.com/fabiommendes/seks/issues"
|
|
39
|
+
Changelog = "https://github.com/fabiommendes/seks/blob/main/CHANGELOG.md"
|
|
40
|
+
|
|
41
|
+
[project.scripts]
|
|
42
|
+
seks = "seks.main:main"
|
|
43
|
+
|
|
44
|
+
[dependency-groups]
|
|
45
|
+
dev = [
|
|
46
|
+
"doc-zero>=0.2; python_version >= '3.13'",
|
|
47
|
+
"mypy>=1.15",
|
|
48
|
+
"pytest>=8.3",
|
|
49
|
+
"pytest-cov>=6.0",
|
|
50
|
+
"ruff>=0.11",
|
|
51
|
+
"taskipy>=1.14",
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
[build-system]
|
|
55
|
+
requires = ["uv_build>=0.8,<0.12"]
|
|
56
|
+
build-backend = "uv_build"
|
|
57
|
+
|
|
58
|
+
[tool.uv.build-backend]
|
|
59
|
+
module-name = "seks"
|
|
60
|
+
module-root = "."
|
|
61
|
+
source-include = [
|
|
62
|
+
"tests/**",
|
|
63
|
+
"CHANGELOG.md",
|
|
64
|
+
]
|
|
65
|
+
source-exclude = ["*.save"]
|
|
66
|
+
wheel-exclude = ["*.save"]
|
|
67
|
+
|
|
68
|
+
[tool.taskipy.tasks.run]
|
|
69
|
+
cmd = "python -m seks"
|
|
70
|
+
help = "run the game"
|
|
71
|
+
|
|
72
|
+
[tool.taskipy.tasks.test]
|
|
73
|
+
cmd = "pytest"
|
|
74
|
+
help = "run all tests"
|
|
75
|
+
|
|
76
|
+
[tool.taskipy.tasks.format]
|
|
77
|
+
cmd = "ruff format . && ruff check . --fix"
|
|
78
|
+
help = "format code and apply safe lint fixes"
|
|
79
|
+
|
|
80
|
+
[tool.taskipy.tasks.lint]
|
|
81
|
+
cmd = "ruff format --check . && ruff check . && mypy"
|
|
82
|
+
help = "run all linters and type checkers"
|
|
83
|
+
|
|
84
|
+
[tool.taskipy.tasks.docs]
|
|
85
|
+
cmd = "doc-zero build"
|
|
86
|
+
help = "build the documentation"
|
|
87
|
+
|
|
88
|
+
[tool.taskipy.tasks.screenshots]
|
|
89
|
+
cmd = "python scripts/screenshots.py"
|
|
90
|
+
help = "play a scripted game and regenerate the README screenshots"
|
|
91
|
+
|
|
92
|
+
[tool.taskipy.tasks.ci]
|
|
93
|
+
cmd = "task lint && task test && task docs"
|
|
94
|
+
help = "run all CI checks"
|
|
95
|
+
|
|
96
|
+
[tool.taskipy.tasks.release]
|
|
97
|
+
cmd = "task ci && rm -rf dist && uv build && uvx twine check --strict dist/*"
|
|
98
|
+
help = "check that the project is ready to be published to PyPI"
|
|
99
|
+
|
|
100
|
+
[tool.pytest.ini_options]
|
|
101
|
+
testpaths = ["tests"]
|
|
102
|
+
addopts = [
|
|
103
|
+
"--import-mode=importlib",
|
|
104
|
+
"--cov=seks",
|
|
105
|
+
"--cov-report=term-missing",
|
|
106
|
+
]
|
|
107
|
+
|
|
108
|
+
[tool.coverage.run]
|
|
109
|
+
omit = ["seks/__main__.py"]
|
|
110
|
+
|
|
111
|
+
[tool.ruff]
|
|
112
|
+
line-length = 88
|
|
113
|
+
target-version = "py312"
|
|
114
|
+
extend-exclude = [
|
|
115
|
+
".base-ast",
|
|
116
|
+
".base-ast-cache",
|
|
117
|
+
"docs",
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
[tool.ruff.lint]
|
|
121
|
+
select = [
|
|
122
|
+
"E",
|
|
123
|
+
"F",
|
|
124
|
+
"W",
|
|
125
|
+
"I",
|
|
126
|
+
"B",
|
|
127
|
+
"UP",
|
|
128
|
+
"SIM",
|
|
129
|
+
"RUF",
|
|
130
|
+
]
|
|
131
|
+
|
|
132
|
+
[tool.ruff.lint.flake8-bugbear]
|
|
133
|
+
extend-immutable-calls = ["seks.types.Pos"]
|
|
134
|
+
|
|
135
|
+
[tool.mypy]
|
|
136
|
+
python_version = "3.12"
|
|
137
|
+
files = [
|
|
138
|
+
"seks",
|
|
139
|
+
"tests",
|
|
140
|
+
"scripts",
|
|
141
|
+
]
|
|
142
|
+
warn_unused_ignores = true
|
|
143
|
+
warn_redundant_casts = true
|
|
144
|
+
check_untyped_defs = true
|
|
145
|
+
|
|
146
|
+
[[tool.mypy.overrides]]
|
|
147
|
+
module = ["pyxel.*"]
|
|
148
|
+
ignore_missing_imports = true
|