mirror of
https://github.com/kristoferssolo/Tetris.git
synced 2025-10-21 20:00:35 +00:00
feat(game): movemnt keys from file
This commit is contained in:
parent
f1e854a38c
commit
8e3ed493e0
@ -1,21 +1,20 @@
|
|||||||
[keybinds]
|
[General]
|
||||||
rotate_colockwise = "up arrow"
|
pause = ["esc", "F1"]
|
||||||
hard_drop = "space"
|
quit = ["q"]
|
||||||
hold = "shift+c"
|
|
||||||
rotate_counter_colockwise = "ctrl+z"
|
|
||||||
pause = "esc+F1"
|
|
||||||
move_left = "left arrow"
|
|
||||||
move_right = "right arrow"
|
|
||||||
move_down = "down arrow"
|
|
||||||
|
|
||||||
[numpad]
|
[Movement]
|
||||||
hold = "numpad 0"
|
left = ["left", "kp4"]
|
||||||
hard_drop = "numpad 5"
|
right = ["right", "kp6"]
|
||||||
move_left = "numpad 4"
|
down = ["down", "kp2"]
|
||||||
move_right = "numpad 6"
|
|
||||||
soft_drop = "numpad 2"
|
[Rotation]
|
||||||
rotate_colockwise_1 = "numpad 1"
|
cw = ["x", "up", "kp1", "kp5", "kp9"] # clockwise
|
||||||
rotate_colockwise_2 = "numpad 5"
|
ccw = ["ctrl", "z", "kp3", "kp7"] # counter-clockwise
|
||||||
rotate_colockwise_3 = "numpad 9"
|
|
||||||
rotate_counter_colockwise_1 = "numpad 3"
|
[Action]
|
||||||
rotate_counter_colockwise_2 = "numpad 7"
|
hold = ["shift", "c", "kp0"]
|
||||||
|
drop = ["space", "kp5"]
|
||||||
|
|
||||||
|
[Sound]
|
||||||
|
music = true
|
||||||
|
volume = 0.5
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import sys
|
from typing import Any
|
||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
from utils import CONFIG, Figure, GameMode
|
from utils import CONFIG, Figure, GameMode
|
||||||
@ -27,8 +27,9 @@ class Game(BaseScreen):
|
|||||||
music: Music that plays in the background.
|
music: Music that plays in the background.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, game_mode: GameMode) -> None:
|
def __init__(self, game_mode: GameMode, settings: dict[str, Any]) -> None:
|
||||||
self.game_mode = game_mode
|
self.game_mode = game_mode
|
||||||
|
self.settings = settings
|
||||||
self._initialize_game_components()
|
self._initialize_game_components()
|
||||||
self._start_background_music()
|
self._start_background_music()
|
||||||
|
|
||||||
@ -60,7 +61,9 @@ class Game(BaseScreen):
|
|||||||
self.clock = pygame.time.Clock()
|
self.clock = pygame.time.Clock()
|
||||||
self.next_figure: Figure = self._generate_next_figure()
|
self.next_figure: Figure = self._generate_next_figure()
|
||||||
|
|
||||||
self.tetris = Tetris(self._get_next_figure, self._update_score, self.game_mode)
|
self.tetris = Tetris(
|
||||||
|
self._get_next_figure, self._update_score, self.game_mode, self.settings
|
||||||
|
)
|
||||||
self.score = Score(self.game_mode)
|
self.score = Score(self.game_mode)
|
||||||
self.preview = Preview()
|
self.preview = Preview()
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import sys
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
from utils import CONFIG, GameMode
|
from utils import CONFIG, PYGAME_EVENT, GameMode, read_settings
|
||||||
|
|
||||||
from game.log import log
|
from game.log import log
|
||||||
|
|
||||||
@ -13,13 +13,14 @@ from .game import Game
|
|||||||
|
|
||||||
class Main(BaseScreen, SceenElement, TextScreen):
|
class Main(BaseScreen, SceenElement, TextScreen):
|
||||||
def __init__(self, mode: GameMode) -> None:
|
def __init__(self, mode: GameMode) -> None:
|
||||||
# log.info("Initializing the game")
|
log.info("Initializing the game")
|
||||||
self._initialize_pygame()
|
self._initialize_pygame()
|
||||||
self._initialize_surface()
|
self._initialize_surface()
|
||||||
self._initialize_rect()
|
self._initialize_rect()
|
||||||
self._initialize_font()
|
self._initialize_font()
|
||||||
self._set_buttons()
|
self._set_buttons()
|
||||||
self._initialize_increment_height()
|
self._initialize_increment_height()
|
||||||
|
self.settings = read_settings()
|
||||||
self.game_mode = mode
|
self.game_mode = mode
|
||||||
self.game: Optional[Game] = None
|
self.game: Optional[Game] = None
|
||||||
|
|
||||||
@ -36,7 +37,9 @@ class Main(BaseScreen, SceenElement, TextScreen):
|
|||||||
if event.type == pygame.QUIT:
|
if event.type == pygame.QUIT:
|
||||||
self.exit()
|
self.exit()
|
||||||
elif event.type == pygame.KEYDOWN:
|
elif event.type == pygame.KEYDOWN:
|
||||||
if event.key == pygame.K_q:
|
if event.key in [
|
||||||
|
PYGAME_EVENT[key] for key in self.settings["General"]["quit"]
|
||||||
|
]:
|
||||||
self.exit()
|
self.exit()
|
||||||
|
|
||||||
if not self.game:
|
if not self.game:
|
||||||
@ -61,13 +64,13 @@ class Main(BaseScreen, SceenElement, TextScreen):
|
|||||||
|
|
||||||
def exit(self) -> None:
|
def exit(self) -> None:
|
||||||
"""Exit the game."""
|
"""Exit the game."""
|
||||||
# log.info("Exiting the game")
|
log.info("Exiting the game")
|
||||||
pygame.quit()
|
pygame.quit()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
def play(self) -> "Main":
|
def play(self) -> "Main":
|
||||||
self._draw_background()
|
self._draw_background()
|
||||||
self.game = Game(self.game_mode)
|
self.game = Game(self.game_mode, self.settings)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _set_buttons(self) -> None:
|
def _set_buttons(self) -> None:
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from typing import Any, Callable, Optional
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pygame
|
import pygame
|
||||||
from utils import CONFIG, Direction, Figure, GameMode, Rotation
|
from utils import CONFIG, PYGAME_EVENT, Direction, Figure, GameMode, Rotation
|
||||||
|
|
||||||
from game.log import log
|
from game.log import log
|
||||||
from game.sprites import Block, Tetromino
|
from game.sprites import Block, Tetromino
|
||||||
@ -45,10 +45,12 @@ class Tetris(BaseScreen):
|
|||||||
get_next_figure: Callable[[], Figure],
|
get_next_figure: Callable[[], Figure],
|
||||||
update_score: Callable[[int, int, int], None],
|
update_score: Callable[[int, int, int], None],
|
||||||
game_mode: GameMode,
|
game_mode: GameMode,
|
||||||
|
settings: dict[str, Any],
|
||||||
) -> None:
|
) -> None:
|
||||||
self._initialize_surface()
|
self._initialize_surface()
|
||||||
self._initialize_rect()
|
self._initialize_rect()
|
||||||
self._initialize_sprites()
|
self._initialize_sprites()
|
||||||
|
self.settings = settings
|
||||||
|
|
||||||
self.get_next_figure = get_next_figure
|
self.get_next_figure = get_next_figure
|
||||||
self.update_score = update_score
|
self.update_score = update_score
|
||||||
@ -150,8 +152,8 @@ class Tetris(BaseScreen):
|
|||||||
self._check_finished_rows()
|
self._check_finished_rows()
|
||||||
|
|
||||||
self.game_over: bool = self._check_game_over()
|
self.game_over: bool = self._check_game_over()
|
||||||
# if self.game_over:
|
if self.game_over:
|
||||||
# self.restart()
|
self.restart()
|
||||||
|
|
||||||
self.tetromino = Tetromino(
|
self.tetromino = Tetromino(
|
||||||
self.sprites,
|
self.sprites,
|
||||||
@ -171,13 +173,13 @@ class Tetris(BaseScreen):
|
|||||||
"""
|
"""
|
||||||
for block in self.tetromino.blocks:
|
for block in self.tetromino.blocks:
|
||||||
if block.pos.y <= 0:
|
if block.pos.y <= 0:
|
||||||
# log.info("Game over!")
|
log.info("Game over!")
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def restart(self) -> None:
|
def restart(self) -> None:
|
||||||
"""Restart the game."""
|
"""Restart the game."""
|
||||||
# log.info("Restarting the game")
|
log.info("Restarting the game")
|
||||||
self._reset_game_state()
|
self._reset_game_state()
|
||||||
self._initialize_field_and_tetromino()
|
self._initialize_field_and_tetromino()
|
||||||
self.game_over = False
|
self.game_over = False
|
||||||
@ -356,17 +358,19 @@ class Tetris(BaseScreen):
|
|||||||
"""
|
"""
|
||||||
Handle movement keys.
|
Handle movement keys.
|
||||||
|
|
||||||
Move right [K_d, K_l].
|
See `settings.toml` for the default key bindings.
|
||||||
Move left [K_a, K_h].
|
|
||||||
"""
|
"""
|
||||||
right_keys = keys[pygame.K_d] or keys[pygame.K_l]
|
right_keys = [PYGAME_EVENT[key] for key in self.settings["Movement"]["right"]]
|
||||||
left_keys = keys[pygame.K_a] or keys[pygame.K_h]
|
right_key_pressed = any(keys[key] for key in right_keys)
|
||||||
|
|
||||||
|
left_keys = [PYGAME_EVENT[key] for key in self.settings["Movement"]["left"]]
|
||||||
|
left_key_pressed = any(keys[key] for key in left_keys)
|
||||||
|
|
||||||
if not self.timers.horizontal.active:
|
if not self.timers.horizontal.active:
|
||||||
if left_keys:
|
if left_key_pressed:
|
||||||
self.move_left()
|
self.move_left()
|
||||||
self.timers.horizontal.activate()
|
self.timers.horizontal.activate()
|
||||||
elif right_keys:
|
elif right_key_pressed:
|
||||||
self.move_right()
|
self.move_right()
|
||||||
self.timers.horizontal.activate()
|
self.timers.horizontal.activate()
|
||||||
|
|
||||||
@ -374,46 +378,49 @@ class Tetris(BaseScreen):
|
|||||||
"""
|
"""
|
||||||
Handle rotation keys.
|
Handle rotation keys.
|
||||||
|
|
||||||
Rotation clockwise [K_RIGHT, K_UP, K_r, K_w, K_k].
|
See `settings.toml` for the default key bindings.
|
||||||
Rotation counter-clockwise [K_LEFT, K_e, K_i].
|
|
||||||
"""
|
"""
|
||||||
clockwise_keys = (
|
cw_keys = [PYGAME_EVENT[key] for key in self.settings["Rotation"]["cw"]]
|
||||||
keys[pygame.K_r]
|
cw_key_pressed = any(keys[key] for key in cw_keys)
|
||||||
or keys[pygame.K_UP]
|
|
||||||
or keys[pygame.K_w]
|
|
||||||
or keys[pygame.K_k]
|
|
||||||
or keys[pygame.K_RIGHT]
|
|
||||||
)
|
|
||||||
|
|
||||||
counter_clockwise_keys = (
|
ccw_keys = [PYGAME_EVENT[key] for key in self.settings["Rotation"]["ccw"]]
|
||||||
keys[pygame.K_e] or keys[pygame.K_i] or keys[pygame.K_LEFT]
|
ccw_key_pressed = any(keys[key] for key in ccw_keys)
|
||||||
)
|
|
||||||
|
|
||||||
if not self.timers.rotation.active:
|
if not self.timers.rotation.active:
|
||||||
if clockwise_keys:
|
if cw_key_pressed:
|
||||||
self.rotate()
|
self.rotate()
|
||||||
self.timers.rotation.activate()
|
self.timers.rotation.activate()
|
||||||
|
|
||||||
if counter_clockwise_keys:
|
if ccw_key_pressed:
|
||||||
self.rotate_reverse()
|
self.rotate_reverse()
|
||||||
self.timers.rotation.activate()
|
self.timers.rotation.activate()
|
||||||
|
|
||||||
def _handle_down_key(self, keys: pygame.key.ScancodeWrapper) -> None:
|
def _handle_down_key(self, keys: pygame.key.ScancodeWrapper) -> None:
|
||||||
"""Handle the down key [K_DOWN, K_s, K_j]."""
|
"""
|
||||||
down_keys = keys[pygame.K_DOWN] or keys[pygame.K_s] or keys[pygame.K_j]
|
Handle the down key.
|
||||||
if not self.down_pressed and down_keys:
|
|
||||||
|
See `settings.toml` for the default key bindings.
|
||||||
|
"""
|
||||||
|
down_keys = [PYGAME_EVENT[key] for key in self.settings["Movement"]["down"]]
|
||||||
|
down_key_pressed = any(keys[key] for key in down_keys)
|
||||||
|
if not self.down_pressed and down_key_pressed:
|
||||||
self.down_pressed = True
|
self.down_pressed = True
|
||||||
self.timers.vertical.duration = self.increased_block_speed
|
self.timers.vertical.duration = self.increased_block_speed
|
||||||
|
|
||||||
if self.down_pressed and not down_keys:
|
if self.down_pressed and not down_key_pressed:
|
||||||
self.down_pressed = False
|
self.down_pressed = False
|
||||||
self.timers.vertical.duration = self.initial_block_speed
|
self.timers.vertical.duration = self.initial_block_speed
|
||||||
|
|
||||||
def _handle_drop_key(self, keys: pygame.key.ScancodeWrapper) -> None:
|
def _handle_drop_key(self, keys: pygame.key.ScancodeWrapper) -> None:
|
||||||
"""Handle the drop key [K_SPACE]."""
|
"""
|
||||||
drop_keys = keys[pygame.K_SPACE]
|
Handle the drop key.
|
||||||
|
|
||||||
if not self.timers.drop.active and drop_keys:
|
See `settings.toml` for the default key bindings.
|
||||||
|
"""
|
||||||
|
drop_keys = [PYGAME_EVENT[key] for key in self.settings["Action"]["drop"]]
|
||||||
|
drop_key_pressed = any(keys[key] for key in drop_keys)
|
||||||
|
|
||||||
|
if not self.timers.drop.active and drop_key_pressed:
|
||||||
self.drop()
|
self.drop()
|
||||||
self.timers.drop.activate()
|
self.timers.drop.activate()
|
||||||
|
|
||||||
|
|||||||
@ -203,7 +203,7 @@ class Tetromino:
|
|||||||
"""
|
"""
|
||||||
return all(
|
return all(
|
||||||
0 <= pos.x < CONFIG.game.columns
|
0 <= pos.x < CONFIG.game.columns
|
||||||
and 0 <= pos.y < CONFIG.game.rows
|
and -2 <= pos.y < CONFIG.game.rows
|
||||||
and not self.field[int(pos.y), int(pos.x)]
|
and not self.field[int(pos.y), int(pos.x)]
|
||||||
for pos in new_positions
|
for pos in new_positions
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
from .config import CONFIG
|
from .config import CONFIG
|
||||||
from .enum import Direction, GameMode, Rotation
|
from .enum import Direction, GameMode, Rotation
|
||||||
|
from .events import PYGAME_EVENT
|
||||||
from .figure import Figure, FigureConfig
|
from .figure import Figure, FigureConfig
|
||||||
from .log import log
|
from .log import log
|
||||||
from .path import BASE_PATH
|
from .path import BASE_PATH
|
||||||
from .settings import read_settings, save_settings
|
from .settings import read_settings, save_settings
|
||||||
from .tuples import BestMove, Size
|
from .tuples import Size
|
||||||
from .weights import Weights
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"BASE_PATH",
|
"BASE_PATH",
|
||||||
@ -17,8 +17,7 @@ __all__ = [
|
|||||||
"Direction",
|
"Direction",
|
||||||
"Rotation",
|
"Rotation",
|
||||||
"GameMode",
|
"GameMode",
|
||||||
"Weights",
|
|
||||||
"BestMove",
|
|
||||||
"read_settings",
|
"read_settings",
|
||||||
"save_settings",
|
"save_settings",
|
||||||
|
"PYGAME_EVENT",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -21,7 +21,7 @@ class Game:
|
|||||||
size: Size = Size(columns * cell.width, rows * cell.width)
|
size: Size = Size(columns * cell.width, rows * cell.width)
|
||||||
pos: Vec2 = Vec2(padding, padding)
|
pos: Vec2 = Vec2(padding, padding)
|
||||||
offset: Vec2 = Vec2(columns // 2, -1)
|
offset: Vec2 = Vec2(columns // 2, -1)
|
||||||
initial_speed: float | int = 100
|
initial_speed: float | int = 300
|
||||||
movment_delay: int = 150
|
movment_delay: int = 150
|
||||||
rotation_delay: int = 200
|
rotation_delay: int = 200
|
||||||
drop_delay: int = 200
|
drop_delay: int = 200
|
||||||
|
|||||||
94
src/utils/events.py
Normal file
94
src/utils/events.py
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import pygame
|
||||||
|
|
||||||
|
PYGAME_EVENT: dict[str, int] = {
|
||||||
|
"up": pygame.K_UP,
|
||||||
|
"down": pygame.K_DOWN,
|
||||||
|
"left": pygame.K_LEFT,
|
||||||
|
"right": pygame.K_RIGHT,
|
||||||
|
"space": pygame.K_SPACE,
|
||||||
|
"escape": pygame.K_ESCAPE,
|
||||||
|
"q": pygame.K_q,
|
||||||
|
"w": pygame.K_w,
|
||||||
|
"e": pygame.K_e,
|
||||||
|
"r": pygame.K_r,
|
||||||
|
"t": pygame.K_t,
|
||||||
|
"y": pygame.K_y,
|
||||||
|
"u": pygame.K_u,
|
||||||
|
"i": pygame.K_i,
|
||||||
|
"o": pygame.K_o,
|
||||||
|
"p": pygame.K_p,
|
||||||
|
"a": pygame.K_a,
|
||||||
|
"s": pygame.K_s,
|
||||||
|
"d": pygame.K_d,
|
||||||
|
"f": pygame.K_f,
|
||||||
|
"g": pygame.K_g,
|
||||||
|
"h": pygame.K_h,
|
||||||
|
"j": pygame.K_j,
|
||||||
|
"k": pygame.K_k,
|
||||||
|
"l": pygame.K_l,
|
||||||
|
"z": pygame.K_z,
|
||||||
|
"x": pygame.K_x,
|
||||||
|
"c": pygame.K_c,
|
||||||
|
"v": pygame.K_v,
|
||||||
|
"b": pygame.K_b,
|
||||||
|
"n": pygame.K_n,
|
||||||
|
"m": pygame.K_m,
|
||||||
|
"1": pygame.K_1,
|
||||||
|
"2": pygame.K_2,
|
||||||
|
"3": pygame.K_3,
|
||||||
|
"4": pygame.K_4,
|
||||||
|
"5": pygame.K_5,
|
||||||
|
"6": pygame.K_6,
|
||||||
|
"7": pygame.K_7,
|
||||||
|
"8": pygame.K_8,
|
||||||
|
"9": pygame.K_9,
|
||||||
|
"0": pygame.K_0,
|
||||||
|
"shift": pygame.K_LSHIFT,
|
||||||
|
"ctrl": pygame.K_LCTRL,
|
||||||
|
"alt": pygame.K_LALT,
|
||||||
|
"tab": pygame.K_TAB,
|
||||||
|
"capslock": pygame.K_CAPSLOCK,
|
||||||
|
"return": pygame.K_RETURN,
|
||||||
|
"backspace": pygame.K_BACKSPACE,
|
||||||
|
"insert": pygame.K_INSERT,
|
||||||
|
"delete": pygame.K_DELETE,
|
||||||
|
"home": pygame.K_HOME,
|
||||||
|
"end": pygame.K_END,
|
||||||
|
"pageup": pygame.K_PAGEUP,
|
||||||
|
"pagedown": pygame.K_PAGEDOWN,
|
||||||
|
"numlock": pygame.K_NUMLOCK,
|
||||||
|
"printscreen": pygame.K_PRINTSCREEN,
|
||||||
|
"scrolllock": pygame.K_SCROLLLOCK,
|
||||||
|
"pause": pygame.K_PAUSE,
|
||||||
|
"F1": pygame.K_F1,
|
||||||
|
"F2": pygame.K_F2,
|
||||||
|
"F3": pygame.K_F3,
|
||||||
|
"F4": pygame.K_F4,
|
||||||
|
"F5": pygame.K_F5,
|
||||||
|
"F6": pygame.K_F6,
|
||||||
|
"F7": pygame.K_F7,
|
||||||
|
"F8": pygame.K_F8,
|
||||||
|
"F9": pygame.K_F9,
|
||||||
|
"F10": pygame.K_F10,
|
||||||
|
"F11": pygame.K_F11,
|
||||||
|
"F12": pygame.K_F12,
|
||||||
|
"F13": pygame.K_F13,
|
||||||
|
"F14": pygame.K_F14,
|
||||||
|
"F15": pygame.K_F15,
|
||||||
|
"kp0": pygame.K_KP0,
|
||||||
|
"kp1": pygame.K_KP1,
|
||||||
|
"kp2": pygame.K_KP2,
|
||||||
|
"kp3": pygame.K_KP3,
|
||||||
|
"kp4": pygame.K_KP4,
|
||||||
|
"kp5": pygame.K_KP5,
|
||||||
|
"kp6": pygame.K_KP6,
|
||||||
|
"kp7": pygame.K_KP7,
|
||||||
|
"kp8": pygame.K_KP8,
|
||||||
|
"kp9": pygame.K_KP9,
|
||||||
|
"kp_divide": pygame.K_KP_DIVIDE,
|
||||||
|
"kp_multiply": pygame.K_KP_MULTIPLY,
|
||||||
|
"kp_minus": pygame.K_KP_MINUS,
|
||||||
|
"kp_plus": pygame.K_KP_PLUS,
|
||||||
|
"kp_enter": pygame.K_KP_ENTER,
|
||||||
|
"kp_equals": pygame.K_KP_EQUALS,
|
||||||
|
}
|
||||||
@ -1,10 +1,11 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Any, Optional
|
||||||
|
|
||||||
import toml
|
import toml
|
||||||
|
|
||||||
from .config import CONFIG, Config
|
from .config import CONFIG, Config
|
||||||
from .log import log
|
from .log import log
|
||||||
|
from .path import BASE_PATH
|
||||||
|
|
||||||
|
|
||||||
def save_settings(settings: Config, file_path: Path) -> None:
|
def save_settings(settings: Config, file_path: Path) -> None:
|
||||||
@ -12,7 +13,9 @@ def save_settings(settings: Config, file_path: Path) -> None:
|
|||||||
toml.dump(settings, file)
|
toml.dump(settings, file)
|
||||||
|
|
||||||
|
|
||||||
def read_settings(file_path: Path) -> Optional[dict[str, str]]:
|
def read_settings(
|
||||||
|
file_path: Path = BASE_PATH / "settings.toml",
|
||||||
|
) -> dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Read and parse a TOML file and return the content as a dictionary.
|
Read and parse a TOML file and return the content as a dictionary.
|
||||||
|
|
||||||
@ -27,7 +30,7 @@ def read_settings(file_path: Path) -> Optional[dict[str, str]]:
|
|||||||
return toml.load(file)
|
return toml.load(file)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
log.error(f"Error: The file '{file_path}' does not exist.")
|
log.error(f"Error: The file '{file_path}' does not exist.")
|
||||||
return None
|
return {}
|
||||||
except toml.TomlDecodeError as e:
|
except toml.TomlDecodeError as e:
|
||||||
log.error(f"rror decoding TOML file: {e}")
|
log.error(f"rror decoding TOML file: {e}")
|
||||||
return None
|
return {}
|
||||||
|
|||||||
@ -11,8 +11,3 @@ class Size(NamedTuple):
|
|||||||
if isinstance(other, Size):
|
if isinstance(other, Size):
|
||||||
return Size(self.width - other.width, self.height - other.height)
|
return Size(self.width - other.width, self.height - other.height)
|
||||||
return Size(self.width - other, self.height - other)
|
return Size(self.width - other, self.height - other)
|
||||||
|
|
||||||
|
|
||||||
class BestMove(NamedTuple):
|
|
||||||
rotation: int
|
|
||||||
x: int
|
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
from attrs import define
|
|
||||||
|
|
||||||
|
|
||||||
@define
|
|
||||||
class Weights:
|
|
||||||
height: float
|
|
||||||
lines: float
|
|
||||||
holes: float
|
|
||||||
bumpiness: float
|
|
||||||
Loading…
Reference in New Issue
Block a user