cetragm 0.1.2__py3-none-any.whl → 0.1.6__py3-none-any.whl
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.
Potentially problematic release.
This version of cetragm might be problematic. Click here for more details.
- cetragm/bag.py +1 -1
- cetragm/controls.py +1 -1
- cetragm/draw.py +2 -2
- cetragm/game.py +4 -2
- cetragm/main.py +78 -41
- cetragm/player.py +2 -1
- cetragm/srs.py +161 -1
- cetragm/tables.py +22 -18
- {cetragm-0.1.2.dist-info → cetragm-0.1.6.dist-info}/METADATA +3 -4
- cetragm-0.1.6.dist-info/RECORD +17 -0
- cetragm-0.1.6.dist-info/entry_points.txt +4 -0
- cetragm-0.1.2.dist-info/RECORD +0 -17
- cetragm-0.1.2.dist-info/entry_points.txt +0 -4
- {cetragm-0.1.2.dist-info → cetragm-0.1.6.dist-info}/WHEEL +0 -0
- {cetragm-0.1.2.dist-info → cetragm-0.1.6.dist-info}/licenses/LICENSE +0 -0
cetragm/bag.py
CHANGED
cetragm/controls.py
CHANGED
cetragm/draw.py
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
# Module for drawing to the screen (stdout tomfuckery time!!!)
|
|
3
3
|
import sys
|
|
4
4
|
import shutil
|
|
5
|
-
from
|
|
6
|
-
from
|
|
5
|
+
from cetragm.tables import pieces, grades
|
|
6
|
+
from cetragm.game import collides
|
|
7
7
|
|
|
8
8
|
BLOCK = "██"
|
|
9
9
|
SHADOW = "▒▒"
|
cetragm/game.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# core logic like lock, gravity, and scoring
|
|
2
|
-
from
|
|
2
|
+
from cetragm.tables import pieces, ROT_180, ROT_CCW, ROT_CW
|
|
3
3
|
import math
|
|
4
4
|
|
|
5
5
|
def get_cells(piece): # {"name": "i", "pos": (0, 0), "rotation": "0"}
|
|
@@ -12,7 +12,6 @@ def get_cells(piece): # {"name": "i", "pos": (0, 0), "rotation": "0"}
|
|
|
12
12
|
return cells
|
|
13
13
|
|
|
14
14
|
def collides(piece, board):
|
|
15
|
-
# Check if the piece is colliding (will want to write a new one for srs.py)
|
|
16
15
|
for (x, y) in get_cells(piece):
|
|
17
16
|
if x < 0 or x >= len(board[0]) or y >= len(board):
|
|
18
17
|
return True
|
|
@@ -33,6 +32,9 @@ def lock_piece(piece, board, player):
|
|
|
33
32
|
board_empty = all(cell[0] for row in board for cell in row)
|
|
34
33
|
soft = player.soft # TODO: ADD SOFT, OR SOFT DROP CALC
|
|
35
34
|
|
|
35
|
+
if board_empty:
|
|
36
|
+
player.score += 2500
|
|
37
|
+
|
|
36
38
|
score_gain, player.combo = get_score(player.level, cleared, player.combo, board_empty, soft)
|
|
37
39
|
player.score += score_gain
|
|
38
40
|
|
cetragm/main.py
CHANGED
|
@@ -6,11 +6,13 @@ import threading
|
|
|
6
6
|
import signal
|
|
7
7
|
import queue
|
|
8
8
|
|
|
9
|
-
from
|
|
10
|
-
from
|
|
11
|
-
from
|
|
12
|
-
from
|
|
13
|
-
from
|
|
9
|
+
from cetragm.draw import draw_board
|
|
10
|
+
from cetragm.game import lock_piece, collides
|
|
11
|
+
from cetragm.player import Player
|
|
12
|
+
from cetragm.bag import Bag
|
|
13
|
+
from cetragm.controls import InputHandler
|
|
14
|
+
from cetragm.srs import rotate_srs
|
|
15
|
+
from cetragm.tables import pieces
|
|
14
16
|
|
|
15
17
|
def sigint_handler(sig, frame):
|
|
16
18
|
sigint.set()
|
|
@@ -19,7 +21,6 @@ def sigint_handler(sig, frame):
|
|
|
19
21
|
sigint = threading.Event()
|
|
20
22
|
lose = threading.Event()
|
|
21
23
|
board_lock = threading.Lock()
|
|
22
|
-
ROT_SEQ = ["0", "r", "2", "l"]
|
|
23
24
|
|
|
24
25
|
signal.signal(signal.SIGINT, sigint_handler)
|
|
25
26
|
|
|
@@ -27,6 +28,27 @@ def setup_board(rows, cols):
|
|
|
27
28
|
board = [[[0] for _ in range(cols)] for _ in range(rows)]
|
|
28
29
|
return board
|
|
29
30
|
|
|
31
|
+
def is_grounded(active_piece, board):
|
|
32
|
+
if not active_piece or "pos" not in active_piece:
|
|
33
|
+
return False
|
|
34
|
+
temp_pos = active_piece["pos"][:]
|
|
35
|
+
temp_pos[1] += 1
|
|
36
|
+
return collides({"name": active_piece["name"], "rotation": active_piece["rotation"], "pos": temp_pos}, board)
|
|
37
|
+
|
|
38
|
+
def get_minos(active_piece):
|
|
39
|
+
if not active_piece or "name" not in active_piece:
|
|
40
|
+
return set()
|
|
41
|
+
try:
|
|
42
|
+
rot_matrix = pieces[active_piece["name"].lower()]["rotations"][active_piece["rotation"]]
|
|
43
|
+
except KeyError:
|
|
44
|
+
return set()
|
|
45
|
+
minos = set()
|
|
46
|
+
for dy, row in enumerate(rot_matrix):
|
|
47
|
+
for dx, cell in enumerate(row):
|
|
48
|
+
if cell:
|
|
49
|
+
minos.add((active_piece["pos"][0] + dx, active_piece["pos"][1] + dy))
|
|
50
|
+
return minos
|
|
51
|
+
|
|
30
52
|
def lock_and_are(player, board, shared):
|
|
31
53
|
board, cleared, loss = lock_piece(player.active_piece, board, player)
|
|
32
54
|
shared["board"] = board
|
|
@@ -39,6 +61,7 @@ def lock_and_are(player, board, shared):
|
|
|
39
61
|
player.fall_progress = 0.0
|
|
40
62
|
player.hold_lock = False
|
|
41
63
|
player.soft = 0
|
|
64
|
+
player.lock_resets = 0
|
|
42
65
|
|
|
43
66
|
if cleared:
|
|
44
67
|
return "line_clear", 0.0
|
|
@@ -57,16 +80,16 @@ def lock_now(player, board, shared, bag):
|
|
|
57
80
|
if loss:
|
|
58
81
|
lose.set()
|
|
59
82
|
return "loss"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
83
|
+
|
|
84
|
+
player.active_piece = {}
|
|
85
|
+
player.fall_progress = 0.0
|
|
86
|
+
player.soft = 0
|
|
87
|
+
player.hold_lock = False
|
|
88
|
+
player.lock_resets = 0
|
|
89
|
+
if cleared:
|
|
64
90
|
return "line_clear"
|
|
65
91
|
else:
|
|
66
92
|
player.active_piece = {"name": bag.get_piece(), "pos": [3, 0], "rotation": "0"}
|
|
67
|
-
player.fall_progress = 0.0
|
|
68
|
-
player.soft = 0
|
|
69
|
-
player.hold_lock = False
|
|
70
93
|
return "active"
|
|
71
94
|
|
|
72
95
|
def input_handler(player, board, action, bag, shared, LOCK_DELAY, FRAME):
|
|
@@ -108,24 +131,18 @@ def input_handler(player, board, action, bag, shared, LOCK_DELAY, FRAME):
|
|
|
108
131
|
return lock_now(player, board, shared, bag)
|
|
109
132
|
|
|
110
133
|
elif action == "rotate_cw":
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if collides(piece, board):
|
|
114
|
-
piece["rotation"] = old_rot
|
|
134
|
+
rotate_srs(player.active_piece, +1, board,
|
|
135
|
+
lambda n,r,p: collides({"name": n, "rotation": r, "pos": [p[0], p[1]]}, board))
|
|
115
136
|
return None
|
|
116
137
|
|
|
117
138
|
elif action == "rotate_ccw":
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if collides(piece, board):
|
|
121
|
-
piece["rotation"] = old_rot
|
|
139
|
+
rotate_srs(player.active_piece, -1, board,
|
|
140
|
+
lambda n,r,p: collides({"name": n, "rotation": r, "pos": [p[0], p[1]]}, board))
|
|
122
141
|
return None
|
|
123
142
|
|
|
124
143
|
elif action == "rotate_180":
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if collides(piece, board):
|
|
128
|
-
piece["rotation"] = old_rot
|
|
144
|
+
rotate_srs(player.active_piece, 2, board,
|
|
145
|
+
lambda n,r,p: collides({"name": n, "rotation": r, "pos": [p[0], p[1]]}, board))
|
|
129
146
|
return None
|
|
130
147
|
|
|
131
148
|
elif action == "hold":
|
|
@@ -135,11 +152,12 @@ def input_handler(player, board, action, bag, shared, LOCK_DELAY, FRAME):
|
|
|
135
152
|
player.hold_piece = player.active_piece["name"]
|
|
136
153
|
if not old:
|
|
137
154
|
player.active_piece = {"name": bag.get_piece(), "pos": [3, 0], "rotation": "0"}
|
|
138
|
-
player.fall_progress = 0.0
|
|
139
155
|
else:
|
|
140
156
|
player.active_piece = {"name": old, "pos": [3, 0], "rotation": "0"}
|
|
141
|
-
|
|
157
|
+
|
|
158
|
+
player.fall_progress = 0.0
|
|
142
159
|
player.hold_lock = True
|
|
160
|
+
player.lock_resets = 0
|
|
143
161
|
return None
|
|
144
162
|
|
|
145
163
|
return None
|
|
@@ -174,7 +192,7 @@ def render_loop(shared, player, bag, fps):
|
|
|
174
192
|
print("\x1b[H\x1b[31mRunning below 60fps!! Performance will be degraded\x1b[0m")
|
|
175
193
|
|
|
176
194
|
def game_loop(shared, player, bag, inputs, fps):
|
|
177
|
-
from
|
|
195
|
+
from cetragm.config import ARE_FRAMES, LINE_CLEAR_FRAMES, LOCK_DELAY_FRAMES
|
|
178
196
|
FRAME = 1.0 / fps
|
|
179
197
|
|
|
180
198
|
LOCK_DELAY = LOCK_DELAY_FRAMES * FRAME
|
|
@@ -190,6 +208,9 @@ def game_loop(shared, player, bag, inputs, fps):
|
|
|
190
208
|
if not hasattr(player, "fall_progress"):
|
|
191
209
|
player.fall_progress = 0.0
|
|
192
210
|
|
|
211
|
+
if not hasattr(player, "lock_resets"):
|
|
212
|
+
player.lock_resets = 0
|
|
213
|
+
|
|
193
214
|
while not sigint.is_set():
|
|
194
215
|
now = time.perf_counter()
|
|
195
216
|
dt = now - last_time
|
|
@@ -205,6 +226,9 @@ def game_loop(shared, player, bag, inputs, fps):
|
|
|
205
226
|
except queue.Empty:
|
|
206
227
|
break
|
|
207
228
|
|
|
229
|
+
was_grounded = is_grounded(player.active_piece, board)
|
|
230
|
+
old_minos = get_minos(player.active_piece)
|
|
231
|
+
|
|
208
232
|
new_state = input_handler(player, board, action, bag, shared, LOCK_DELAY, FRAME)
|
|
209
233
|
|
|
210
234
|
if new_state == "ground":
|
|
@@ -216,13 +240,23 @@ def game_loop(shared, player, bag, inputs, fps):
|
|
|
216
240
|
phase_timer = 0.0
|
|
217
241
|
continue
|
|
218
242
|
|
|
219
|
-
if new_state in ("line_clear", "are", "loss"):
|
|
243
|
+
if new_state in ("line_clear", "are", "loss", "active"):
|
|
220
244
|
state = new_state
|
|
221
245
|
phase_timer = 0.0
|
|
222
246
|
player.hold_lock = False
|
|
223
247
|
if state == "active":
|
|
224
|
-
player.
|
|
248
|
+
player.fall_progress = 0.0
|
|
225
249
|
break
|
|
250
|
+
|
|
251
|
+
new_minos = get_minos(player.active_piece)
|
|
252
|
+
if new_minos != old_minos and was_grounded:
|
|
253
|
+
now_grounded = is_grounded(player.active_piece, board)
|
|
254
|
+
if now_grounded:
|
|
255
|
+
player.lock_resets += 1
|
|
256
|
+
if player.lock_resets <= 15:
|
|
257
|
+
lock_timer = 0.0
|
|
258
|
+
else:
|
|
259
|
+
player.lock_resets = 0
|
|
226
260
|
|
|
227
261
|
player.check_grade()
|
|
228
262
|
|
|
@@ -251,17 +285,18 @@ def game_loop(shared, player, bag, inputs, fps):
|
|
|
251
285
|
break
|
|
252
286
|
else:
|
|
253
287
|
lock_timer = 0.0
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
288
|
+
|
|
289
|
+
if state == "active":
|
|
290
|
+
piece = player.active_piece
|
|
291
|
+
temp_pos = piece["pos"].copy()
|
|
292
|
+
temp_pos[1] += 1
|
|
293
|
+
if collides({"name": piece["name"], "pos": temp_pos, "rotation": piece["rotation"]}, board):
|
|
294
|
+
lock_timer += dt
|
|
295
|
+
if lock_timer >= LOCK_DELAY:
|
|
296
|
+
state, lock_timer = lock_and_are(player, board, shared)
|
|
297
|
+
if state == "loss":
|
|
298
|
+
return
|
|
299
|
+
phase_timer = 0.0
|
|
265
300
|
|
|
266
301
|
# pause after line clear
|
|
267
302
|
elif state == "line_clear":
|
|
@@ -277,6 +312,7 @@ def game_loop(shared, player, bag, inputs, fps):
|
|
|
277
312
|
player.active_piece = {"name": bag.get_piece(), "pos": [3, 0], "rotation": "0"}
|
|
278
313
|
player.fall_progress = 0.0
|
|
279
314
|
lock_timer = 0.0
|
|
315
|
+
player.lock_resets = 0
|
|
280
316
|
state = "active"
|
|
281
317
|
|
|
282
318
|
# first piece
|
|
@@ -284,6 +320,7 @@ def game_loop(shared, player, bag, inputs, fps):
|
|
|
284
320
|
player.active_piece = {"name": bag.get_piece(), "pos": [3, 0], "rotation": "0"} # and again
|
|
285
321
|
player.fall_progress = 0.0
|
|
286
322
|
lock_timer = 0.0
|
|
323
|
+
player.lock_resets = 0
|
|
287
324
|
state = "active"
|
|
288
325
|
|
|
289
326
|
elapsed_loop = time.perf_counter() - now
|
cetragm/player.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# module containing the Player class and its functions
|
|
2
2
|
|
|
3
3
|
import time
|
|
4
|
-
from
|
|
4
|
+
from cetragm.tables import thresholds, gravity
|
|
5
5
|
|
|
6
6
|
class Player:
|
|
7
7
|
def __init__(self):
|
|
@@ -23,6 +23,7 @@ class Player:
|
|
|
23
23
|
self.combo = 0
|
|
24
24
|
self.soft = 0
|
|
25
25
|
self.hold_lock = False
|
|
26
|
+
self.lock_resets = 0
|
|
26
27
|
self.fall_progress = 0.0
|
|
27
28
|
|
|
28
29
|
def upd_time(self):
|
cetragm/srs.py
CHANGED
|
@@ -1 +1,161 @@
|
|
|
1
|
-
# Definitions of the tomfuckery that is Super Rotation System (rotation and wallkicks)
|
|
1
|
+
# Definitions of the tomfuckery that is Super Rotation System (rotation and wallkicks)
|
|
2
|
+
|
|
3
|
+
from typing import Tuple, Callable, List, Dict
|
|
4
|
+
|
|
5
|
+
Pos = Tuple[int, int]
|
|
6
|
+
CollidesFn = Callable[[str, str, Pos], bool]
|
|
7
|
+
|
|
8
|
+
ROT_SEQ = ["0", "r", "2", "l"]
|
|
9
|
+
ROT_CW = {"0": "r", "r": "2", "2": "l", "l": "0"}
|
|
10
|
+
ROT_CCW = {"0": "l", "l": "2", "2": "r", "r": "0"}
|
|
11
|
+
ROT_180 = {"0": "2", "2": "0", "r": "l", "l": "r"}
|
|
12
|
+
JLSTZ_OFFSETS = {"0": (0,0), "r": (0,0), "2": (0,0), "l": (0,0)}
|
|
13
|
+
|
|
14
|
+
I_OFFSETS = {
|
|
15
|
+
"0": (0, 0),
|
|
16
|
+
"r": (0, 0),
|
|
17
|
+
"2": (0, 0),
|
|
18
|
+
"l": (0, 0),
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
# These kick tables are not my values, they're from the Super Rotation System (or Tetris Guideline)
|
|
22
|
+
# Also they were originally inverted until the commit that added this comment so i made an LLM invert them because im too lazy
|
|
23
|
+
JLSTZ_KICKS = {
|
|
24
|
+
("0", "r"): [(0,0), (-1,0), (-1,-1), (0,2), (-1,2)],
|
|
25
|
+
("r", "0"): [(0,0), (1,0), (1,1), (0,-2), (1,-2)],
|
|
26
|
+
|
|
27
|
+
("r", "2"): [(0,0), (1,0), (1,1), (0,-2), (1,-2)],
|
|
28
|
+
("2", "r"): [(0,0), (-1,0), (-1,-1), (0,2), (-1,2)],
|
|
29
|
+
|
|
30
|
+
("2", "l"): [(0,0), (1,0), (1,-1), (0,2), (1,2)],
|
|
31
|
+
("l", "2"): [(0,0), (-1,0), (-1,1), (0,-2), (-1,-2)],
|
|
32
|
+
|
|
33
|
+
("l", "0"): [(0,0), (-1,0), (-1,1), (0,-2), (-1,-2)],
|
|
34
|
+
("0", "l"): [(0,0), (1,0), (1,-1), (0,2), (1,2)],
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
I_KICKS = {
|
|
38
|
+
("0", "r"): [(0,0), (-2,0), (1,0), (-2,1), (1,-2)],
|
|
39
|
+
("r", "0"): [(0,0), (2,0), (-1,0), (2,-1), (-1,2)],
|
|
40
|
+
|
|
41
|
+
("r", "2"): [(0,0), (-1,0), (2,0), (-1,-2), (2,1)],
|
|
42
|
+
("2", "r"): [(0,0), (1,0), (-2,0), (1,2), (-2,-1)],
|
|
43
|
+
|
|
44
|
+
("2", "l"): [(0,0), (2,0), (-1,0), (2,-1), (-1,2)],
|
|
45
|
+
("l", "2"): [(0,0), (-2,0), (1,0), (-2,1), (1,-2)],
|
|
46
|
+
|
|
47
|
+
("l", "0"): [(0,0), (1,0), (-2,0), (1,2), (-2,-1)],
|
|
48
|
+
("0", "l"): [(0,0), (-1,0), (2,0), (-1,-2), (2,1)],
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
O_KICKS = {
|
|
52
|
+
("0", "r"): [(0,0)],
|
|
53
|
+
("r", "2"): [(0,0)],
|
|
54
|
+
|
|
55
|
+
("2", "l"): [(0,0)],
|
|
56
|
+
("l", "0"): [(0,0)],
|
|
57
|
+
|
|
58
|
+
("r", "0"): [(0,0)],
|
|
59
|
+
("2", "r"): [(0,0)],
|
|
60
|
+
|
|
61
|
+
("l", "2"): [(0,0)],
|
|
62
|
+
("0", "l"): [(0,0)],
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
JLSTZ_KICKS_180 = {
|
|
66
|
+
("0","2"): [(0,0), (0,-1), (0,-2), (1,0), (-1,0), (1,-1), (-1,-1)],
|
|
67
|
+
("2","0"): [(0,0), (0,-1), (0,-2), (-1,0), (1,0), (-1,-1), (1,-1)],
|
|
68
|
+
("r","l"): [(0,0), (0,-1), (0,-2), (1,0), (-1,0), (1,-1), (-1,-1)],
|
|
69
|
+
("l","r"): [(0,0), (0,-1), (0,-2), (-1,0), (1,0), (-1,-1), (1,-1)],
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
I_KICKS_180 = {
|
|
73
|
+
("0","2"): [(0,0), (0,1), (0,-1), (1,0), (-1,0), (2,0), (-2,0)],
|
|
74
|
+
("2","0"): [(0,0), (0,1), (0,-1), (-1,0), (1,0), (-2,0), (2,0)],
|
|
75
|
+
("r","l"): [(0,0), (0,1), (0,-1), (1,0), (-1,0)],
|
|
76
|
+
("l","r"): [(0,0), (0,1), (0,-1), (-1,0), (1,0)],
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
def rotate_label(current: str, direction:int) -> str:
|
|
80
|
+
if direction == +1:
|
|
81
|
+
return ROT_CW[current]
|
|
82
|
+
if direction == -1:
|
|
83
|
+
return ROT_CCW[current]
|
|
84
|
+
if direction == 2:
|
|
85
|
+
return ROT_180[current]
|
|
86
|
+
return current
|
|
87
|
+
|
|
88
|
+
def _offset_for(name: str, rot: str) -> Pos:
|
|
89
|
+
n = name.lower()
|
|
90
|
+
if n == "i":
|
|
91
|
+
return I_OFFSETS[rot]
|
|
92
|
+
return JLSTZ_OFFSETS[rot]
|
|
93
|
+
|
|
94
|
+
def _kick_table(name: str):
|
|
95
|
+
n = name.lower()
|
|
96
|
+
if n == "i":
|
|
97
|
+
return I_KICKS
|
|
98
|
+
if n == "o":
|
|
99
|
+
return O_KICKS
|
|
100
|
+
return JLSTZ_KICKS
|
|
101
|
+
|
|
102
|
+
def _kick_table_180(name: str):
|
|
103
|
+
n = name.lower()
|
|
104
|
+
if n == "i":
|
|
105
|
+
return I_KICKS_180
|
|
106
|
+
if n == "o":
|
|
107
|
+
return O_KICKS
|
|
108
|
+
return JLSTZ_KICKS_180
|
|
109
|
+
|
|
110
|
+
def _get_kicks_for(name: str, fr: str, to: str, direction: int) -> List[Tuple[int,int]]:
|
|
111
|
+
table = _kick_table_180(name) if direction == 2 else _kick_table(name)
|
|
112
|
+
if (fr, to) in table:
|
|
113
|
+
return list(table[(fr,to)])
|
|
114
|
+
if (to, fr) in table:
|
|
115
|
+
return [(-dx, -dy) for dx, dy in table[(to, fr)]]
|
|
116
|
+
return [(0,0)]
|
|
117
|
+
|
|
118
|
+
def try_rotate_srs(
|
|
119
|
+
name: str,
|
|
120
|
+
pos: Pos,
|
|
121
|
+
rot_label: str,
|
|
122
|
+
direction: int,
|
|
123
|
+
board,
|
|
124
|
+
collides_fn: CollidesFn,
|
|
125
|
+
) -> Tuple[str, Pos, bool]: # false if no kick
|
|
126
|
+
name = name.lower()
|
|
127
|
+
if rot_label not in ROT_SEQ:
|
|
128
|
+
raise ValueError("invalid rotation")
|
|
129
|
+
if direction not in (1, -1, 2):
|
|
130
|
+
return rot_label, pos, False
|
|
131
|
+
|
|
132
|
+
to_label = rotate_label(rot_label, direction)
|
|
133
|
+
|
|
134
|
+
off_from = _offset_for(name, rot_label)
|
|
135
|
+
off_to = _offset_for(name, to_label)
|
|
136
|
+
delta_off = (off_from[0] - off_to[0], off_from[1] - off_to[1])
|
|
137
|
+
|
|
138
|
+
kicks = _get_kicks_for(name, rot_label, to_label, direction)
|
|
139
|
+
|
|
140
|
+
for dx, dy in kicks:
|
|
141
|
+
tx = pos[0] + dx + delta_off[0]
|
|
142
|
+
ty = pos[1] + dy + delta_off[1]
|
|
143
|
+
if not collides_fn(name, to_label, (tx, ty)):
|
|
144
|
+
return to_label, (tx, ty), True
|
|
145
|
+
return rot_label, pos, False
|
|
146
|
+
|
|
147
|
+
def rotate_srs(
|
|
148
|
+
piece: dict,
|
|
149
|
+
direction: int,
|
|
150
|
+
board,
|
|
151
|
+
collides_fn: CollidesFn,
|
|
152
|
+
) -> bool:
|
|
153
|
+
name = piece["name"]
|
|
154
|
+
pos = tuple(piece["pos"])
|
|
155
|
+
rot = piece["rotation"]
|
|
156
|
+
new_rot, new_pos, ok = try_rotate_srs(name, pos, rot, direction, board, collides_fn)
|
|
157
|
+
if ok:
|
|
158
|
+
piece["rotation"] = new_rot
|
|
159
|
+
piece["pos"] = [int(new_pos[0]), int(new_pos[1])]
|
|
160
|
+
return True
|
|
161
|
+
return False
|
cetragm/tables.py
CHANGED
|
@@ -390,25 +390,29 @@ gravity = {
|
|
|
390
390
|
90: 64,
|
|
391
391
|
100: 80,
|
|
392
392
|
120: 96,
|
|
393
|
-
140:
|
|
394
|
-
160:
|
|
395
|
-
170:
|
|
393
|
+
140: 100,
|
|
394
|
+
160: 112,
|
|
395
|
+
170: 120,
|
|
396
396
|
200: 4,
|
|
397
|
-
220:
|
|
398
|
-
230:
|
|
399
|
-
233:
|
|
400
|
-
236:
|
|
401
|
-
239:
|
|
402
|
-
243:
|
|
403
|
-
247:
|
|
404
|
-
251:
|
|
405
|
-
300:
|
|
406
|
-
330:
|
|
407
|
-
360:
|
|
408
|
-
400:
|
|
409
|
-
420:
|
|
410
|
-
450:
|
|
411
|
-
500:
|
|
397
|
+
220: 16,
|
|
398
|
+
230: 32,
|
|
399
|
+
233: 64,
|
|
400
|
+
236: 96,
|
|
401
|
+
239: 100,
|
|
402
|
+
243: 120,
|
|
403
|
+
247: 130,
|
|
404
|
+
251: 140,
|
|
405
|
+
300: 180,
|
|
406
|
+
330: 200,
|
|
407
|
+
360: 220,
|
|
408
|
+
400: 256, # 1g
|
|
409
|
+
420: 300,
|
|
410
|
+
450: 340,
|
|
411
|
+
500: 512,
|
|
412
|
+
600: 768,
|
|
413
|
+
700: 1024,
|
|
414
|
+
750: 1280,
|
|
415
|
+
800: 5120 # 20g
|
|
412
416
|
}
|
|
413
417
|
|
|
414
418
|
ROT_CW = {"0": "r", "r": "2", "2": "l", "l": "0"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cetragm
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: Cetra Grand Master | An oddly familiar block stacker in the command line!
|
|
5
5
|
License-Expression: GPL-3.0-only
|
|
6
6
|
License-File: LICENSE
|
|
@@ -29,22 +29,21 @@ Features:
|
|
|
29
29
|
- Dynamic gravity (speed) as your level increases
|
|
30
30
|
- Scoring system
|
|
31
31
|
- Gameplay timer
|
|
32
|
-
- 7-bag piece drawing
|
|
32
|
+
- 7-bag piece drawing
|
|
33
33
|
- 5-piece next queue and level display
|
|
34
34
|
- Persistent TLS (or shadow piece)
|
|
35
35
|
- TGM's 20G gravity after level 500
|
|
36
36
|
- Proper ARE, lock delay, and line clear delay
|
|
37
37
|
- Real-time gravity (not tied to frame rates)
|
|
38
|
+
- The standard Super Rotation System and all its janky kicks!
|
|
38
39
|
|
|
39
40
|
Drawbacks:
|
|
40
41
|
- Requires manual ARR/DAS and can't press two keys at once
|
|
41
|
-
- Very sub-par rotation system
|
|
42
42
|
- Scoring is slightly off
|
|
43
43
|
- Lack of theming or menus at all, as well as a lose state
|
|
44
44
|
- No sound (background or effect)
|
|
45
45
|
|
|
46
46
|
To add by next week:
|
|
47
|
-
- The Super Rotation System and standard wallkicks
|
|
48
47
|
- T-spins and detection for them
|
|
49
48
|
- IHS and IRS (Inital Hold/Rotation System)
|
|
50
49
|
- Full menu with configuration
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
cetragm/__init__.py,sha256=okJMmUyau9oeoBfxhg6AYZn4nPvcTqLrAgzIDpUXMz8,382
|
|
2
|
+
cetragm/audio.py,sha256=-w9omAYlvbUPRHuOe0IOBCSbBnjaOM9MjQy6oRU-hgA,47
|
|
3
|
+
cetragm/bag.py,sha256=qPvDmKoduJPZuwz5DMhh9rp85MUEfUPuiFsqOfJNq2U,704
|
|
4
|
+
cetragm/config.py,sha256=tJjbKxtwIWb3AMmIyBUosWkyHFO0OEzpYbqO5PHxz84,550
|
|
5
|
+
cetragm/controls.py,sha256=iR-ZpudiE6J92FMZmOwZlZpcOUhxfc1bWvb18VR4Cbk,3165
|
|
6
|
+
cetragm/draw.py,sha256=F4GZhNAXhxyPCksY0Pq4wjJQ904pgqCrCZ2ZDfgZHlU,6459
|
|
7
|
+
cetragm/game.py,sha256=tfIEEbtZc6VxxARGdlJ7C_jBzw-rsJU2dM8I7gPqMLk,3164
|
|
8
|
+
cetragm/main.py,sha256=G2ce_4AsKDHd6GU5oig5ScUfSqa2uaEVVoHn85C6fhw,11624
|
|
9
|
+
cetragm/player.py,sha256=9KL5cNDYCp98OB7AiVdKISCbnmSqMn0StM2Ve3OHWGE,2469
|
|
10
|
+
cetragm/srs.py,sha256=Fi4mOkaM_Qq716XUa1V4W1W2j4P7WsZmGnkOMbj7H2o,4865
|
|
11
|
+
cetragm/tables.py,sha256=X3XBkTqQ7mX_jYDoDD5DfhW_cM8NOp-EU6tUY5PnoSE,12285
|
|
12
|
+
cetragm/ui.txt,sha256=7wSQU8ht-5A2Fz5iFbuLTdzc1Cl6otcnqIRUw5_wZoM,2006
|
|
13
|
+
cetragm-0.1.6.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
14
|
+
cetragm-0.1.6.dist-info/WHEEL,sha256=Jb20R3Ili4n9P1fcwuLup21eQ5r9WXhs4_qy7VTrgPI,79
|
|
15
|
+
cetragm-0.1.6.dist-info/entry_points.txt,sha256=m6wjlRzXqvDPFceo250KJO4LDsEp_q2rBcCZa2lDcpo,73
|
|
16
|
+
cetragm-0.1.6.dist-info/METADATA,sha256=Hi6l9TgKtRhRz6F2UZFLvBu7g-b7W3lKav0_pHCRcuE,3134
|
|
17
|
+
cetragm-0.1.6.dist-info/RECORD,,
|
cetragm-0.1.2.dist-info/RECORD
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
cetragm/__init__.py,sha256=okJMmUyau9oeoBfxhg6AYZn4nPvcTqLrAgzIDpUXMz8,382
|
|
2
|
-
cetragm/audio.py,sha256=-w9omAYlvbUPRHuOe0IOBCSbBnjaOM9MjQy6oRU-hgA,47
|
|
3
|
-
cetragm/bag.py,sha256=GOLle_p4uJIDAr81d6mT6ERK6g9N97tYTL53a5JExzA,700
|
|
4
|
-
cetragm/config.py,sha256=tJjbKxtwIWb3AMmIyBUosWkyHFO0OEzpYbqO5PHxz84,550
|
|
5
|
-
cetragm/controls.py,sha256=5KiPc2UlB-mdYik48F-qrhZPWwPjneGicoAcEWtcyrE,3161
|
|
6
|
-
cetragm/draw.py,sha256=t_kRyYDo6miDCKzVFUBmjyBA3BYbzxN49p_85DYpwcU,6451
|
|
7
|
-
cetragm/game.py,sha256=ko2ADM8q3AkXdEwQIwva4MFA2PCKOlaETjmp_Qbgwz0,3186
|
|
8
|
-
cetragm/main.py,sha256=8TChVoLKkSr13nMhxPMIkNBV13_Iw-fnubJWnZzPUUQ,9971
|
|
9
|
-
cetragm/player.py,sha256=BjmsyZ8XYMq8nn2T28Ze23Ey1GMv1LrzRw7OSFJYJb8,2436
|
|
10
|
-
cetragm/srs.py,sha256=AV-JXtGqX6bc9mvSSlSngL5squr4P_qYz7tbBghZBB0,86
|
|
11
|
-
cetragm/tables.py,sha256=MCLD4tz5fO0YJJwEqdqmXegR24kzjWkzvZP5Ev6fQEQ,12220
|
|
12
|
-
cetragm/ui.txt,sha256=7wSQU8ht-5A2Fz5iFbuLTdzc1Cl6otcnqIRUw5_wZoM,2006
|
|
13
|
-
cetragm-0.1.2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
14
|
-
cetragm-0.1.2.dist-info/WHEEL,sha256=Jb20R3Ili4n9P1fcwuLup21eQ5r9WXhs4_qy7VTrgPI,79
|
|
15
|
-
cetragm-0.1.2.dist-info/entry_points.txt,sha256=8jMkTAJSkUBD_f2FGMlk9_AdrWzhj9Ohv8TKfA1kSuk,71
|
|
16
|
-
cetragm-0.1.2.dist-info/METADATA,sha256=ysMe2qfpxFpM96jXxsq3MomX6b77kIPe6Hk1zXtQFiU,3191
|
|
17
|
-
cetragm-0.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|