summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app.py20
-rw-r--r--board/board.py34
-rw-r--r--tui/tui.py94
3 files changed, 131 insertions, 17 deletions
diff --git a/app.py b/app.py
new file mode 100644
index 0000000..4c0c325
--- /dev/null
+++ b/app.py
@@ -0,0 +1,20 @@
+from board.board import Board
+from tui.tui import Tui
+
+b = Board()
+t = Tui()
+x, y = 0, 0
+
+while True:
+ x, y = t.matrix_selector(b.get_view(), x, y)
+ if x == -1:
+ print("LOPETUS!")
+ break
+ if not b.make_guess(x, y):
+ print("KUOLEMA!")
+ break
+ if b.is_winning():
+ print("VOITTO!")
+ break
+
+t.draw_matrix(b.get_view(),-1,-1) \ No newline at end of file
diff --git a/board/board.py b/board/board.py
index e457a1a..3b5cd77 100644
--- a/board/board.py
+++ b/board/board.py
@@ -23,6 +23,9 @@ class Board():
continue
self.tiles[x][y]=9
break
+
+ def invalid_coordinates(self, x, y):
+ return x < 0 or x >= self.size or y < 0 or y >= self.size
def calculate_neighbours(self):
neighbours = ( (-1,-1), (0,-1), (1,-1),
@@ -34,17 +37,12 @@ class Board():
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:
+ if self.invalid_coordinates(x+dx, y+dy):
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):
@@ -53,16 +51,22 @@ class Board():
view[x][y]=self.tiles[x][y]
return view
+ def is_winning(self):
+ for y in range(self.size):
+ for x in range(self.size):
+ if self.tiles[x][y] != 9 and self.masked[x][y]:
+ return False
+ return True
+
+
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:
+ if self.invalid_coordinates(x+dx, y+dy):
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))
+ area.add((x+dx, y+dy))
for tx, ty in to_test:
area.add((x,y))
area=area.union(self.collect_area(tx, ty, area))
@@ -70,7 +74,7 @@ class Board():
def make_guess(self, x, y):
- if x not in range(self.size) or y not in range(self.size):
+ if self.invalid_coordinates(x, y):
print("Koordinaatit on pelilaudan ulkopuolella", file=stderr)
return False
@@ -85,11 +89,8 @@ class Board():
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
+ if not self.invalid_coordinates(cx+dx, cy+dy):
+ self.masked[cx+dx][cy+dy] = 0
else:
self.masked[x][y] = 0
@@ -108,5 +109,4 @@ if __name__ == "__main__":
b.make_guess(5,5)
print_matrix(b.get_view())
-
\ No newline at end of file
diff --git a/tui/tui.py b/tui/tui.py
new file mode 100644
index 0000000..1cacf30
--- /dev/null
+++ b/tui/tui.py
@@ -0,0 +1,94 @@
+import termios, fcntl, sys, os
+fd = sys.stdin.fileno()
+
+oldterm = termios.tcgetattr(fd)
+newattr = termios.tcgetattr(fd)
+newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
+termios.tcsetattr(fd, termios.TCSANOW, newattr)
+
+oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
+fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
+
+
+class Tui():
+ def __init__(self):
+ # https://stackoverflow.com/questions/983354/how-do-i-wait-for-a-pressed-key
+ fd = sys.stdin.fileno()
+ oldterm = termios.tcgetattr(fd)
+ newattr = termios.tcgetattr(fd)
+ newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
+ termios.tcsetattr(fd, termios.TCSANOW, newattr)
+
+ def __del__(self):
+ termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
+ fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
+
+ def set_color(self, color):
+ if color>=0 and color<16:
+ print(end=f"\033[{'1;' if color//8 else ''}3{color%8}m")
+
+ def set_bg(self, color):
+ if color>=0 and color<8:
+ print(end=f"\033[4{color}m")
+
+ def reset_color(self):
+ print(end="\033[0m")
+
+ def draw_tile(self, tile, hilighted):
+ chars_and_colors = (
+ (' ', 7, 0), ('1', 10, 0), ('2', 12, 0),
+ ('3', 11, 0), ('4', 9, 0), ('5', 9, 0),
+ ('6', 9, 0), ('7', 9, 0), ('8', 9, 0),
+ ('9', 15, 1), ('#', 8, 7)
+ )
+
+ if hilighted:
+ self.set_color(14)
+ self.set_bg(6)
+ else:
+ self.set_color(chars_and_colors[tile][1])
+ self.set_bg(chars_and_colors[tile][2])
+
+ print(end=f"[{chars_and_colors[tile][0]}]")
+ self.reset_color()
+
+ def draw_matrix(self, matrix, hx, hy ):
+ for y in range(len(matrix[0])):
+ for x in range(len(matrix)):
+ self.draw_tile( matrix[x][y],
+ x == hx and y == hy )
+ print()
+
+ def matrix_selector(self, matrix, x,y ):
+ self.draw_matrix(matrix, x, y)
+ while True:
+ try:
+ c = sys.stdin.read(1)
+ except:
+ continue
+ match c:
+ case 'A':
+ y-=1
+ case 'B':
+ y+=1
+ case 'C':
+ x+=1
+ case 'D':
+ x-=1
+ case '':
+ continue
+ case 'q':
+ return (-1,-1)
+ case ' ':
+ return (x,y)
+ case _:
+ continue
+ x = 0 if x < 0 else x
+ y = 0 if y < 0 else y
+ x = len(matrix)-1 if x >= len(matrix) else x
+ y = len(matrix[0])-1 if y >= len(matrix[0]) else y
+
+ print(repr(c))
+ self.draw_matrix(matrix, x, y)
+
+ \ No newline at end of file