improve T-Spin detection

This commit is contained in:
Adrien MALINGREY 2019-10-08 01:06:36 +02:00
parent c5c21c5017
commit deba1a2daf
2 changed files with 40 additions and 42 deletions

View File

@ -135,7 +135,6 @@ class State:
class Timer(AbstractTimer): class Timer(AbstractTimer):
def __init__(self): def __init__(self):
self.tasks = {} self.tasks = {}
@ -165,7 +164,6 @@ class Timer(AbstractTimer):
class MinoSprite(arcade.Sprite): class MinoSprite(arcade.Sprite):
def __init__(self, mino, window, alpha): def __init__(self, mino, window, alpha):
super().__init__() super().__init__()
self.alpha = alpha self.alpha = alpha
@ -182,7 +180,6 @@ class MinoSprite(arcade.Sprite):
class MinoesSprites(arcade.SpriteList): class MinoesSprites(arcade.SpriteList):
def resize(self, scale): def resize(self, scale):
for sprite in self: for sprite in self:
sprite.scale = scale sprite.scale = scale
@ -190,7 +187,6 @@ class MinoesSprites(arcade.SpriteList):
class TetrominoSprites(MinoesSprites): class TetrominoSprites(MinoesSprites):
def __init__(self, tetromino, window, alpha=NORMAL_ALPHA): def __init__(self, tetromino, window, alpha=NORMAL_ALPHA):
super().__init__() super().__init__()
self.tetromino = tetromino self.tetromino = tetromino
@ -211,7 +207,6 @@ class TetrominoSprites(MinoesSprites):
class MatrixSprites(MinoesSprites): class MatrixSprites(MinoesSprites):
def __init__(self, matrix): def __init__(self, matrix):
super().__init__() super().__init__()
self.matrix = matrix self.matrix = matrix
@ -438,7 +433,7 @@ AGAIN""".format(
2 * COLLUMNS * MINO_SIZE, 2 * COLLUMNS * MINO_SIZE,
5 * MINO_SIZE, 5 * MINO_SIZE,
), ),
lifetime=.2, lifetime=0.2,
center_xy=arcade.rand_on_line((0, 0), (matrix.bg.width, 0)), center_xy=arcade.rand_on_line((0, 0), (matrix.bg.width, 0)),
scale=self.scale, scale=self.scale,
alpha=NORMAL_ALPHA, alpha=NORMAL_ALPHA,
@ -641,7 +636,11 @@ High score could not be saved:
) )
def update(self, delta_time): def update(self, delta_time):
for piece in [self.held.piece, self.matrix.piece, self.matrix.ghost] + self.next.pieces: for piece in [
self.held.piece,
self.matrix.piece,
self.matrix.ghost,
] + self.next.pieces:
if piece: if piece:
piece.sprites.update() piece.sprites.update()
for exploding_minoes in self.exploding_minoes: for exploding_minoes in self.exploding_minoes:

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import pickle import pickle
from .utils import Coord, Movement, Rotation, T_Spin from .utils import Coord, Movement, Spin, T_Spin, T_Slot
from .tetromino import Tetromino, T_Tetrimino from .tetromino import Tetromino, T_Tetrimino
from .consts import ( from .consts import (
LINES, LINES,
@ -12,15 +12,15 @@ from .consts import (
AUTOREPEAT_DELAY, AUTOREPEAT_DELAY,
AUTOREPEAT_PERIOD, AUTOREPEAT_PERIOD,
MATRIX_PIECE_COORD, MATRIX_PIECE_COORD,
SCORES,
LINES_CLEAR_NAME
) )
LINES_CLEAR_NAME = "LINES_CLEAR_NAME"
CRYPT_KEY = 987943759387540938469837689379857347598347598379584857934579343 CRYPT_KEY = 987943759387540938469837689379857347598347598379584857934579343
class AbstractTimer: class AbstractTimer:
def postpone(task, delay): def postpone(task, delay):
raise Warning("AbstractTimer.postpone is not implemented.") raise Warning("AbstractTimer.postpone is not implemented.")
@ -31,6 +31,7 @@ class AbstractTimer:
self.timer.cancel(task) self.timer.cancel(task)
self.timer.postpone(task, period) self.timer.postpone(task, period)
class PieceContainer: class PieceContainer:
def __init__(self): def __init__(self):
self.piece = None self.piece = None
@ -69,8 +70,7 @@ class Matrix(list, PieceContainer):
def space_to_fall(self): def space_to_fall(self):
return self.space_to_move( return self.space_to_move(
self.piece.coord + Movement.DOWN, self.piece.coord + Movement.DOWN, (mino.coord for mino in self.piece)
(mino.coord for mino in self.piece),
) )
@ -83,14 +83,6 @@ class NextQueue(PieceContainer):
class Stats: class Stats:
SCORES = (
{LINES_CLEAR_NAME: "", T_Spin.NONE: 0, T_Spin.MINI: 1, T_Spin.T_SPIN: 4},
{LINES_CLEAR_NAME: "SINGLE", T_Spin.NONE: 1, T_Spin.MINI: 2, T_Spin.T_SPIN: 8},
{LINES_CLEAR_NAME: "DOUBLE", T_Spin.NONE: 3, T_Spin.T_SPIN: 12},
{LINES_CLEAR_NAME: "TRIPLE", T_Spin.NONE: 5, T_Spin.T_SPIN: 16},
{LINES_CLEAR_NAME: "TETRIS", T_Spin.NONE: 8},
)
def _get_score(self): def _get_score(self):
return self._score return self._score
@ -136,13 +128,13 @@ class Stats:
if t_spin: if t_spin:
pattern_name.append(t_spin) pattern_name.append(t_spin)
if lines_cleared: if lines_cleared:
pattern_name.append(self.SCORES[lines_cleared][LINES_CLEAR_NAME]) pattern_name.append(SCORES[lines_cleared][LINES_CLEAR_NAME])
self.combo += 1 self.combo += 1
else: else:
self.combo = -1 self.combo = -1
if lines_cleared or t_spin: if lines_cleared or t_spin:
pattern_score = self.SCORES[lines_cleared][t_spin] pattern_score = SCORES[lines_cleared][t_spin]
self.goal -= pattern_score self.goal -= pattern_score
pattern_score *= 100 * self.level pattern_score *= 100 * self.level
pattern_name = "\n".join(pattern_name) pattern_name = "\n".join(pattern_name)
@ -206,7 +198,7 @@ class TetrisLogic:
self.matrix.piece.coord = self.MATRIX_PIECE_COORD self.matrix.piece.coord = self.MATRIX_PIECE_COORD
self.matrix.ghost = self.matrix.piece.ghost() self.matrix.ghost = self.matrix.piece.ghost()
self.refresh_ghost() self.refresh_ghost()
#if self.pressed_actions: # if self.pressed_actions:
# self.timer.postpone(self.repeat_action, self.AUTOREPEAT_DELAY) # self.timer.postpone(self.repeat_action, self.AUTOREPEAT_DELAY)
self.on_generation_phase( self.on_generation_phase(
@ -248,15 +240,17 @@ class TetrisLogic:
def move(self, movement, rotated_coords=None, lock=True): def move(self, movement, rotated_coords=None, lock=True):
potential_coord = self.matrix.piece.coord + movement potential_coord = self.matrix.piece.coord + movement
portential_minoes_coords = rotated_coords or (mino.coord for mino in self.matrix.piece) potential_minoes_coords = rotated_coords or (
if self.matrix.space_to_move(potential_coord, portential_minoes_coords): mino.coord for mino in self.matrix.piece
)
if self.matrix.space_to_move(potential_coord, potential_minoes_coords):
self.matrix.piece.coord = potential_coord self.matrix.piece.coord = potential_coord
if rotated_coords: if rotated_coords:
for mino, coord in zip(self.matrix.piece, rotated_coords): for mino, coord in zip(self.matrix.piece, rotated_coords):
mino.coord = coord mino.coord = coord
self.refresh_ghost() self.refresh_ghost()
if movement != Movement.DOWN: if movement != Movement.DOWN:
self.matrix.piece.last_rotation_point = None self.matrix.piece.rotated_last = False
if self.matrix.space_to_fall(): if self.matrix.space_to_fall():
self.falling_phase() self.falling_phase()
else: else:
@ -267,25 +261,27 @@ class TetrisLogic:
else: else:
return False return False
def rotate(self, rotation): def rotate(self, spin):
rotated_coords = tuple( rotated_coords = tuple(
Coord(rotation * mino.coord.y, -rotation * mino.coord.x) Coord(spin * mino.coord.y, -spin * mino.coord.x)
for mino in self.matrix.piece for mino in self.matrix.piece
) )
for rotation_point, liberty_degree in enumerate( for rotation_point, liberty_degree in enumerate(
self.matrix.piece.SRS[rotation][self.matrix.piece.orientation], start=1 self.matrix.piece.SRS[spin][self.matrix.piece.orientation], start=1
): ):
if self.move(liberty_degree, rotated_coords, lock=False): if self.move(liberty_degree, rotated_coords, lock=False):
self.matrix.piece.orientation = ( self.matrix.piece.orientation = (
self.matrix.piece.orientation + rotation self.matrix.piece.orientation + spin
) % 4 ) % 4
self.matrix.piece.last_rotation_point = rotation_point self.matrix.piece.rotated_last = True
if rotation_point == 5:
self.matrix.piece.rotation_point_5_used = True
return True return True
else: else:
return False return False
def locks_down(self): def locks_down(self):
#self.timer.cancel(self.repeat_action) # self.timer.cancel(self.repeat_action)
self.timer.cancel(self.lock_phase) self.timer.cancel(self.lock_phase)
# Game over # Game over
@ -303,21 +299,24 @@ class TetrisLogic:
self.on_locks_down(self.matrix, self.matrix.piece) self.on_locks_down(self.matrix, self.matrix.piece)
#Pattern phase # Pattern phase
# T-Spin # T-Spin
if ( if (
type(self.matrix.piece) == T_Tetrimino type(self.matrix.piece) == T_Tetrimino
and self.matrix.piece.last_rotation_point is not None and self.matrix.piece.rotated_last
): ):
a = self.is_t_slot(0) a = self.is_t_slot(T_Slot.A)
b = self.is_t_slot(1) b = self.is_t_slot(T_Slot.B)
c = self.is_t_slot(3) c = self.is_t_slot(T_Slot.C)
d = self.is_t_slot(2) d = self.is_t_slot(T_Slot.D)
if self.matrix.piece.last_rotation_point == 5 or (a and b and (c or d)): if a and b and (c or d):
t_spin = T_Spin.T_SPIN t_spin = T_Spin.T_SPIN
elif c and d and (a or b): elif c and d and (a or b):
t_spin = T_Spin.MINI if self.matrix.piece.rotation_point_5_used:
t_spin = T_Spin.T_SPIN
else:
t_spin = T_Spin.MINI
else: else:
t_spin = T_Spin.NONE t_spin = T_Spin.NONE
else: else:
@ -375,10 +374,10 @@ class TetrisLogic:
self.move(Movement.RIGHT) self.move(Movement.RIGHT)
def rotate_clockwise(self): def rotate_clockwise(self):
self.rotate(Rotation.CLOCKWISE) self.rotate(Spin.CLOCKWISE)
def rotate_counter(self): def rotate_counter(self):
self.rotate(Rotation.COUNTER) self.rotate(Spin.COUNTER)
def soft_drop(self): def soft_drop(self):
moved = self.move(Movement.DOWN) moved = self.move(Movement.DOWN)