working Board.click()
This commit is contained in:
parent
85d275f04b
commit
f8dadca9a8
3 changed files with 51 additions and 15 deletions
|
@ -1,5 +1,7 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
from .helpers import rotate_r
|
||||
|
||||
|
||||
@dataclass(kw_only=True, slots=True)
|
||||
class Board:
|
||||
|
@ -25,6 +27,9 @@ class Board:
|
|||
else:
|
||||
return len(self.rows[0])
|
||||
|
||||
def __len__(self) -> int:
|
||||
return self.height * self.width
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
# check char set
|
||||
chars = {c for c in "".join(self.rows)}
|
||||
|
@ -37,9 +42,8 @@ class Board:
|
|||
), "Inconsistent width!"
|
||||
|
||||
# check buttons
|
||||
length = self.height * self.width
|
||||
assert all(
|
||||
button in range(length)
|
||||
button in range(len(self))
|
||||
for button in self.buttons
|
||||
), "Invalid buttons!"
|
||||
|
||||
|
@ -72,16 +76,36 @@ class Board:
|
|||
for column in self.columns
|
||||
)
|
||||
|
||||
def __idx_to_xy(self, index: int) -> tuple[int, int]:
|
||||
return index % self.width, index // self.width
|
||||
def __getitem__(self, key: tuple[int, int]) -> str:
|
||||
row, col = key
|
||||
|
||||
def is_clickable(self, index: int) -> bool:
|
||||
# check index
|
||||
assert index in self.buttons, f"{index} is not a button!"
|
||||
if row not in range(self.height) or col not in range(self.width):
|
||||
return "x"
|
||||
|
||||
# check is button
|
||||
x, y = self.__idx_to_xy(index)
|
||||
return self.rows[y][x] == "1"
|
||||
return self.rows[row][col]
|
||||
|
||||
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:
|
||||
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
|
||||
|
|
|
@ -5,7 +5,18 @@ from .board import Board
|
|||
|
||||
def main() -> None:
|
||||
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)
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import pytest
|
||||
|
||||
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.solution_class == (1, 3, 2), "Wrong solution class"
|
||||
|
||||
assert board.is_clickable(3) is False, "Button 3 should be inactive"
|
||||
assert board.is_clickable(4) is True, "Button 4 should be active"
|
||||
assert board.is_clickable(5) is True, "Button 5 should be active"
|
||||
assert board.is_clickable(7) is False, "Button 7 should be inactive"
|
||||
for idx in (3, 7):
|
||||
with pytest.raises(AssertionError):
|
||||
board.click(idx)
|
||||
|
|
Loading…
Reference in a new issue