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.
@@ -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
+ [![CI](https://github.com/fabiommendes/seks/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/fabiommendes/seks/actions/workflows/ci.yml)
32
+ [![PyPI](https://img.shields.io/pypi/v/seks.svg)](https://pypi.org/project/seks/)
33
+ [![Python versions](https://img.shields.io/pypi/pyversions/seks.svg)](https://pypi.org/project/seks/)
34
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](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
+ [![CI](https://github.com/fabiommendes/seks/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/fabiommendes/seks/actions/workflows/ci.yml)
4
+ [![PyPI](https://img.shields.io/pypi/v/seks.svg)](https://pypi.org/project/seks/)
5
+ [![Python versions](https://img.shields.io/pypi/pyversions/seks.svg)](https://pypi.org/project/seks/)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](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