hysteris for move detection

This commit is contained in:
Thomas Lindner 2022-12-30 00:15:41 +01:00
parent 8027f3f537
commit 3b005ad506

View file

@ -3,6 +3,7 @@ import RPi.GPIO as gpio
class BoardReader: class BoardReader:
hysteresis = 10
default_gpio_mode = gpio.BCM default_gpio_mode = gpio.BCM
default_row_gpios = [4, 5, 6, 12, 13, 16, 17, 19] default_row_gpios = [4, 5, 6, 12, 13, 16, 17, 19]
default_column_gpios = [20, 21, 22, 23, 24, 25, 26, 27] default_column_gpios = [20, 21, 22, 23, 24, 25, 26, 27]
@ -10,16 +11,18 @@ class BoardReader:
def __init__( def __init__(
self, self,
move_generator: MoveGenerator, move_generator: MoveGenerator,
rows: list[int] = default_row_gpios, row_gpios: list[int] = default_row_gpios,
columns: list[int] = default_column_gpios, column_gpios: list[int] = default_column_gpios,
gpio_mode=default_gpio_mode, gpio_mode=default_gpio_mode,
): ):
gpio.setmode(gpio_mode) gpio.setmode(gpio_mode)
gpio.setup(columns, gpio.IN, pull_up_down=gpio.PUD_DOWN) gpio.setup(column_gpios, gpio.IN, pull_up_down=gpio.PUD_DOWN)
gpio.setup(rows, gpio.OUT, initial=gpio.LOW) gpio.setup(row_gpios, gpio.OUT, initial=gpio.LOW)
self.columns = columns self.column_gpios = column_gpios
self.rows = rows self.row_gpios = row_gpios
self.board = self._empty_board() self.board_history: list[list[list[str]]] = []
for _ in range(self.hysteresis):
self.board_history.append(self._empty_board())
self.move_generator = move_generator self.move_generator = move_generator
def __del__(self): def __del__(self):
@ -50,30 +53,46 @@ class BoardReader:
return True return True
def scan(self) -> None: def scan(self) -> None:
board = self._initial_board() next_board = self._empty_board()
for i, row_gpio in enumerate(self.rows): for i, row_gpio in enumerate(self.row_gpios):
gpio.output(row_gpio, gpio.HIGH) gpio.output(row_gpio, gpio.HIGH)
for j, column_gpio in enumerate(self.columns): for j, column_gpio in enumerate(self.column_gpios):
if gpio.input(column_gpio): if gpio.input(column_gpio):
board[i][j] = "x" next_board[i][j] = "x"
else:
board[i][j] = " "
gpio.output(row_gpio, gpio.LOW) gpio.output(row_gpio, gpio.LOW)
prev_board = self.board_history[-1]
self.board_history = [next_board] + self.board_history[:-1]
if not self._is_initial_board(self.board) and self._is_initial_board(board): # if the oldest board is not in inital position but all newer boards are, reset
self.move_generator.reset() # game state
self.board = board if not self._is_initial_board(prev_board):
return for board in self.board_history:
if not self._is_initial_board(board):
break
else:
self.move_generator.reset()
return
for i, row in enumerate(board): for i, row in enumerate(prev_board):
for j, field in enumerate(row): for j, field in enumerate(row):
if field == " " and self.board[i][j] == "x": # if the oldest board has a piece but no newer boards have it, the
self.move_generator.take(i, j) # piece was removed
for i, row in enumerate(board): if field == "x":
for board in self.board_history:
if board[i][j] == "x":
break
else:
self.move_generator.take(i, j)
for i, row in enumerate(prev_board):
for j, field in enumerate(row): for j, field in enumerate(row):
if field == "x" and self.board[i][j] == " ": # if the oldest board doesn't have a piece but all newer boards have
self.move_generator.put(i, j) # it, the piece was placed
self.board = board if field == " ":
for board in self.board_history:
if board[i][j] == " ":
break
else:
self.move_generator.put(i, j)
def _print(self, board) -> None: def _print(self, board) -> None:
print(" a b c d e f g h") print(" a b c d e f g h")
@ -90,4 +109,4 @@ class BoardReader:
print(" a b c d e f g h") print(" a b c d e f g h")
def print(self) -> None: def print(self) -> None:
self._print(self.board) self._print(self.board_history[0])