par-infini-sweeper 0.2.9__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.
Files changed (26) hide show
  1. par_infini_sweeper-0.2.9/.gitignore +81 -0
  2. par_infini_sweeper-0.2.9/LICENSE +21 -0
  3. par_infini_sweeper-0.2.9/PKG-INFO +214 -0
  4. par_infini_sweeper-0.2.9/README.md +149 -0
  5. par_infini_sweeper-0.2.9/pyproject.toml +119 -0
  6. par_infini_sweeper-0.2.9/src/par_infini_sweeper/__init__.py +31 -0
  7. par_infini_sweeper-0.2.9/src/par_infini_sweeper/__main__.py +52 -0
  8. par_infini_sweeper-0.2.9/src/par_infini_sweeper/data_structures.py +690 -0
  9. par_infini_sweeper-0.2.9/src/par_infini_sweeper/db.py +232 -0
  10. par_infini_sweeper-0.2.9/src/par_infini_sweeper/db_migrations.py +98 -0
  11. par_infini_sweeper-0.2.9/src/par_infini_sweeper/dialogs/__init__.py +5 -0
  12. par_infini_sweeper-0.2.9/src/par_infini_sweeper/dialogs/difficulty_dialog.py +86 -0
  13. par_infini_sweeper-0.2.9/src/par_infini_sweeper/dialogs/error_dialog.py +28 -0
  14. par_infini_sweeper-0.2.9/src/par_infini_sweeper/dialogs/help_dialog.py +75 -0
  15. par_infini_sweeper-0.2.9/src/par_infini_sweeper/dialogs/information.py +15 -0
  16. par_infini_sweeper-0.2.9/src/par_infini_sweeper/dialogs/input_dialog.py +106 -0
  17. par_infini_sweeper-0.2.9/src/par_infini_sweeper/dialogs/password_dialog.py +88 -0
  18. par_infini_sweeper-0.2.9/src/par_infini_sweeper/dialogs/text_dialog.py +79 -0
  19. par_infini_sweeper-0.2.9/src/par_infini_sweeper/dialogs/theme_dialog.py +107 -0
  20. par_infini_sweeper-0.2.9/src/par_infini_sweeper/dialogs/yes_no_dialog.py +112 -0
  21. par_infini_sweeper-0.2.9/src/par_infini_sweeper/enums.py +13 -0
  22. par_infini_sweeper-0.2.9/src/par_infini_sweeper/help.md +35 -0
  23. par_infini_sweeper-0.2.9/src/par_infini_sweeper/main_grid.py +215 -0
  24. par_infini_sweeper-0.2.9/src/par_infini_sweeper/minesweeper_app.py +111 -0
  25. par_infini_sweeper-0.2.9/src/par_infini_sweeper/pim.tcss +29 -0
  26. par_infini_sweeper-0.2.9/src/par_infini_sweeper/py.typed +0 -0
@@ -0,0 +1,81 @@
1
+ ### PythonVanilla template
2
+ # Byte-compiled / optimized / DLL files
3
+ __pycache__/
4
+ *.py[cod]
5
+ *$py.class
6
+
7
+ # C extensions
8
+ *.so
9
+
10
+ # Distribution / packaging
11
+ .Python
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # Installer logs
30
+ pip-log.txt
31
+ pip-delete-this-directory.txt
32
+
33
+ # Unit test / coverage reports
34
+ htmlcov/
35
+ .tox/
36
+ .nox/
37
+ .coverage
38
+ .coverage.*
39
+ .cache
40
+ nosetests.xml
41
+ coverage.xml
42
+ *.cover
43
+ *.py,cover
44
+ .hypothesis/
45
+ .pytest_cache/
46
+ cover/
47
+
48
+ # Translations
49
+ *.mo
50
+ *.pot
51
+
52
+ # pyenv
53
+ # For a library or package, you might want to ignore these files since the code is
54
+ # intended to run in multiple environments; otherwise, check them in:
55
+ # .python-version
56
+
57
+ # pipenv
58
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
59
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
60
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
61
+ # install all needed dependencies.
62
+ #Pipfile.lock
63
+
64
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
65
+ __pypackages__/
66
+ .ruff_Cache
67
+
68
+ .aider*
69
+ **/venv
70
+ **/.venv
71
+ **/.env
72
+ **/.idea
73
+ /config.json
74
+ /output/
75
+ /history.json
76
+ **/.ruff_cache/
77
+ **/*~
78
+ **/.DS_Store
79
+ **/ls_volume
80
+ **/.terraform
81
+ /game_state.json
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Paul Robello
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.
@@ -0,0 +1,214 @@
1
+ Metadata-Version: 2.4
2
+ Name: par_infini_sweeper
3
+ Version: 0.2.9
4
+ Summary: Par Infinite Minesweeper
5
+ Project-URL: Homepage, https://github.com/paulrobello/par_infini_sweeper
6
+ Project-URL: Documentation, https://github.com/paulrobello/par_infini_sweeper/blob/main/README.md
7
+ Project-URL: Repository, https://github.com/paulrobello/par_infini_sweeper
8
+ Project-URL: Issues, https://github.com/paulrobello/par_infini_sweeper/issues
9
+ Project-URL: Discussions, https://github.com/paulrobello/par_infini_sweeper/discussions
10
+ Project-URL: Wiki, https://github.com/paulrobello/par_infini_sweeper/wiki
11
+ Author-email: Paul Robello <probello@gmail.com>
12
+ Maintainer-email: Paul Robello <probello@gmail.com>
13
+ License: MIT License
14
+
15
+ Copyright (c) 2024 Paul Robello
16
+
17
+ Permission is hereby granted, free of charge, to any person obtaining a copy
18
+ of this software and associated documentation files (the "Software"), to deal
19
+ in the Software without restriction, including without limitation the rights
20
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21
+ copies of the Software, and to permit persons to whom the Software is
22
+ furnished to do so, subject to the following conditions:
23
+
24
+ The above copyright notice and this permission notice shall be included in all
25
+ copies or substantial portions of the Software.
26
+
27
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33
+ SOFTWARE.
34
+ License-File: LICENSE
35
+ Keywords: minesweeper,tui
36
+ Classifier: Development Status :: 4 - Beta
37
+ Classifier: Environment :: Console
38
+ Classifier: Intended Audience :: Developers
39
+ Classifier: Intended Audience :: End Users/Desktop
40
+ Classifier: Intended Audience :: Other Audience
41
+ Classifier: License :: OSI Approved :: MIT License
42
+ Classifier: Operating System :: MacOS
43
+ Classifier: Operating System :: Microsoft :: Windows :: Windows 10
44
+ Classifier: Operating System :: Microsoft :: Windows :: Windows 11
45
+ Classifier: Operating System :: POSIX :: Linux
46
+ Classifier: Programming Language :: Python :: 3
47
+ Classifier: Programming Language :: Python :: 3.10
48
+ Classifier: Programming Language :: Python :: 3.11
49
+ Classifier: Programming Language :: Python :: 3.12
50
+ Classifier: Programming Language :: Python :: 3.13
51
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
52
+ Classifier: Typing :: Typed
53
+ Requires-Python: >=3.11
54
+ Requires-Dist: asyncio>=3.4.3
55
+ Requires-Dist: orjson>=3.10.15
56
+ Requires-Dist: pydantic-core>=2.27.2
57
+ Requires-Dist: pydantic>=2.10.6
58
+ Requires-Dist: python-dotenv>=1.0.1
59
+ Requires-Dist: requests>=2.32.3
60
+ Requires-Dist: rich>=13.9.4
61
+ Requires-Dist: textual-serve>=1.1.1
62
+ Requires-Dist: textual>=2.1.0
63
+ Requires-Dist: typer>=0.15.1
64
+ Description-Content-Type: text/markdown
65
+
66
+ # Par Infinite Minesweeper
67
+
68
+ ## Description
69
+
70
+ Infinite Minesweeper TUI. Play a game of minesweeper with infinite board size!
71
+
72
+ ![Par Infinite Minesweeper](https://raw.githubusercontent.com/paulrobello/par_infini_sweeper/main/Screenshot.png)
73
+
74
+ ## Technology
75
+ - Python
76
+ - Textual
77
+ - Sqlite3
78
+
79
+ ## Objective
80
+ The goal of the game is to uncover all the cells that do not contain mines.
81
+ If you uncover a mine, you lose the game.
82
+ If you uncover a cell that is not a mine, it will show a number indicating how many mines are in the neighboring cells.
83
+ Use this information to determine which cells are safe to uncover.
84
+
85
+ ## Controls
86
+
87
+ * Left click to uncover a cell. If a cell is flagged as a mine, it will not be uncovered.
88
+ * Sub grids can only be unlocked when cells neighboring the sub grid are uncovered.
89
+ * Shift or Ctrl + Left-click to toggle flagging a covered cell as a mine.
90
+ * Shift or Ctrl + Left-click on an uncovered cell it will uncover all neighboring cells.
91
+ * As a safety you must have same number of flags as mines in the neighboring cells.
92
+ * Drag to pan the board.
93
+ * Keys:
94
+ * `F1` Help.
95
+ * `N` New game.
96
+ * `O` Move view to origin.
97
+ * `C` Move view to board center (computed as center of exposed sub grids).
98
+ * `P` Pause.
99
+ * `H` Highscores.
100
+ * `T` Change theme.
101
+ * `Q` Quit.
102
+
103
+ ## Scoring
104
+
105
+ The main grid consists of 8x8 sub grids.
106
+ Depending the difficulty level, the number of mines in each sub grid will vary.
107
+ * Easy: 8 mines
108
+ * Medium: 12 mines
109
+ * Hard: 16 mines
110
+
111
+ When all cells that are not mines in a sub grid are uncovered the sub grid is marked solved and flags are placed on any mines that are not already flagged.
112
+ Your score is the sum of all mines in the solved sub grids.
113
+
114
+ ## Storage
115
+
116
+ All data for the application is stored in a sqlite3 database located in `~/.pim/game_data.sqlite`
117
+ The database is backed up daily to `~/.pim/game_data.sqlite.bak`
118
+
119
+ ## Prerequisites
120
+
121
+ The instructions assume you have `uv` installed.
122
+
123
+ ## Installation
124
+
125
+ ### PyPi
126
+ ```shell
127
+ uv tool install par_infini_sweeper
128
+ ```
129
+
130
+ ### GitHub
131
+ ```shell
132
+ uv tool install git+https://github.com/paulrobello/par_infini_sweeper
133
+ ```
134
+
135
+ ## Update
136
+
137
+ ### PyPi
138
+ ```shell
139
+ uv tool install par_infini_sweeper -U --force
140
+ ```
141
+
142
+ ### GitHub
143
+ ```shell
144
+ uv tool install git+https://github.com/paulrobello/par_infini_sweeper -U --force
145
+ ```
146
+
147
+
148
+ ## Installed Usage
149
+ ```shell
150
+ pim [OPTIONS]
151
+ ```
152
+
153
+ ## From source Usage
154
+ ```shell
155
+ uv run pim [OPTIONS]
156
+ ```
157
+
158
+
159
+ ### CLI Options
160
+ ```
161
+ --server -s Start webserver that allows app to be played in a browser
162
+ --user -u TEXT User name to use [default: logged in username]
163
+ --nick -n TEXT Set user nickname [default: None]
164
+ --version -v Show version and exit.
165
+ --help Show this message and exit.
166
+ ```
167
+
168
+ ## Roadmap
169
+
170
+ - Global Leaderboard
171
+ - More game modes
172
+ - Optimize for more performance
173
+
174
+ ## Whats New
175
+ - Version 0.2.9:
176
+ - Fixed some first run db issues
177
+ - Version 0.2.8:
178
+ - Addata game data backup
179
+ - Updated readme and help
180
+ - Version 0.2.7:
181
+ - Added pause key `p`
182
+ - Fixed bug where sometimes newly generated sub grids would not get saved if no cells were uncovered
183
+ - More optimizations
184
+ - Support for future game modes
185
+ - Version 0.2.6:
186
+ - Now only highlights unrevealed surrounding cells when shift/ctrl + left-click on uncovered cells
187
+ - Version 0.2.6:
188
+ - Now stops timer on game over
189
+ - Now highlights surrounding cells when shift/ctrl + left-click on uncovered cells
190
+ - Version 0.2.5:
191
+ - Disabled some toasts to reduce clutter
192
+ - Moved middle click function to shift/ctrl + left-click on uncovered cells
193
+ - Version 0.2.3:
194
+ - Enabled multi user support
195
+ - Version 0.2.0:
196
+ - Added webserver to play in a browser
197
+ - Version 0.1.0:
198
+ - Initial release
199
+
200
+ ## Contributing
201
+
202
+ Contributions are welcome! Please feel free to submit a Pull Request.
203
+
204
+ ## Shoutout
205
+
206
+ I would like to thank [Edward Jazzhands](http://edward-jazzhands.github.io/) for all his help testing and feedback / feature requests!
207
+
208
+ ## License
209
+
210
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
211
+
212
+ ## Author
213
+
214
+ Paul Robello - probello@gmail.com
@@ -0,0 +1,149 @@
1
+ # Par Infinite Minesweeper
2
+
3
+ ## Description
4
+
5
+ Infinite Minesweeper TUI. Play a game of minesweeper with infinite board size!
6
+
7
+ ![Par Infinite Minesweeper](https://raw.githubusercontent.com/paulrobello/par_infini_sweeper/main/Screenshot.png)
8
+
9
+ ## Technology
10
+ - Python
11
+ - Textual
12
+ - Sqlite3
13
+
14
+ ## Objective
15
+ The goal of the game is to uncover all the cells that do not contain mines.
16
+ If you uncover a mine, you lose the game.
17
+ If you uncover a cell that is not a mine, it will show a number indicating how many mines are in the neighboring cells.
18
+ Use this information to determine which cells are safe to uncover.
19
+
20
+ ## Controls
21
+
22
+ * Left click to uncover a cell. If a cell is flagged as a mine, it will not be uncovered.
23
+ * Sub grids can only be unlocked when cells neighboring the sub grid are uncovered.
24
+ * Shift or Ctrl + Left-click to toggle flagging a covered cell as a mine.
25
+ * Shift or Ctrl + Left-click on an uncovered cell it will uncover all neighboring cells.
26
+ * As a safety you must have same number of flags as mines in the neighboring cells.
27
+ * Drag to pan the board.
28
+ * Keys:
29
+ * `F1` Help.
30
+ * `N` New game.
31
+ * `O` Move view to origin.
32
+ * `C` Move view to board center (computed as center of exposed sub grids).
33
+ * `P` Pause.
34
+ * `H` Highscores.
35
+ * `T` Change theme.
36
+ * `Q` Quit.
37
+
38
+ ## Scoring
39
+
40
+ The main grid consists of 8x8 sub grids.
41
+ Depending the difficulty level, the number of mines in each sub grid will vary.
42
+ * Easy: 8 mines
43
+ * Medium: 12 mines
44
+ * Hard: 16 mines
45
+
46
+ When all cells that are not mines in a sub grid are uncovered the sub grid is marked solved and flags are placed on any mines that are not already flagged.
47
+ Your score is the sum of all mines in the solved sub grids.
48
+
49
+ ## Storage
50
+
51
+ All data for the application is stored in a sqlite3 database located in `~/.pim/game_data.sqlite`
52
+ The database is backed up daily to `~/.pim/game_data.sqlite.bak`
53
+
54
+ ## Prerequisites
55
+
56
+ The instructions assume you have `uv` installed.
57
+
58
+ ## Installation
59
+
60
+ ### PyPi
61
+ ```shell
62
+ uv tool install par_infini_sweeper
63
+ ```
64
+
65
+ ### GitHub
66
+ ```shell
67
+ uv tool install git+https://github.com/paulrobello/par_infini_sweeper
68
+ ```
69
+
70
+ ## Update
71
+
72
+ ### PyPi
73
+ ```shell
74
+ uv tool install par_infini_sweeper -U --force
75
+ ```
76
+
77
+ ### GitHub
78
+ ```shell
79
+ uv tool install git+https://github.com/paulrobello/par_infini_sweeper -U --force
80
+ ```
81
+
82
+
83
+ ## Installed Usage
84
+ ```shell
85
+ pim [OPTIONS]
86
+ ```
87
+
88
+ ## From source Usage
89
+ ```shell
90
+ uv run pim [OPTIONS]
91
+ ```
92
+
93
+
94
+ ### CLI Options
95
+ ```
96
+ --server -s Start webserver that allows app to be played in a browser
97
+ --user -u TEXT User name to use [default: logged in username]
98
+ --nick -n TEXT Set user nickname [default: None]
99
+ --version -v Show version and exit.
100
+ --help Show this message and exit.
101
+ ```
102
+
103
+ ## Roadmap
104
+
105
+ - Global Leaderboard
106
+ - More game modes
107
+ - Optimize for more performance
108
+
109
+ ## Whats New
110
+ - Version 0.2.9:
111
+ - Fixed some first run db issues
112
+ - Version 0.2.8:
113
+ - Addata game data backup
114
+ - Updated readme and help
115
+ - Version 0.2.7:
116
+ - Added pause key `p`
117
+ - Fixed bug where sometimes newly generated sub grids would not get saved if no cells were uncovered
118
+ - More optimizations
119
+ - Support for future game modes
120
+ - Version 0.2.6:
121
+ - Now only highlights unrevealed surrounding cells when shift/ctrl + left-click on uncovered cells
122
+ - Version 0.2.6:
123
+ - Now stops timer on game over
124
+ - Now highlights surrounding cells when shift/ctrl + left-click on uncovered cells
125
+ - Version 0.2.5:
126
+ - Disabled some toasts to reduce clutter
127
+ - Moved middle click function to shift/ctrl + left-click on uncovered cells
128
+ - Version 0.2.3:
129
+ - Enabled multi user support
130
+ - Version 0.2.0:
131
+ - Added webserver to play in a browser
132
+ - Version 0.1.0:
133
+ - Initial release
134
+
135
+ ## Contributing
136
+
137
+ Contributions are welcome! Please feel free to submit a Pull Request.
138
+
139
+ ## Shoutout
140
+
141
+ I would like to thank [Edward Jazzhands](http://edward-jazzhands.github.io/) for all his help testing and feedback / feature requests!
142
+
143
+ ## License
144
+
145
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
146
+
147
+ ## Author
148
+
149
+ Paul Robello - probello@gmail.com
@@ -0,0 +1,119 @@
1
+ [project]
2
+ name = "par_infini_sweeper"
3
+ dynamic = [
4
+ "version",
5
+ ]
6
+ description = "Par Infinite Minesweeper"
7
+ readme = "README.md"
8
+ requires-python = ">=3.11"
9
+ authors = [
10
+ { name = "Paul Robello", email = "probello@gmail.com" },
11
+ ]
12
+ maintainers = [
13
+ { name = "Paul Robello", email = "probello@gmail.com" },
14
+ ]
15
+ classifiers = [
16
+ "License :: OSI Approved :: MIT License",
17
+ "Environment :: Console",
18
+ "Development Status :: 4 - Beta",
19
+ "Intended Audience :: Developers",
20
+ "Intended Audience :: End Users/Desktop",
21
+ "Intended Audience :: Other Audience",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Operating System :: MacOS",
28
+ "Operating System :: Microsoft :: Windows :: Windows 10",
29
+ "Operating System :: Microsoft :: Windows :: Windows 11",
30
+ "Operating System :: POSIX :: Linux",
31
+ "Topic :: Software Development :: Libraries :: Python Modules",
32
+ "Typing :: Typed",
33
+ ]
34
+ keywords = [
35
+ "tui",
36
+ "minesweeper",
37
+ ]
38
+ dependencies = [
39
+ "asyncio>=3.4.3",
40
+ "pydantic-core>=2.27.2",
41
+ "pydantic>=2.10.6",
42
+ "python-dotenv>=1.0.1",
43
+ "requests>=2.32.3",
44
+ "rich>=13.9.4",
45
+ "orjson>=3.10.15",
46
+ "typer>=0.15.1",
47
+ "textual>=2.1.0",
48
+ "textual-serve>=1.1.1",
49
+
50
+ ]
51
+ packages = [
52
+ "src/par_infini_sweeper",
53
+ ]
54
+
55
+ [project.license]
56
+ file = "LICENSE"
57
+
58
+ [project.urls]
59
+ Homepage = "https://github.com/paulrobello/par_infini_sweeper"
60
+ Documentation = "https://github.com/paulrobello/par_infini_sweeper/blob/main/README.md"
61
+ Repository = "https://github.com/paulrobello/par_infini_sweeper"
62
+ Issues = "https://github.com/paulrobello/par_infini_sweeper/issues"
63
+ Discussions = "https://github.com/paulrobello/par_infini_sweeper/discussions"
64
+ Wiki = "https://github.com/paulrobello/par_infini_sweeper/wiki"
65
+
66
+ [project.scripts]
67
+ pim = "par_infini_sweeper.__main__:app"
68
+
69
+ [build-system]
70
+ requires = [
71
+ "hatchling",
72
+ "wheel",
73
+ ]
74
+ build-backend = "hatchling.build"
75
+
76
+ [dependency-groups]
77
+ dev = [
78
+ "build>=1.2.1",
79
+ "twine>=6.1.0",
80
+ "pyright>=1.1.379",
81
+ "pre-commit>=4.1.0",
82
+ "ruff>=0.9.3",
83
+ "pyinstrument>=5.0.1",
84
+ "ruff>=0.7.0",
85
+ "types-orjson>=3.6.2",
86
+ ]
87
+
88
+ [tool.hatch.version]
89
+ path = "src/par_infini_sweeper/__init__.py"
90
+
91
+ [tool.hatch.build.targets.wheel]
92
+ packages = [
93
+ "src/par_infini_sweeper",
94
+ ]
95
+ include = [
96
+ "py.typed",
97
+ "**/*.py",
98
+ "**/*.html",
99
+ "**/*.gif",
100
+ "**/*.jpg",
101
+ "**/*.png",
102
+ "**/*.md",
103
+ "**/*.tcss",
104
+ ]
105
+
106
+ [tool.hatch.build.targets.sdist]
107
+ include = [
108
+ "src/par_infini_sweeper",
109
+ "LICENSE",
110
+ "README.md",
111
+ "extraction_prompt.md",
112
+ "pyproject.toml",
113
+ ]
114
+ exclude = [
115
+ "*.pyc",
116
+ "__pycache__",
117
+ "*.so",
118
+ "*.dylib",
119
+ ]
@@ -0,0 +1,31 @@
1
+ """Par Infinite Minesweeper."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+
7
+ __author__ = "Paul Robello"
8
+ __credits__ = ["Paul Robello"]
9
+ __maintainer__ = "Paul Robello"
10
+ __email__ = "probello@gmail.com"
11
+ __version__ = "0.2.9"
12
+ __application_title__ = "Par Infinite Minesweeper"
13
+ __application_binary__ = "pim"
14
+ __licence__ = "MIT"
15
+
16
+ from par_infini_sweeper.minesweeper_app import MinesweeperApp
17
+
18
+ os.environ["USER_AGENT"] = f"{__application_title__} {__version__}"
19
+
20
+
21
+ __all__: list[str] = [
22
+ "__author__",
23
+ "__credits__",
24
+ "__maintainer__",
25
+ "__email__",
26
+ "__version__",
27
+ "__application_binary__",
28
+ "__licence__",
29
+ "__application_title__",
30
+ "MinesweeperApp",
31
+ ]
@@ -0,0 +1,52 @@
1
+ """Main application"""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import Annotated
7
+
8
+ import typer
9
+ from dotenv import load_dotenv
10
+ from rich.console import Console
11
+ from textual_serve.server import Server
12
+
13
+ from par_infini_sweeper import __application_title__, __version__
14
+ from par_infini_sweeper.minesweeper_app import MinesweeperApp
15
+
16
+ app = typer.Typer()
17
+ console = Console(stderr=True)
18
+
19
+ load_dotenv()
20
+
21
+
22
+ def version_callback(value: bool) -> None:
23
+ """Print version and exit."""
24
+ if value:
25
+ print(f"{__application_title__}: {__version__}")
26
+ raise typer.Exit()
27
+
28
+
29
+ @app.command()
30
+ def main(
31
+ start_server: Annotated[
32
+ bool, typer.Option("--server", "-s", help="Start webserver that allows app to be played in a browser")
33
+ ] = False,
34
+ user_name: Annotated[str, typer.Option("--user", "-u", help="User name to use")] = os.environ.get("USER", "user"),
35
+ nickname: Annotated[str | None, typer.Option("--nick", "-n", help="Set user nickname")] = None,
36
+ version: Annotated[ # pylint: disable=unused-argument
37
+ bool | None,
38
+ typer.Option("--version", "-v", callback=version_callback, is_eager=True),
39
+ ] = None,
40
+ ) -> None:
41
+ """Main function."""
42
+ if start_server:
43
+ server = Server("pim")
44
+ server.serve()
45
+ return
46
+
47
+ sweeper_app: MinesweeperApp = MinesweeperApp(user_name, nickname)
48
+ sweeper_app.run()
49
+
50
+
51
+ if __name__ == "__main__":
52
+ app()