working Board.click()

This commit is contained in:
Jörn-Michael Miehe 2023-08-18 22:35:10 +00:00
parent 85d275f04b
commit f8dadca9a8
3 changed files with 51 additions and 15 deletions

View file

@ -1,5 +1,7 @@
from dataclasses import dataclass from dataclasses import dataclass
from .helpers import rotate_r
@dataclass(kw_only=True, slots=True) @dataclass(kw_only=True, slots=True)
class Board: class Board:
@ -25,6 +27,9 @@ class Board:
else: else:
return len(self.rows[0]) return len(self.rows[0])
def __len__(self) -> int:
return self.height * self.width
def __post_init__(self) -> None: def __post_init__(self) -> None:
# check char set # check char set
chars = {c for c in "".join(self.rows)} chars = {c for c in "".join(self.rows)}
@ -37,9 +42,8 @@ class Board:
), "Inconsistent width!" ), "Inconsistent width!"
# check buttons # check buttons
length = self.height * self.width
assert all( assert all(
button in range(length) button in range(len(self))
for button in self.buttons for button in self.buttons
), "Invalid buttons!" ), "Invalid buttons!"
@ -72,16 +76,36 @@ class Board:
for column in self.columns for column in self.columns
) )
def __idx_to_xy(self, index: int) -> tuple[int, int]: def __getitem__(self, key: tuple[int, int]) -> str:
return index % self.width, index // self.width row, col = key
def is_clickable(self, index: int) -> bool: if row not in range(self.height) or col not in range(self.width):
# check index return "x"
assert index in self.buttons, f"{index} is not a button!"
# check is button return self.rows[row][col]
x, y = self.__idx_to_xy(index)
return self.rows[y][x] == "1" def __setitem__(self, key: tuple[int, int], value: str):
row, col = key
if row not in range(self.height) or col not in range(self.width):
return
old_row = self.rows[row]
self.rows[row] = old_row[:col] + value + old_row[col+1:]
def click(self, index: int) -> None: def click(self, index: int) -> None:
assert self.is_clickable(index), f"{index} is not clickable!" # check is clickable
row, col = index // self.width, index % self.width
assert self.rows[row][col] == "1", f"{index} is not clickable!"
nb_rc = [
(row - 1, col),
(row, col + 1),
(row + 1, col),
(row, col - 1),
]
nb_str = "".join(self[*rc] for rc in nb_rc)
for rc, val in zip(nb_rc, rotate_r(nb_str)):
self[rc] = val

View file

@ -5,7 +5,18 @@ from .board import Board
def main() -> None: def main() -> None:
board = Board.default_puzzle board = Board.default_puzzle
print(board)
print()
board.click(2) # not a button!
print(board)
print()
board.click(4)
print(board)
print()
board.click(5)
print(board) print(board)

View file

@ -1,3 +1,5 @@
import pytest
from pigeon_magnet_solver.board import Board from pigeon_magnet_solver.board import Board
@ -11,7 +13,6 @@ def test_default():
assert board.binary_repr == (4, 11, 3), "Wrong binary repr" assert board.binary_repr == (4, 11, 3), "Wrong binary repr"
assert board.solution_class == (1, 3, 2), "Wrong solution class" assert board.solution_class == (1, 3, 2), "Wrong solution class"
assert board.is_clickable(3) is False, "Button 3 should be inactive" for idx in (3, 7):
assert board.is_clickable(4) is True, "Button 4 should be active" with pytest.raises(AssertionError):
assert board.is_clickable(5) is True, "Button 5 should be active" board.click(idx)
assert board.is_clickable(7) is False, "Button 7 should be inactive"