diff options
-rw-r--r-- | .github/workflows/auto.yml | 2 | ||||
-rw-r--r-- | board/board.py | 112 | ||||
-rw-r--r-- | tests/test_board.py | 30 |
3 files changed, 143 insertions, 1 deletions
diff --git a/.github/workflows/auto.yml b/.github/workflows/auto.yml index 81b0ab0..d4c744b 100644 --- a/.github/workflows/auto.yml +++ b/.github/workflows/auto.yml @@ -35,4 +35,4 @@ jobs: # Run unittests - name: Run unittests - run: poetry run pytest -v + run: poetry run python3 -m pytest -v diff --git a/board/board.py b/board/board.py new file mode 100644 index 0000000..e457a1a --- /dev/null +++ b/board/board.py @@ -0,0 +1,112 @@ +from random import randrange +from sys import stderr +from copy import deepcopy + +class Board(): + def __init__(self, size = 10): + self.size = size + self.tiles = [] + self.masked = [] + self.initialize_tiles( size ) + self.randomize_bombs( size ) + self.calculate_neighbours() + + def initialize_tiles(self, size): + self.tiles = [[0 for _ in range(size)] for _ in range(size)] + self.masked = [[10 for _ in range(size)] for _ in range(size)] + + def randomize_bombs(self, bomb_count): + for _ in range(bomb_count): + while True: + x, y = randrange(0,self.size), randrange(0,self.size) + if self.tiles[x][y] != 0: + continue + self.tiles[x][y]=9 + break + + def calculate_neighbours(self): + neighbours = ( (-1,-1), (0,-1), (1,-1), + (-1, 0), (1, 0), + (-1, 1), (0, 1), (1, 1) ) + for y in range(self.size): + for x in range(self.size): + if self.tiles[x][y] == 9: + continue + neighbouring_bombs = 0 + for dx,dy in neighbours: + if x+dx < 0 or x+dx >= self.size: + continue + if y+dy < 0 or y+dy >= self.size: + continue + if self.tiles[x+dx][y+dy] == 9: + neighbouring_bombs += 1 + self.tiles[x][y] = neighbouring_bombs + + def reset_guesses(self): + pass + + def get_view(self): + view = deepcopy(self.masked) + for y in range(self.size): + for x in range(self.size): + if not view[x][y]: + view[x][y]=self.tiles[x][y] + return view + + def collect_area(self, x, y, area=set()): + to_test = [] + for dx, dy in ( (0,-1), (-1,0), (1,0), (0,1) ): + if x+dx < 0 or x+dx >= self.size: + continue + if y+dy < 0 or y+dy >= self.size: + continue + if self.tiles[x+dx][y+dy] == 0 and (x+dx,y+dy) not in area: + area.add((x+dx, y+dy)) + to_test.append((x+dx, y+dy)) + for tx, ty in to_test: + area.add((x,y)) + area=area.union(self.collect_area(tx, ty, area)) + return area + + + def make_guess(self, x, y): + if x not in range(self.size) or y not in range(self.size): + print("Koordinaatit on pelilaudan ulkopuolella", file=stderr) + return False + + if self.masked[x][y] == 0: + print("Ruutu on jo avattu", file=stderr) + return False + + if self.tiles[x][y] == 9: + self.masked[x][y] = 0 + return False + + if self.tiles[x][y] == 0: + for cx, cy in self.collect_area( x, y ): + for dx, dy in ( (0,-1), (-1,0), (0,0), (1,0), (0,1) ): + if cx+dx < 0 or cx+dx >= self.size: + continue + if cy+dy < 0 or cy+dy >= self.size: + continue + self.masked[cx+dx][cy+dy] = 0 + else: + self.masked[x][y] = 0 + + return True + + + +if __name__ == "__main__": + def print_matrix(m): + for y in range(len(m)): + for x in range(len(m[0])): + print(end=f"[{m[x][y]:x}]") + print() + + b = Board() + b.make_guess(5,5) + print_matrix(b.get_view()) + + +
\ No newline at end of file diff --git a/tests/test_board.py b/tests/test_board.py new file mode 100644 index 0000000..8fa2fa3 --- /dev/null +++ b/tests/test_board.py @@ -0,0 +1,30 @@ +import unittest +from board.board import Board + +class TestBoardClass(unittest.TestCase): + def test_init(self): + b = Board() + self.assertTrue(b.size>0) + + def test_init_with_size(self): + b = Board(15) + self.assertEqual(b.size, 15) + + def test_get_view_and_make_guess(self): + b = Board(3) + b.tiles=[[0,0,0],[0,1,1],[0,1,9]] + + v = b.get_view() + t = [[10,10,10],[10,10,10],[10,10,10]] + for i in range(3): + self.assertEqual(v[i],t[i]) + + self.assertTrue(b.make_guess(0,0)) + v = b.get_view() + t = [[0,0,0],[0,1,1],[0,1,10]] + for i in range(3): + self.assertEqual(v[i],t[i]) + + self.assertFalse(b.make_guess(2,2)) + +
\ No newline at end of file |