From 3b005ad506596ca40e25cf253212ad77598d5ba7 Mon Sep 17 00:00:00 2001 From: Thomas Lindner Date: Fri, 30 Dec 2022 00:15:41 +0100 Subject: [PATCH] hysteris for move detection --- src/blunderboard/boardreader.py | 69 +++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/src/blunderboard/boardreader.py b/src/blunderboard/boardreader.py index 5eb0523..2e7258d 100644 --- a/src/blunderboard/boardreader.py +++ b/src/blunderboard/boardreader.py @@ -3,6 +3,7 @@ import RPi.GPIO as gpio class BoardReader: + hysteresis = 10 default_gpio_mode = gpio.BCM default_row_gpios = [4, 5, 6, 12, 13, 16, 17, 19] default_column_gpios = [20, 21, 22, 23, 24, 25, 26, 27] @@ -10,16 +11,18 @@ class BoardReader: def __init__( self, move_generator: MoveGenerator, - rows: list[int] = default_row_gpios, - columns: list[int] = default_column_gpios, + row_gpios: list[int] = default_row_gpios, + column_gpios: list[int] = default_column_gpios, gpio_mode=default_gpio_mode, ): gpio.setmode(gpio_mode) - gpio.setup(columns, gpio.IN, pull_up_down=gpio.PUD_DOWN) - gpio.setup(rows, gpio.OUT, initial=gpio.LOW) - self.columns = columns - self.rows = rows - self.board = self._empty_board() + gpio.setup(column_gpios, gpio.IN, pull_up_down=gpio.PUD_DOWN) + gpio.setup(row_gpios, gpio.OUT, initial=gpio.LOW) + self.column_gpios = column_gpios + self.row_gpios = row_gpios + self.board_history: list[list[list[str]]] = [] + for _ in range(self.hysteresis): + self.board_history.append(self._empty_board()) self.move_generator = move_generator def __del__(self): @@ -50,30 +53,46 @@ class BoardReader: return True def scan(self) -> None: - board = self._initial_board() - for i, row_gpio in enumerate(self.rows): + next_board = self._empty_board() + for i, row_gpio in enumerate(self.row_gpios): 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): - board[i][j] = "x" - else: - board[i][j] = " " + next_board[i][j] = "x" 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): - self.move_generator.reset() - self.board = board - return + # if the oldest board is not in inital position but all newer boards are, reset + # game state + if not self._is_initial_board(prev_board): + 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): - if field == " " and self.board[i][j] == "x": - self.move_generator.take(i, j) - for i, row in enumerate(board): + # if the oldest board has a piece but no newer boards have it, the + # piece was removed + 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): - if field == "x" and self.board[i][j] == " ": - self.move_generator.put(i, j) - self.board = board + # if the oldest board doesn't have a piece but all newer boards have + # it, the piece was placed + 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: print(" a b c d e f g h") @@ -90,4 +109,4 @@ class BoardReader: print(" a b c d e f g h") def print(self) -> None: - self._print(self.board) + self._print(self.board_history[0])