tmscli 0.3.8__tar.gz → 0.4.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.
- tmscli-0.4.0/PKG-INFO +40 -0
- tmscli-0.4.0/README.md +34 -0
- tmscli-0.4.0/initialise.sh +4 -0
- {tmscli-0.3.8 → tmscli-0.4.0}/pyproject.toml +1 -1
- {tmscli-0.3.8 → tmscli-0.4.0}/src/tmscli/about.html +1 -0
- {tmscli-0.3.8 → tmscli-0.4.0}/src/tmscli/changelog.html +4 -5
- {tmscli-0.3.8 → tmscli-0.4.0}/src/tmscli/index.html +1 -0
- tmscli-0.4.0/src/tmscli/install.html +136 -0
- tmscli-0.4.0/src/tmscli/main.py +229 -0
- tmscli-0.4.0/src/tmscli/play.html +52 -0
- {tmscli-0.3.8 → tmscli-0.4.0}/src/tmscli/screenshots.html +2 -1
- {tmscli-0.3.8 → tmscli-0.4.0}/src/tmscli/style.css +101 -0
- {tmscli-0.3.8 → tmscli-0.4.0}/update.sh +2 -2
- tmscli-0.4.0/video and storyboard/pyauto.py +19 -0
- tmscli-0.4.0/video and storyboard/vid.py +0 -0
- tmscli-0.3.8/PKG-INFO +0 -17
- tmscli-0.3.8/README.md +0 -11
- tmscli-0.3.8/initialise.sh +0 -3
- tmscli-0.3.8/src/tmscli/install.html +0 -62
- {tmscli-0.3.8 → tmscli-0.4.0}/src/tmscli/.gitkeep +0 -0
- {tmscli-0.3.8 → tmscli-0.4.0}/src/tmscli/__init__.py +0 -0
- {tmscli-0.3.8 → tmscli-0.4.0}/src/tmscli/img/big.jpg +0 -0
- {tmscli-0.3.8 → tmscli-0.4.0}/src/tmscli/img/midgame.jpg +0 -0
- {tmscli-0.3.8 → tmscli-0.4.0}/src/tmscli/img/new_board.jpg +0 -0
- {tmscli-0.3.8 → tmscli-0.4.0}/src/tmscli/img/win.jpg +0 -0
- /tmscli-0.3.8/src/tmscli/main.py → /tmscli-0.4.0/video and storyboard/script.txt +0 -0
tmscli-0.4.0/PKG-INFO
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: tmscli
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: runs minesweeper in your terminal, type rules for how to play
|
|
5
|
+
Description-Content-Type: text/markdown
|
|
6
|
+
|
|
7
|
+
# tmscli
|
|
8
|
+
|
|
9
|
+
**Minesweeper, in your terminal, all at once.**
|
|
10
|
+
|
|
11
|
+
`tmscli` is a lightweight Python module that brings classic Minesweeper into your terminal. No GUI, no dependencies beyond the standard library — just you, a grid, and a few mines.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Why tmscli?
|
|
16
|
+
|
|
17
|
+
Bored of sitting there, with all your work done, but unable to do anything?
|
|
18
|
+
|
|
19
|
+
`tmscli` brings Minesweeper to the terminal and is customisable, so you can shape the board to suit your mood — from a quick 9×9 coffee break to a punishing 16×16 minefield.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
Install from PyPI:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install tmscli
|
|
29
|
+
|
|
30
|
+
# Default game
|
|
31
|
+
tmscli
|
|
32
|
+
|
|
33
|
+
# Bigger board, more mines
|
|
34
|
+
tmscli -s 16 -m 40
|
|
35
|
+
|
|
36
|
+
# Read the rules first
|
|
37
|
+
tmscli --rules
|
|
38
|
+
|
|
39
|
+
# Combine flags
|
|
40
|
+
tmscli -s 12 -m 20
|
tmscli-0.4.0/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# tmscli
|
|
2
|
+
|
|
3
|
+
**Minesweeper, in your terminal, all at once.**
|
|
4
|
+
|
|
5
|
+
`tmscli` is a lightweight Python module that brings classic Minesweeper into your terminal. No GUI, no dependencies beyond the standard library — just you, a grid, and a few mines.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Why tmscli?
|
|
10
|
+
|
|
11
|
+
Bored of sitting there, with all your work done, but unable to do anything?
|
|
12
|
+
|
|
13
|
+
`tmscli` brings Minesweeper to the terminal and is customisable, so you can shape the board to suit your mood — from a quick 9×9 coffee break to a punishing 16×16 minefield.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
Install from PyPI:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install tmscli
|
|
23
|
+
|
|
24
|
+
# Default game
|
|
25
|
+
tmscli
|
|
26
|
+
|
|
27
|
+
# Bigger board, more mines
|
|
28
|
+
tmscli -s 16 -m 40
|
|
29
|
+
|
|
30
|
+
# Read the rules first
|
|
31
|
+
tmscli --rules
|
|
32
|
+
|
|
33
|
+
# Combine flags
|
|
34
|
+
tmscli -s 12 -m 20
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
<a href="install.html">installation + usage</a>
|
|
18
18
|
<a href="screenshots.html">screenshots</a>
|
|
19
19
|
<a href="changelog.html" class="active">changelog</a>
|
|
20
|
+
<a href="play.html">play</a>
|
|
20
21
|
</nav>
|
|
21
22
|
</div>
|
|
22
23
|
</header>
|
|
@@ -55,8 +56,6 @@
|
|
|
55
56
|
<li>Added customisation options for board size and mine count</li>
|
|
56
57
|
<li>Improved rendering speed in the terminal</li>
|
|
57
58
|
</ul>
|
|
58
|
-
<p class="muted">(Placeholder entry — replace with real notes when ready.)</p>
|
|
59
|
-
|
|
60
59
|
<details class="patch-dropdown">
|
|
61
60
|
<summary>Show all minor patches</summary>
|
|
62
61
|
<div class="patch-list">
|
|
@@ -78,9 +77,9 @@
|
|
|
78
77
|
<ul>
|
|
79
78
|
<li>Initial release</li>
|
|
80
79
|
<li>Basic Minesweeper gameplay in the terminal</li>
|
|
81
|
-
<li>
|
|
80
|
+
<li>Basic commands and original 9x9 grid</li>
|
|
82
81
|
</ul>
|
|
83
|
-
|
|
82
|
+
|
|
84
83
|
|
|
85
84
|
<details class="patch-dropdown">
|
|
86
85
|
<summary>Show all minor patches</summary>
|
|
@@ -90,7 +89,7 @@
|
|
|
90
89
|
<ul>
|
|
91
90
|
<li>Initial release</li>
|
|
92
91
|
<li>Basic Minesweeper gameplay in the terminal</li>
|
|
93
|
-
<li>
|
|
92
|
+
<li>Basic commands and original 9x9 grid</li>
|
|
94
93
|
</ul>
|
|
95
94
|
</div>
|
|
96
95
|
<!-- add v0.1.1, v0.1.2 etc. here -->
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
<!-- install.html (installation + usage) -->
|
|
2
|
+
<!DOCTYPE html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>installation + usage · tmscli</title>
|
|
8
|
+
<link rel="stylesheet" href="style.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<header>
|
|
12
|
+
<div class="header-inner">
|
|
13
|
+
<div class="logo">tmscli</div>
|
|
14
|
+
<nav>
|
|
15
|
+
<a href="index.html">main</a>
|
|
16
|
+
<a href="about.html">about</a>
|
|
17
|
+
<a href="install.html" class="active">installation + usage</a>
|
|
18
|
+
<a href="screenshots.html">screenshots</a>
|
|
19
|
+
<a href="changelog.html">changelog</a>
|
|
20
|
+
<a href="play.html">play</a>
|
|
21
|
+
</nav>
|
|
22
|
+
</div>
|
|
23
|
+
</header>
|
|
24
|
+
|
|
25
|
+
<main class="container">
|
|
26
|
+
<h1>installation & usage</h1>
|
|
27
|
+
<p class="subhead">Get tmscli running in your terminal in seconds.</p>
|
|
28
|
+
|
|
29
|
+
<div class="install-card">
|
|
30
|
+
<h2>Install from PyPI</h2>
|
|
31
|
+
<pre><code>pip install tmscli</code></pre>
|
|
32
|
+
<p>Once installed, the <code>tmscli</code> command becomes available in your terminal.</p>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<div class="usage-section">
|
|
36
|
+
<h2>Command-line flags</h2>
|
|
37
|
+
|
|
38
|
+
<table class="flags-table">
|
|
39
|
+
<thead>
|
|
40
|
+
<tr>
|
|
41
|
+
<th>Flag</th>
|
|
42
|
+
<th>Short</th>
|
|
43
|
+
<th>Default</th>
|
|
44
|
+
<th>Description</th>
|
|
45
|
+
</tr>
|
|
46
|
+
</thead>
|
|
47
|
+
<tbody>
|
|
48
|
+
<tr>
|
|
49
|
+
<td><code>--size</code></td>
|
|
50
|
+
<td><code>-s</code></td>
|
|
51
|
+
<td>9</td>
|
|
52
|
+
<td>Set the board size to <em>x</em> (creates an <em>x</em> × <em>x</em> grid).</td>
|
|
53
|
+
</tr>
|
|
54
|
+
<tr>
|
|
55
|
+
<td><code>--mine_num</code></td>
|
|
56
|
+
<td><code>-m</code></td>
|
|
57
|
+
<td>5</td>
|
|
58
|
+
<td>Set the number of mines to <em>x</em>.</td>
|
|
59
|
+
</tr>
|
|
60
|
+
<tr>
|
|
61
|
+
<td><code>--rules</code></td>
|
|
62
|
+
<td><code>-r</code></td>
|
|
63
|
+
<td>off</td>
|
|
64
|
+
<td>Show the rules and controls before starting.</td>
|
|
65
|
+
</tr>
|
|
66
|
+
</tbody>
|
|
67
|
+
</table>
|
|
68
|
+
|
|
69
|
+
<h3>Examples</h3>
|
|
70
|
+
<pre><code>tmscli</code></pre>
|
|
71
|
+
<p>Start with the default 9×9 board and 5 mines.</p>
|
|
72
|
+
|
|
73
|
+
<pre><code>tmscli -s 16 -m 40</code></pre>
|
|
74
|
+
<p>Start with a 16×16 board containing 40 mines.</p>
|
|
75
|
+
|
|
76
|
+
<pre><code>tmscli --rules</code></pre>
|
|
77
|
+
<p>Read the rules first, then start the game.</p>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
<div class="usage-section">
|
|
81
|
+
<h2>In-game commands</h2>
|
|
82
|
+
<p>Once the board is printed, type a command and press enter. Each command takes three parts: an action followed by two coordinates.</p>
|
|
83
|
+
|
|
84
|
+
<table class="flags-table">
|
|
85
|
+
<thead>
|
|
86
|
+
<tr>
|
|
87
|
+
<th>Command</th>
|
|
88
|
+
<th>Description</th>
|
|
89
|
+
</tr>
|
|
90
|
+
</thead>
|
|
91
|
+
<tbody>
|
|
92
|
+
<tr>
|
|
93
|
+
<td><code>uc x y</code></td>
|
|
94
|
+
<td>Uncover the square at (x, y).</td>
|
|
95
|
+
</tr>
|
|
96
|
+
<tr>
|
|
97
|
+
<td><code>fl x y</code></td>
|
|
98
|
+
<td>Flag the square at (x, y).</td>
|
|
99
|
+
</tr>
|
|
100
|
+
<tr>
|
|
101
|
+
<td><code>uf x y</code></td>
|
|
102
|
+
<td>Unflag the square at (x, y).</td>
|
|
103
|
+
</tr>
|
|
104
|
+
</tbody>
|
|
105
|
+
</table>
|
|
106
|
+
|
|
107
|
+
<h3>Board symbols</h3>
|
|
108
|
+
<ul class="symbol-list">
|
|
109
|
+
<li><code>F</code> — flagged</li>
|
|
110
|
+
<li><code> </code> (space) — covered / unknown</li>
|
|
111
|
+
<li><code>1</code>–<code>8</code> — number of mines in the surrounding 3×3 area</li>
|
|
112
|
+
<li><code>M</code> — a mine (game over)</li>
|
|
113
|
+
</ul>
|
|
114
|
+
|
|
115
|
+
<h3>Coordinates</h3>
|
|
116
|
+
<p>Coordinates are 1-indexed and must be within the board. The <code>x</code> axis runs down the board, and the <code>y</code> axis runs across:</p>
|
|
117
|
+
<pre><code> y------>
|
|
118
|
+
x
|
|
119
|
+
|
|
|
120
|
+
|
|
|
121
|
+
|
|
|
122
|
+
V</code></pre>
|
|
123
|
+
</div>
|
|
124
|
+
|
|
125
|
+
<div class="lorem-note">
|
|
126
|
+
<h2>Version note</h2>
|
|
127
|
+
<p>v0.3.0 added a border to the minesweeper format and minor bug fixes. Update with:</p>
|
|
128
|
+
<pre><code>pip install --upgrade tmscli</code></pre>
|
|
129
|
+
</div>
|
|
130
|
+
</main>
|
|
131
|
+
|
|
132
|
+
<footer>
|
|
133
|
+
<p>tmscli · PyPI module · terminal minesweeper</p>
|
|
134
|
+
</footer>
|
|
135
|
+
</body>
|
|
136
|
+
</html>
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import random
|
|
2
|
+
import argparse
|
|
3
|
+
import importlib.metadata
|
|
4
|
+
class minesweeper():
|
|
5
|
+
def __init__(self,size,num):
|
|
6
|
+
self.size=size
|
|
7
|
+
self.num=num
|
|
8
|
+
['uncovered?','flagged?','display']
|
|
9
|
+
def print_board(self,board):
|
|
10
|
+
top=' '+(self.size*2)*'_'
|
|
11
|
+
print(top)
|
|
12
|
+
for i in range(self.size):
|
|
13
|
+
buffer='| '
|
|
14
|
+
for j in board[i]:
|
|
15
|
+
if j[0]==True:
|
|
16
|
+
buffer+=str(j[2])+' '
|
|
17
|
+
elif j[1]==True:
|
|
18
|
+
buffer+='F'+' '
|
|
19
|
+
else:
|
|
20
|
+
buffer+=' '+' '
|
|
21
|
+
print(buffer[:-1]+'|')
|
|
22
|
+
bottom=' '+(len(top)-1)*'-'
|
|
23
|
+
print(bottom)
|
|
24
|
+
def get_mines(self):
|
|
25
|
+
mines=[]
|
|
26
|
+
while len(mines)<self.num:
|
|
27
|
+
temp=(random.randint(1,self.size),random.randint(1,self.size))
|
|
28
|
+
if temp not in mines:
|
|
29
|
+
mines.append(temp)
|
|
30
|
+
return mines
|
|
31
|
+
def sub1(self, coord):
|
|
32
|
+
a,b=coord
|
|
33
|
+
return (a-1,b-1)
|
|
34
|
+
def create_starting_board(self,mines):
|
|
35
|
+
board=[]
|
|
36
|
+
o=[False,False,0,False]
|
|
37
|
+
for i in range(self.size):
|
|
38
|
+
board.append(list([]))
|
|
39
|
+
for j in range(self.size):
|
|
40
|
+
board[i].append(list(o))
|
|
41
|
+
for i in mines:
|
|
42
|
+
mine=self.sub1(i)
|
|
43
|
+
x,y=mine
|
|
44
|
+
board[x][y][2]='M'
|
|
45
|
+
for i in range(self.size):
|
|
46
|
+
for j in range(self.size):
|
|
47
|
+
c=0
|
|
48
|
+
if board[i][j][2]=='M':
|
|
49
|
+
continue
|
|
50
|
+
for k in range(-1,2):
|
|
51
|
+
for l in range(-1,2):
|
|
52
|
+
try:
|
|
53
|
+
if (i+k >=0) and (j+l >=0):
|
|
54
|
+
if board[i+k][j+l][2]=='M':
|
|
55
|
+
c+=1
|
|
56
|
+
except:
|
|
57
|
+
pass
|
|
58
|
+
board[i][j][2]=c
|
|
59
|
+
return board
|
|
60
|
+
def print_ending(self,board):
|
|
61
|
+
for i in board:
|
|
62
|
+
buffer=''
|
|
63
|
+
for j in i:
|
|
64
|
+
buffer+=str(j[2])+' '
|
|
65
|
+
print(buffer)
|
|
66
|
+
exit()
|
|
67
|
+
def check_success(self,board):
|
|
68
|
+
for i in board:
|
|
69
|
+
for j in i:
|
|
70
|
+
if j[2]!='M':
|
|
71
|
+
if not j[0]:
|
|
72
|
+
return False
|
|
73
|
+
return True
|
|
74
|
+
def check_death(self,board):
|
|
75
|
+
for i in board:
|
|
76
|
+
for j in i:
|
|
77
|
+
if j[2]=='M':
|
|
78
|
+
if j[0]:
|
|
79
|
+
return True
|
|
80
|
+
return False
|
|
81
|
+
def check(self,board):
|
|
82
|
+
if self.check_death(board):
|
|
83
|
+
print('GAME OVER')
|
|
84
|
+
return True
|
|
85
|
+
elif self.check_success(board):
|
|
86
|
+
print('YOU WIN')
|
|
87
|
+
return True
|
|
88
|
+
return False
|
|
89
|
+
def richochet(self,board,coord):
|
|
90
|
+
x,y=coord
|
|
91
|
+
board[x][y][3]=True
|
|
92
|
+
for i in range(-1,2):
|
|
93
|
+
for j in range(-1,2):
|
|
94
|
+
if x+i>=0 and y+j>=0:
|
|
95
|
+
try:
|
|
96
|
+
if not board[x+i][y+j][3]:
|
|
97
|
+
board[x+i][y+j][0]=True
|
|
98
|
+
board[x+i][y+j][3]=True
|
|
99
|
+
if board[x+i][y+j][2]==0:
|
|
100
|
+
self.richochet(board,(x+i,y+j))
|
|
101
|
+
except:
|
|
102
|
+
continue
|
|
103
|
+
|
|
104
|
+
return board
|
|
105
|
+
|
|
106
|
+
terminal_minesweeper=minesweeper(9,5)
|
|
107
|
+
# terminal_minesweeper.print_board(board)
|
|
108
|
+
def throw():
|
|
109
|
+
print('unrecognised command, please try again')
|
|
110
|
+
def main_loop(board):
|
|
111
|
+
try:
|
|
112
|
+
while True:
|
|
113
|
+
terminal_minesweeper.print_board(board)
|
|
114
|
+
cmd=input()
|
|
115
|
+
cmds=cmd.split()
|
|
116
|
+
if len(cmds)!=3:
|
|
117
|
+
throw()
|
|
118
|
+
continue
|
|
119
|
+
elif cmds[0] not in ['uc','uf','fl']:
|
|
120
|
+
throw()
|
|
121
|
+
continue
|
|
122
|
+
if int(cmds[1])>terminal_minesweeper.size or int(cmds[1])<=0 or int(cmds[2])>terminal_minesweeper.size or int(cmds[2])<=0:
|
|
123
|
+
print('coordinate out of range, please try again')
|
|
124
|
+
continue
|
|
125
|
+
if cmds[0]=='uc':
|
|
126
|
+
if (not board[int(cmds[1])-1][int(cmds[2])-1][0]) and (not board[int(cmds[1])-1][int(cmds[2])-1][1]):
|
|
127
|
+
board[int(cmds[1])-1][int(cmds[2])-1][0]=True
|
|
128
|
+
if board[int(cmds[1])-1][int(cmds[2])-1][2]==0:
|
|
129
|
+
board=terminal_minesweeper.richochet(board,(int(cmds[1])-1,int(cmds[2])-1))
|
|
130
|
+
else:
|
|
131
|
+
print('already uncovered or flagged')
|
|
132
|
+
elif cmds[0]=='fl':
|
|
133
|
+
if not board[int(cmds[1])-1][int(cmds[2])-1][1] and not board[int(cmds[1])-1][int(cmds[2])-1][0]:
|
|
134
|
+
board[int(cmds[1])-1][int(cmds[2])-1][1]=True
|
|
135
|
+
else:
|
|
136
|
+
print('already flagged or already uncovered')
|
|
137
|
+
elif cmds[0]=='uf':
|
|
138
|
+
if board[int(cmds[1])-1][int(cmds[2])-1][1]:
|
|
139
|
+
board[int(cmds[1])-1][int(cmds[2])-1][1]=False
|
|
140
|
+
else:
|
|
141
|
+
print('already not flagged')
|
|
142
|
+
else:
|
|
143
|
+
throw()
|
|
144
|
+
continue
|
|
145
|
+
if terminal_minesweeper.check(board):
|
|
146
|
+
terminal_minesweeper.print_ending(board)
|
|
147
|
+
exit()
|
|
148
|
+
except KeyboardInterrupt:
|
|
149
|
+
print('Interrupted')
|
|
150
|
+
terminal_minesweeper.print_ending(board)
|
|
151
|
+
except:
|
|
152
|
+
if terminal_minesweeper.check(board):
|
|
153
|
+
exit()
|
|
154
|
+
print('ERROR')
|
|
155
|
+
terminal_minesweeper.print_ending(board)
|
|
156
|
+
def run():
|
|
157
|
+
try:
|
|
158
|
+
__version__ = importlib.metadata.version("your-package-name")
|
|
159
|
+
except importlib.metadata.PackageNotFoundError:
|
|
160
|
+
__version__ = "0.0.0-dev"
|
|
161
|
+
p=argparse.ArgumentParser(description='Minesweeper CLI')
|
|
162
|
+
p.add_argument(
|
|
163
|
+
'-r','--rules',
|
|
164
|
+
action='store_true',
|
|
165
|
+
help='gives rules'
|
|
166
|
+
)
|
|
167
|
+
p.add_argument(
|
|
168
|
+
'-s','--size',
|
|
169
|
+
type=int,
|
|
170
|
+
default=9,
|
|
171
|
+
help='set size to x'
|
|
172
|
+
)
|
|
173
|
+
p.add_argument(
|
|
174
|
+
'-m','--mine_num',
|
|
175
|
+
type=int,
|
|
176
|
+
default=5,
|
|
177
|
+
help='set number of mines to x'
|
|
178
|
+
)
|
|
179
|
+
p.add_argument(
|
|
180
|
+
"-v", "--version",
|
|
181
|
+
action="version",
|
|
182
|
+
version=f"%(prog)s {__version__}"
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
args=p.parse_args()
|
|
186
|
+
if args.rules:
|
|
187
|
+
print_rules()
|
|
188
|
+
if args.size:
|
|
189
|
+
terminal_minesweeper.size=args.size
|
|
190
|
+
if args.mine_num:
|
|
191
|
+
terminal_minesweeper.num=args.mine_num
|
|
192
|
+
mines=terminal_minesweeper.get_mines()
|
|
193
|
+
board=terminal_minesweeper.create_starting_board(mines)
|
|
194
|
+
main_loop(board)
|
|
195
|
+
|
|
196
|
+
def print_rules():
|
|
197
|
+
place='''
|
|
198
|
+
y------>
|
|
199
|
+
x
|
|
200
|
+
|
|
|
201
|
+
|
|
|
202
|
+
|
|
|
203
|
+
V'''
|
|
204
|
+
rules='''
|
|
205
|
+
Minesweeper is a game where you uncover squares in a minefield, and discover where the mines are
|
|
206
|
+
this version has a 9 x 9 board with 10 mines in it.
|
|
207
|
+
commands:
|
|
208
|
+
uc x y = uncovers square (x,y)
|
|
209
|
+
fl x y = flags square (x,y)
|
|
210
|
+
uf x y = unflags square (x,y)
|
|
211
|
+
#####
|
|
212
|
+
Aim:
|
|
213
|
+
uncover every square without a mine on it.
|
|
214
|
+
|
|
215
|
+
Symbols:
|
|
216
|
+
F = flagged
|
|
217
|
+
A space = covered (unknown)
|
|
218
|
+
A number = the number of mines around it
|
|
219
|
+
M = a mine (game over)
|
|
220
|
+
If you step on a mine you lose, the number on the square is how many mines are around it (3 x 3 radius)
|
|
221
|
+
'''
|
|
222
|
+
for i in rules.split('\n'):
|
|
223
|
+
if i=='#####':
|
|
224
|
+
print(place)
|
|
225
|
+
else:
|
|
226
|
+
print(i.rstrip())
|
|
227
|
+
input()
|
|
228
|
+
input('press enter to start:')
|
|
229
|
+
run()
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<!-- play.html -->
|
|
2
|
+
<!DOCTYPE html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>play · tmscli</title>
|
|
8
|
+
<link rel="stylesheet" href="style.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<header>
|
|
12
|
+
<div class="header-inner">
|
|
13
|
+
<div class="logo">tmscli</div>
|
|
14
|
+
<nav>
|
|
15
|
+
<a href="index.html">main</a>
|
|
16
|
+
<a href="about.html">about</a>
|
|
17
|
+
<a href="install.html">installation + usage</a>
|
|
18
|
+
<a href="screenshots.html">screenshots</a>
|
|
19
|
+
<a href="changelog.html">changelog</a>
|
|
20
|
+
<a href="play.html" class="active">play</a>
|
|
21
|
+
</nav>
|
|
22
|
+
</div>
|
|
23
|
+
</header>
|
|
24
|
+
|
|
25
|
+
<main class="container">
|
|
26
|
+
<h1>play tmscli</h1>
|
|
27
|
+
<p class="subhead">Try the game in your browser — no install needed.</p>
|
|
28
|
+
|
|
29
|
+
<div class="embed-card">
|
|
30
|
+
<iframe
|
|
31
|
+
src="https://www.programiz.com/online-compiler/0cfPcHKGhg10y"
|
|
32
|
+
title="tmscli on Programiz"
|
|
33
|
+
loading="lazy"
|
|
34
|
+
allow="clipboard-write"
|
|
35
|
+
referrerpolicy="no-referrer"
|
|
36
|
+
class="embed-frame">
|
|
37
|
+
</iframe>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<p class="embed-fallback">
|
|
41
|
+
If the embed doesn't load, open it directly:
|
|
42
|
+
<a href="https://www.programiz.com/online-compiler/0cfPcHKGhg10y" target="_blank" rel="noopener">
|
|
43
|
+
programiz.com/online-compiler/0cfPcHKGhg10y
|
|
44
|
+
</a>
|
|
45
|
+
</p>
|
|
46
|
+
</main>
|
|
47
|
+
|
|
48
|
+
<footer>
|
|
49
|
+
<p>tmscli · PyPI module · terminal minesweeper</p>
|
|
50
|
+
</footer>
|
|
51
|
+
</body>
|
|
52
|
+
</html>
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
<a href="install.html">installation + usage</a>
|
|
18
18
|
<a href="screenshots.html" class="active">screenshots</a>
|
|
19
19
|
<a href="changelog.html">changelog</a>
|
|
20
|
+
<a href="play.html">play</a>
|
|
20
21
|
</nav>
|
|
21
22
|
</div>
|
|
22
23
|
</header>
|
|
@@ -54,7 +55,7 @@
|
|
|
54
55
|
<div class="screenshot-card">
|
|
55
56
|
<h2>Custom board</h2>
|
|
56
57
|
<img src="img/big.jpg" alt="A custom-sized tmscli board" class="screenshot-img">
|
|
57
|
-
<p>Bigger boards with <code>tmscli -s 16</code> — tmscli is customisable to make it suitable for you.</p>
|
|
58
|
+
<p>Bigger boards with <code>tmscli -s 16 -m 15</code> — tmscli is customisable to make it suitable for you.</p>
|
|
58
59
|
</div>
|
|
59
60
|
|
|
60
61
|
</div>
|
|
@@ -371,4 +371,105 @@ footer {
|
|
|
371
371
|
font-size: 0.7rem;
|
|
372
372
|
padding: 0.8rem;
|
|
373
373
|
}
|
|
374
|
+
}
|
|
375
|
+
/* ---- tables & lists (usage page) ---- */
|
|
376
|
+
|
|
377
|
+
.flags-table {
|
|
378
|
+
width: 100%;
|
|
379
|
+
border-collapse: collapse;
|
|
380
|
+
margin: 1rem 0 1.5rem;
|
|
381
|
+
background: #ffffff;
|
|
382
|
+
border-radius: 12px;
|
|
383
|
+
overflow: hidden;
|
|
384
|
+
border: 1px solid #e1eef5;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.flags-table th,
|
|
388
|
+
.flags-table td {
|
|
389
|
+
text-align: left;
|
|
390
|
+
padding: 0.8rem 1rem;
|
|
391
|
+
border-bottom: 1px solid #eef6fb;
|
|
392
|
+
font-size: 0.95rem;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.flags-table th {
|
|
396
|
+
background: #f0f8fd;
|
|
397
|
+
font-weight: 600;
|
|
398
|
+
color: #0f2b3d;
|
|
399
|
+
font-size: 0.85rem;
|
|
400
|
+
text-transform: uppercase;
|
|
401
|
+
letter-spacing: 0.04em;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.flags-table tr:last-child td {
|
|
405
|
+
border-bottom: none;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.flags-table tr:hover td {
|
|
409
|
+
background: #fafdff;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.symbol-list {
|
|
413
|
+
list-style: none;
|
|
414
|
+
margin: 1rem 0 1.5rem;
|
|
415
|
+
padding: 0;
|
|
416
|
+
background: #ffffff;
|
|
417
|
+
border-radius: 12px;
|
|
418
|
+
border: 1px solid #e1eef5;
|
|
419
|
+
overflow: hidden;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
.symbol-list li {
|
|
423
|
+
padding: 0.7rem 1rem;
|
|
424
|
+
border-bottom: 1px solid #eef6fb;
|
|
425
|
+
font-size: 0.95rem;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.symbol-list li:last-child {
|
|
429
|
+
border-bottom: none;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
@media (max-width: 700px) {
|
|
433
|
+
.flags-table {
|
|
434
|
+
font-size: 0.85rem;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
.flags-table th,
|
|
438
|
+
.flags-table td {
|
|
439
|
+
padding: 0.6rem 0.7rem;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
.embed-card {
|
|
443
|
+
background: #ffffff;
|
|
444
|
+
border: 1px solid #e1eef5;
|
|
445
|
+
border-radius: 18px;
|
|
446
|
+
box-shadow: 0 6px 18px rgba(0, 20, 30, 0.06);
|
|
447
|
+
overflow: hidden;
|
|
448
|
+
margin: 1.5rem 0 1rem;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
.embed-frame {
|
|
452
|
+
width: 100%;
|
|
453
|
+
height: 700px;
|
|
454
|
+
border: 0;
|
|
455
|
+
display: block;
|
|
456
|
+
background: #0b1e2e;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.embed-fallback {
|
|
460
|
+
font-size: 0.9rem;
|
|
461
|
+
color: #5c7a8c;
|
|
462
|
+
text-align: center;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
.embed-fallback a {
|
|
466
|
+
color: #2d7a9b;
|
|
467
|
+
font-weight: 500;
|
|
468
|
+
word-break: break-all;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
@media (max-width: 700px) {
|
|
472
|
+
.embed-frame {
|
|
473
|
+
height: 550px;
|
|
474
|
+
}
|
|
374
475
|
}
|
|
@@ -5,7 +5,7 @@ set -e
|
|
|
5
5
|
|
|
6
6
|
read commit
|
|
7
7
|
read pypi
|
|
8
|
-
if [ "$pypi"=="yes" ]; then
|
|
8
|
+
if [ "$pypi" == "yes" ]; then
|
|
9
9
|
|
|
10
10
|
echo "Building the package with Hatch..."
|
|
11
11
|
hatch build
|
|
@@ -14,7 +14,7 @@ if [ "$pypi"=="yes" ]; then
|
|
|
14
14
|
hatch publish
|
|
15
15
|
|
|
16
16
|
fi
|
|
17
|
-
if [ "$commit"=="yes" ]; then
|
|
17
|
+
if [ "$commit" == "yes" ]; then
|
|
18
18
|
echo "Pulling latest changes from remote Git repository..."
|
|
19
19
|
git pull || echo "Pull skipped or failed, continuing..."
|
|
20
20
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import pyautogui
|
|
2
|
+
from time import sleep
|
|
3
|
+
from random import random as r
|
|
4
|
+
sleep(5)
|
|
5
|
+
with open("src/tmscli/main.py",'r') as script:
|
|
6
|
+
# print(script)
|
|
7
|
+
script=script.read()
|
|
8
|
+
scripts=script.split('\n')
|
|
9
|
+
cur=0
|
|
10
|
+
for i in scripts:
|
|
11
|
+
x=str(i)
|
|
12
|
+
i.lstrip()
|
|
13
|
+
diff=len(x)-len(i)
|
|
14
|
+
diff/=3
|
|
15
|
+
if i[:3]==' ':
|
|
16
|
+
pyautogui.press('tab')
|
|
17
|
+
i=i[3:]
|
|
18
|
+
|
|
19
|
+
|
|
File without changes
|
tmscli-0.3.8/PKG-INFO
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.5
|
|
2
|
-
Name: tmscli
|
|
3
|
-
Version: 0.3.8
|
|
4
|
-
Summary: runs minesweeper in your terminal, type rules for how to play
|
|
5
|
-
Description-Content-Type: text/markdown
|
|
6
|
-
|
|
7
|
-
# minesweeper
|
|
8
|
-
## installation
|
|
9
|
-
```pip install tmscli```
|
|
10
|
-
## Running
|
|
11
|
-
```tms```
|
|
12
|
-
### For rules
|
|
13
|
-
```tms -r```
|
|
14
|
-
### For size
|
|
15
|
-
```tms -s SIZE```
|
|
16
|
-
### For number of mines
|
|
17
|
-
```tms -m NUM```
|
tmscli-0.3.8/README.md
DELETED
tmscli-0.3.8/initialise.sh
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
<!-- install.html (installation + usage) -->
|
|
2
|
-
<!DOCTYPE html>
|
|
3
|
-
<html lang="en">
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="UTF-8">
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
-
<title>installation + usage · tmscli</title>
|
|
8
|
-
<link rel="stylesheet" href="style.css">
|
|
9
|
-
</head>
|
|
10
|
-
<body>
|
|
11
|
-
<header>
|
|
12
|
-
<div class="header-inner">
|
|
13
|
-
<div class="logo">tmscli</div>
|
|
14
|
-
<nav>
|
|
15
|
-
<a href="index.html">main</a>
|
|
16
|
-
<a href="about.html">about</a>
|
|
17
|
-
<a href="install.html" class="active">installation + usage</a>
|
|
18
|
-
<a href="screenshots.html">screenshots</a>
|
|
19
|
-
<a href="changelog.html">changelog</a>
|
|
20
|
-
</nav>
|
|
21
|
-
</div>
|
|
22
|
-
</header>
|
|
23
|
-
|
|
24
|
-
<main class="container">
|
|
25
|
-
<h1>installation & usage</h1>
|
|
26
|
-
<p class="subhead">Get tmscli running in your terminal in seconds.</p>
|
|
27
|
-
|
|
28
|
-
<div class="install-card">
|
|
29
|
-
<h2>Install from PyPI</h2>
|
|
30
|
-
<pre><code>pip install tmscli</code></pre>
|
|
31
|
-
<p>Once installed, the <code>tmscli</code> command becomes available in your terminal.</p>
|
|
32
|
-
</div>
|
|
33
|
-
|
|
34
|
-
<div class="usage-section">
|
|
35
|
-
<h2>Basic usage</h2>
|
|
36
|
-
|
|
37
|
-
<h3>1. Start the game</h3>
|
|
38
|
-
<pre><code>tmscli</code></pre>
|
|
39
|
-
<p>Launches Minesweeper directly in your terminal with the default board.</p>
|
|
40
|
-
|
|
41
|
-
<h3>2. Set the board size</h3>
|
|
42
|
-
<pre><code>tmscli --size 10</code></pre>
|
|
43
|
-
<p>Or use the short form:</p>
|
|
44
|
-
<pre><code>tmscli -s 10</code></pre>
|
|
45
|
-
<p>Adjust the board size to set your own difficulty.</p>
|
|
46
|
-
|
|
47
|
-
<h3>3. Controls</h3>
|
|
48
|
-
<p>Use the arrow keys to move, space to reveal, and <code>f</code> to flag a cell. (Exact keys may vary — check the in‑game help.)</p>
|
|
49
|
-
</div>
|
|
50
|
-
|
|
51
|
-
<div class="lorem-note">
|
|
52
|
-
<h2>Version note</h2>
|
|
53
|
-
<p>v0.3.0 added a border to the minesweeper format and minor bug fixes. Update with:</p>
|
|
54
|
-
<pre><code>pip install --upgrade tmscli</code></pre>
|
|
55
|
-
</div>
|
|
56
|
-
</main>
|
|
57
|
-
|
|
58
|
-
<footer>
|
|
59
|
-
<p>tmscli · PyPI module · terminal minesweeper</p>
|
|
60
|
-
</footer>
|
|
61
|
-
</body>
|
|
62
|
-
</html>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|