Finish game
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import pygame
|
||||
import pygame.draw as draw
|
||||
from collections import namedtuple, defaultdict
|
||||
from typing import NamedTuple, Any, Iterable, Optional
|
||||
from typing import NamedTuple, Any, Iterable, Optional, Callable
|
||||
from functools import cache
|
||||
import random
|
||||
import math
|
||||
@@ -107,7 +107,7 @@ class Action(NamedTuple):
|
||||
MOVE_RIGHT = auto()
|
||||
OPEN_HELP = auto()
|
||||
|
||||
# Game over
|
||||
# Game over (also in game)
|
||||
RESTART = auto()
|
||||
|
||||
# Help
|
||||
@@ -241,6 +241,23 @@ class Font:
|
||||
return surf
|
||||
|
||||
|
||||
class LazyVariable:
|
||||
def __init__(self, thunk: Callable[[], Any]):
|
||||
self.thunk = thunk
|
||||
self.need_eval = True
|
||||
self.value = None
|
||||
|
||||
def __get__(self, instance: Any, owner: Optional[type] = None):
|
||||
if self.need_eval:
|
||||
self.value = self.thunk()
|
||||
self.need_eval = False
|
||||
return self.value
|
||||
|
||||
def __set__(self, instance: Any, value: Any):
|
||||
self.value = value
|
||||
self.need_eval = False
|
||||
|
||||
|
||||
class Game:
|
||||
PLACE_POINTS = 10
|
||||
CLEAR_POINTS = 100
|
||||
@@ -293,7 +310,7 @@ class Game:
|
||||
pygame.K_s,
|
||||
Action.Type.SWAP_HOLD,
|
||||
False,
|
||||
"Swap the current and held piece.",
|
||||
"Swap the current and held pieces.",
|
||||
),
|
||||
Action(
|
||||
pygame.K_DOWN, Action.Type.DROP, True, "Drop the current piece."
|
||||
@@ -310,6 +327,12 @@ class Game:
|
||||
True,
|
||||
"Move the current piece right.",
|
||||
),
|
||||
Action(
|
||||
pygame.K_r,
|
||||
Action.Type.RESTART,
|
||||
False,
|
||||
"Start a new game.",
|
||||
),
|
||||
Action(
|
||||
pygame.K_h,
|
||||
Action.Type.OPEN_HELP,
|
||||
@@ -335,435 +358,10 @@ class Game:
|
||||
),
|
||||
)
|
||||
|
||||
FONT = Font(
|
||||
6,
|
||||
3,
|
||||
3,
|
||||
[
|
||||
Font.Glyph(
|
||||
" ",
|
||||
[
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"a",
|
||||
[
|
||||
"*****",
|
||||
"* *",
|
||||
"*****",
|
||||
"* *",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"b",
|
||||
[
|
||||
"**** ",
|
||||
"* *",
|
||||
"*****",
|
||||
"* *",
|
||||
"**** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"c",
|
||||
[
|
||||
"*****",
|
||||
"* *",
|
||||
"* ",
|
||||
"* *",
|
||||
"*****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"d",
|
||||
[
|
||||
"**** ",
|
||||
"* *",
|
||||
"* *",
|
||||
"* *",
|
||||
"**** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"e",
|
||||
[
|
||||
"*****",
|
||||
"* ",
|
||||
"**** ",
|
||||
"* ",
|
||||
"*****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"f",
|
||||
[
|
||||
"*****",
|
||||
"* ",
|
||||
"**** ",
|
||||
"* ",
|
||||
"* ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"g",
|
||||
[
|
||||
"*****",
|
||||
"* ",
|
||||
"* **",
|
||||
"* *",
|
||||
"*****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"h",
|
||||
[
|
||||
"* *",
|
||||
"* *",
|
||||
"*****",
|
||||
"* *",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"i",
|
||||
[
|
||||
"*****",
|
||||
" * ",
|
||||
" * ",
|
||||
" * ",
|
||||
"*****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"j",
|
||||
[
|
||||
"*****",
|
||||
" * ",
|
||||
" * ",
|
||||
"* * ",
|
||||
" ** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"k",
|
||||
[
|
||||
"* *",
|
||||
"* * ",
|
||||
"*** ",
|
||||
"* * ",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"l",
|
||||
[
|
||||
"* ",
|
||||
"* ",
|
||||
"* ",
|
||||
"* ",
|
||||
"*****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"m",
|
||||
[
|
||||
"* *",
|
||||
"** **",
|
||||
"* * *",
|
||||
"* *",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"n",
|
||||
[
|
||||
"* *",
|
||||
"** *",
|
||||
"* * *",
|
||||
"* **",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"o",
|
||||
[
|
||||
" *** ",
|
||||
"* *",
|
||||
"* *",
|
||||
"* *",
|
||||
" *** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"p",
|
||||
[
|
||||
"**** ",
|
||||
"* *",
|
||||
"**** ",
|
||||
"* ",
|
||||
"* ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"q",
|
||||
[
|
||||
" *** ",
|
||||
"* *",
|
||||
"* * *",
|
||||
"* * ",
|
||||
" ** *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"r",
|
||||
[
|
||||
"**** ",
|
||||
"* *",
|
||||
"**** ",
|
||||
"* * ",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"s",
|
||||
[
|
||||
" ****",
|
||||
"* ",
|
||||
" *** ",
|
||||
" *",
|
||||
"**** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"t",
|
||||
[
|
||||
"*****",
|
||||
" * ",
|
||||
" * ",
|
||||
" * ",
|
||||
" * ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"u",
|
||||
[
|
||||
"* *",
|
||||
"* *",
|
||||
"* *",
|
||||
"* *",
|
||||
" *** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"v",
|
||||
[
|
||||
"* *",
|
||||
"* *",
|
||||
"* *",
|
||||
" * * ",
|
||||
" * ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"w",
|
||||
[
|
||||
"* *",
|
||||
"* *",
|
||||
"* * *",
|
||||
"** **",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"x",
|
||||
[
|
||||
"* *",
|
||||
" * * ",
|
||||
" * ",
|
||||
" * * ",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"y",
|
||||
[
|
||||
"* *",
|
||||
" * * ",
|
||||
" * ",
|
||||
" * ",
|
||||
" * ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"z",
|
||||
[
|
||||
"*****",
|
||||
" * ",
|
||||
" * ",
|
||||
" * ",
|
||||
"*****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"0",
|
||||
[
|
||||
" *** ",
|
||||
"* *",
|
||||
"* * *",
|
||||
"* *",
|
||||
" *** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"1",
|
||||
[
|
||||
" ** ",
|
||||
"* * ",
|
||||
" * ",
|
||||
" * ",
|
||||
"*****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"2",
|
||||
[
|
||||
" *** ",
|
||||
"* *",
|
||||
" * ",
|
||||
" * ",
|
||||
" ****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"3",
|
||||
[
|
||||
" *** ",
|
||||
"* *",
|
||||
" ***",
|
||||
"* *",
|
||||
" *** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"4",
|
||||
[
|
||||
"* * ",
|
||||
"* * ",
|
||||
"*****",
|
||||
" * ",
|
||||
" * ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"5",
|
||||
[
|
||||
"*****",
|
||||
"* ",
|
||||
"**** ",
|
||||
" *",
|
||||
"**** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"6",
|
||||
[
|
||||
" ****",
|
||||
"* ",
|
||||
"**** ",
|
||||
"* *",
|
||||
" *** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"7",
|
||||
[
|
||||
"*****",
|
||||
" * ",
|
||||
" * ",
|
||||
" * ",
|
||||
"* ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"8",
|
||||
[
|
||||
" *** ",
|
||||
"* *",
|
||||
" *** ",
|
||||
"* *",
|
||||
" *** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"9",
|
||||
[
|
||||
" *** ",
|
||||
"* *",
|
||||
" ****",
|
||||
" *",
|
||||
"**** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
".",
|
||||
[
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"!",
|
||||
[
|
||||
" *",
|
||||
" *",
|
||||
" *",
|
||||
" ",
|
||||
" *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
":",
|
||||
[
|
||||
" ",
|
||||
" *",
|
||||
" ",
|
||||
" *",
|
||||
" ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"<",
|
||||
[
|
||||
" **",
|
||||
" ** ",
|
||||
"* ",
|
||||
" ** ",
|
||||
" **",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
">",
|
||||
[
|
||||
"** ",
|
||||
" ** ",
|
||||
" *",
|
||||
" ** ",
|
||||
"** ",
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
SMALL_FONT = FONT.scaled(4, 2, 2)
|
||||
TINY_FONT = FONT.scaled(2, 2, 2)
|
||||
# The actual font data is long, so I put it at the end
|
||||
FONT = LazyVariable(lambda: Font(6, 3, 3, GLYPH_DATA))
|
||||
SMALL_FONT = LazyVariable(lambda: Game.FONT.scaled(4, 2, 2))
|
||||
TINY_FONT = LazyVariable(lambda: Game.FONT.scaled(2, 2, 2))
|
||||
CONTROL_DISPLAY_BORDER = 5
|
||||
INFO_BOX_BORDER_SIZE = 5
|
||||
HELP_MENU_INSET = 10
|
||||
@@ -1006,6 +604,9 @@ class Game:
|
||||
self.move_current_piece(Direction.LEFT)
|
||||
case Action.Type.MOVE_RIGHT:
|
||||
self.move_current_piece(Direction.RIGHT)
|
||||
case Action.Type.RESTART:
|
||||
self.start_new_game()
|
||||
self.pending_actions = []
|
||||
|
||||
def place_piece(self, x: int, y: int, piece: Tetromino):
|
||||
self.score += Game.PLACE_POINTS
|
||||
@@ -1376,6 +977,430 @@ class Game:
|
||||
self.loop()
|
||||
|
||||
|
||||
GLYPH_DATA = [
|
||||
Font.Glyph(
|
||||
" ",
|
||||
[
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"a",
|
||||
[
|
||||
"*****",
|
||||
"* *",
|
||||
"*****",
|
||||
"* *",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"b",
|
||||
[
|
||||
"**** ",
|
||||
"* *",
|
||||
"*****",
|
||||
"* *",
|
||||
"**** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"c",
|
||||
[
|
||||
"*****",
|
||||
"* *",
|
||||
"* ",
|
||||
"* *",
|
||||
"*****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"d",
|
||||
[
|
||||
"**** ",
|
||||
"* *",
|
||||
"* *",
|
||||
"* *",
|
||||
"**** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"e",
|
||||
[
|
||||
"*****",
|
||||
"* ",
|
||||
"**** ",
|
||||
"* ",
|
||||
"*****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"f",
|
||||
[
|
||||
"*****",
|
||||
"* ",
|
||||
"**** ",
|
||||
"* ",
|
||||
"* ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"g",
|
||||
[
|
||||
"*****",
|
||||
"* ",
|
||||
"* **",
|
||||
"* *",
|
||||
"*****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"h",
|
||||
[
|
||||
"* *",
|
||||
"* *",
|
||||
"*****",
|
||||
"* *",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"i",
|
||||
[
|
||||
"*****",
|
||||
" * ",
|
||||
" * ",
|
||||
" * ",
|
||||
"*****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"j",
|
||||
[
|
||||
"*****",
|
||||
" * ",
|
||||
" * ",
|
||||
"* * ",
|
||||
" ** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"k",
|
||||
[
|
||||
"* *",
|
||||
"* * ",
|
||||
"*** ",
|
||||
"* * ",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"l",
|
||||
[
|
||||
"* ",
|
||||
"* ",
|
||||
"* ",
|
||||
"* ",
|
||||
"*****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"m",
|
||||
[
|
||||
"* *",
|
||||
"** **",
|
||||
"* * *",
|
||||
"* *",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"n",
|
||||
[
|
||||
"* *",
|
||||
"** *",
|
||||
"* * *",
|
||||
"* **",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"o",
|
||||
[
|
||||
" *** ",
|
||||
"* *",
|
||||
"* *",
|
||||
"* *",
|
||||
" *** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"p",
|
||||
[
|
||||
"**** ",
|
||||
"* *",
|
||||
"**** ",
|
||||
"* ",
|
||||
"* ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"q",
|
||||
[
|
||||
" *** ",
|
||||
"* *",
|
||||
"* * *",
|
||||
"* * ",
|
||||
" ** *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"r",
|
||||
[
|
||||
"**** ",
|
||||
"* *",
|
||||
"**** ",
|
||||
"* * ",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"s",
|
||||
[
|
||||
" ****",
|
||||
"* ",
|
||||
" *** ",
|
||||
" *",
|
||||
"**** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"t",
|
||||
[
|
||||
"*****",
|
||||
" * ",
|
||||
" * ",
|
||||
" * ",
|
||||
" * ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"u",
|
||||
[
|
||||
"* *",
|
||||
"* *",
|
||||
"* *",
|
||||
"* *",
|
||||
" *** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"v",
|
||||
[
|
||||
"* *",
|
||||
"* *",
|
||||
"* *",
|
||||
" * * ",
|
||||
" * ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"w",
|
||||
[
|
||||
"* *",
|
||||
"* *",
|
||||
"* * *",
|
||||
"** **",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"x",
|
||||
[
|
||||
"* *",
|
||||
" * * ",
|
||||
" * ",
|
||||
" * * ",
|
||||
"* *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"y",
|
||||
[
|
||||
"* *",
|
||||
" * * ",
|
||||
" * ",
|
||||
" * ",
|
||||
" * ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"z",
|
||||
[
|
||||
"*****",
|
||||
" * ",
|
||||
" * ",
|
||||
" * ",
|
||||
"*****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"0",
|
||||
[
|
||||
" *** ",
|
||||
"* *",
|
||||
"* * *",
|
||||
"* *",
|
||||
" *** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"1",
|
||||
[
|
||||
" ** ",
|
||||
"* * ",
|
||||
" * ",
|
||||
" * ",
|
||||
"*****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"2",
|
||||
[
|
||||
" *** ",
|
||||
"* *",
|
||||
" * ",
|
||||
" * ",
|
||||
" ****",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"3",
|
||||
[
|
||||
" *** ",
|
||||
"* *",
|
||||
" ***",
|
||||
"* *",
|
||||
" *** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"4",
|
||||
[
|
||||
"* * ",
|
||||
"* * ",
|
||||
"*****",
|
||||
" * ",
|
||||
" * ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"5",
|
||||
[
|
||||
"*****",
|
||||
"* ",
|
||||
"**** ",
|
||||
" *",
|
||||
"**** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"6",
|
||||
[
|
||||
" ****",
|
||||
"* ",
|
||||
"**** ",
|
||||
"* *",
|
||||
" *** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"7",
|
||||
[
|
||||
"*****",
|
||||
" * ",
|
||||
" * ",
|
||||
" * ",
|
||||
"* ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"8",
|
||||
[
|
||||
" *** ",
|
||||
"* *",
|
||||
" *** ",
|
||||
"* *",
|
||||
" *** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"9",
|
||||
[
|
||||
" *** ",
|
||||
"* *",
|
||||
" ****",
|
||||
" *",
|
||||
"**** ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
".",
|
||||
[
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"!",
|
||||
[
|
||||
" *",
|
||||
" *",
|
||||
" *",
|
||||
" ",
|
||||
" *",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
":",
|
||||
[
|
||||
" ",
|
||||
" *",
|
||||
" ",
|
||||
" *",
|
||||
" ",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
"<",
|
||||
[
|
||||
" **",
|
||||
" ** ",
|
||||
"* ",
|
||||
" ** ",
|
||||
" **",
|
||||
],
|
||||
),
|
||||
Font.Glyph(
|
||||
">",
|
||||
[
|
||||
"** ",
|
||||
" ** ",
|
||||
" *",
|
||||
" ** ",
|
||||
"** ",
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
game = Game()
|
||||
game.run()
|
||||
|
||||
Reference in New Issue
Block a user