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 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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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"
|
|
||||||
|
|
Loading…
Reference in a new issue