summaryrefslogtreecommitdiff
path: root/tui
diff options
context:
space:
mode:
Diffstat (limited to 'tui')
-rw-r--r--tui/__init__.py1
-rw-r--r--tui/ansi_draw.py61
-rw-r--r--tui/autotui.py27
-rw-r--r--tui/kbd.py78
-rw-r--r--tui/tui.py173
5 files changed, 202 insertions, 138 deletions
diff --git a/tui/__init__.py b/tui/__init__.py
index f39cd45..c1c5b91 100644
--- a/tui/__init__.py
+++ b/tui/__init__.py
@@ -1,4 +1,3 @@
""" tui - hoitaa käyttäjälle katseltavaa ja havaitsee syötteet """
from .tui import Tui
-from .autotui import AutoTui
from .static import Action
diff --git a/tui/ansi_draw.py b/tui/ansi_draw.py
new file mode 100644
index 0000000..dd304d0
--- /dev/null
+++ b/tui/ansi_draw.py
@@ -0,0 +1,61 @@
+""" tui/ansi_draw.py - perustukset ansi tulostelulle """
+# pylint: disable = multiple-imports
+from .ansi import Ansi
+from .static import TileTypes
+
+class AnsiDraw():
+ """ AnsiDraw - "piirtelee" näytölle kirjailmilla """
+ def __init__(self, height = 15):
+ print(end="\n"*height)
+
+ def __del__(self):
+ print()
+
+ def __tile(self, tile, hilighted):
+ """ "piirtää" yhden ruudun """
+ for ch, colors in zip(TileTypes[tile].text, TileTypes[tile].colors):
+ color, bg = colors
+ Ansi.color(Ansi.BLACK if hilighted else color)
+ Ansi.bg(Ansi.CYAN if hilighted else bg)
+ print(end=ch)
+ Ansi.reset()
+
+
+ def matrix(self, matrix, hx, hy):
+ """ "piirtää" ruudukon """
+ Ansi.cup(len(matrix[0]))
+ # pylint: disable=consider-using-enumerate
+ for y in range(len(matrix[0])):
+ for x in range(len(matrix)):
+ hilight = matrix[x][y] != 9 and x == hx and y == hy
+ self.__tile(matrix[x][y], hilight)
+ print()
+
+
+ def status_line(self, text):
+ """ draw_status_line - tulostaa pelitietorivin"""
+ print(end=text+'\r')
+
+class SuppressDraw():
+ """ SuppressDraw - vain status """
+ # pylint: disable = unused-argument
+
+ def matrix(self, matrix, hx, hy):
+ """ "piirtää" ruudukon """
+ return True
+
+ def status_line(self, text):
+ """ draw_status_line - tulostaa pelitietorivin"""
+ print(end=text+'\r')
+
+class NoDraw():
+ """ NoDraw - ei mitään """
+ # pylint: disable = unused-argument
+
+ def matrix(self, matrix, hx, hy):
+ """ "piirtää" ruudukon """
+ return True
+
+ def status_line(self, text):
+ """ draw_status_line - tulostaa pelitietorivin"""
+ return True
diff --git a/tui/autotui.py b/tui/autotui.py
deleted file mode 100644
index ae5d58c..0000000
--- a/tui/autotui.py
+++ /dev/null
@@ -1,27 +0,0 @@
-""" autotui - pelaa botin antamat vinkit jonka jälkeen käyttäjän """
-from .tui import Tui
-from .static import Action
-from .ansi import Ansi
-
-class AutoTui(Tui):
- """ Tui - Luokka joka tekee botin vinkit ensin """
- def matrix_selector(self, matrix, x, y):
- """ yritetään pyydellä botilta vinkkiä ensin """
- if self.bot is not None:
- action, x, y = self.bot.hint(matrix, x, y)
- if action != Action.NOOP:
- self.draw_matrix(matrix, -1, -1)
- if action==Action.SAFE:
- action = Action.OPEN
- return action, x, y
-
- return super().matrix_selector(matrix, x, y)
-
- def show_board_with_text(self, matrix, x, y, text):
- """ näyttää laudan, tekstin alla (ei odota nappia) """
- self.draw_matrix(matrix, x, y)
- print(text)
- Ansi.cup(1)
-
- def game_end(self, matrix):
- """ pelin lopetus """
diff --git a/tui/kbd.py b/tui/kbd.py
new file mode 100644
index 0000000..b6d2363
--- /dev/null
+++ b/tui/kbd.py
@@ -0,0 +1,78 @@
+""" tui/kbd.py - näppäimistön käsittellijä """
+# pylint: disable = multiple-imports
+import termios, fcntl, sys, os
+from time import sleep
+from .static import ActionKeys, Action
+
+class NoKbd():
+ """ NoKbd - näppis-ei-käsittelijä """
+ # pylint: disable = unused-argument
+ def read_action(self):
+ """ read_action - ilman näppistä -> loppu """
+ return Action.QUIT
+
+ def read_matrix_action(self, w, h, x, y):
+ """ read_matrix_action - ilman näppistä -> loppu """
+ return Action.QUIT, 0, 0
+
+class Kbd():
+ """ Kbd - näppiskäsittelijä """
+ def __init__(self):
+ # Vaatii hieman terminaaliasetusten muokkaamista jotta yksittäiset
+ # napin painallukset voidaan lukea
+ # https://stackoverflow.com/questions/983354/how-do-i-wait-for-a-pressed-key
+ fd = sys.stdin.fileno()
+ self.oldterm = termios.tcgetattr(fd)
+
+ newattr = termios.tcgetattr(fd)
+ newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
+ termios.tcsetattr(fd, termios.TCSANOW, newattr)
+
+ self.oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
+ fcntl.fcntl(fd, fcntl.F_SETFL, self.oldflags | os.O_NONBLOCK)
+
+ def __del__(self):
+ # palautetaan terminaali takaisin alkupetäiseen uskoon
+ fd = sys.stdin.fileno()
+ termios.tcsetattr(fd, termios.TCSAFLUSH, self.oldterm)
+ fcntl.fcntl(fd, fcntl.F_SETFL, self.oldflags)
+
+ def read_action(self):
+ """ lukee näppäimistölä käyttäjän toiminnon """
+ while True:
+ # Ehkä riittää jos näppäimiä luetaan 50x sekunnissa
+ sleep(0.02)
+ try:
+ keycode = sys.stdin.read(16)
+ except KeyboardInterrupt:
+ return Action.QUIT
+ if keycode:
+ for key, action in ActionKeys.items():
+ if keycode.startswith(key):
+ return action
+
+ def read_matrix_action(self, w, h, x, y):
+ """ read_matrix_action - lukee actionit ja pitää huolen koordinaat"""
+ action = self.read_action()
+ match action:
+ case Action.QUIT | Action.HINT:
+ return (action, x, y)
+ case Action.OPEN | Action.FLAG | Action.BOMB | Action.SAFE:
+ return (action, x, y)
+ case Action.UP:
+ y = y-1 if y > 0 else 0
+ case Action.LEFT:
+ x = x-1 if x > 0 else 0
+ case Action.DOWN:
+ y = y+1 if y < h-1 else y
+ case Action.RIGHT:
+ x = x+1 if x < w-1 else x
+ case Action.TOP:
+ y = 0
+ case Action.BOTTOM:
+ y = h-1
+ case Action.BEGIN:
+ x = 0
+ case Action.END:
+ x = w-1
+ return (Action.NOOP, x, y)
diff --git a/tui/tui.py b/tui/tui.py
index e925e57..7d8f565 100644
--- a/tui/tui.py
+++ b/tui/tui.py
@@ -1,136 +1,89 @@
-""" tui/tui.py - teksikäyttöliittymä """
+""" tui/tui.py - runko käyttöliittymälle """
# pylint: disable = multiple-imports
-import termios, fcntl, sys, os
-from time import sleep
-from .static import Action, ActionKeys, TileTypes
-from .ansi import Ansi
+from .static import Action
+from .kbd import Kbd, NoKbd
+from .ansi_draw import AnsiDraw, SuppressDraw
class Tui():
""" Tui - Luokka käyttäjän interaktiota varten """
- def __init__(self, bot = None):
- # Vaatii hieman terminaaliasetusten muokkaamista jotta yksittäiset
- # napin painallukset voidaan lukea
- # https://stackoverflow.com/questions/983354/how-do-i-wait-for-a-pressed-key
- fd = sys.stdin.fileno()
- self.oldterm = termios.tcgetattr(fd)
+ # pylint: disable = unused-argument
+ def __init__(self, **opts):
+ self.bot = opts['bot'] if 'bot' in opts else None
+ self.autoplay = opts['autoplay'] if 'autoplay' in opts else False
+ self.interact = opts['interact'] if 'interact' in opts else True
+ self.suppress = opts['suppress'] if 'suppress' in opts else False
+ self.height = opts['height'] if 'height' in opts else 15
+
+ # jos ei oo bottia pitää olla interaktiivinen
+ if self.bot is None:
+ self.autoplay = False
+ self.interact = True
+ self.suppress = False
+
+ # jos ei mitään näytetä ei voi olla interaktiivinen
+ self.interact = False if self.suppress else self.interact
+
+ # automaattipeli pitää olla päällä jos ei interaktiivinen
+ self.autoplay = self.autoplay if self.interact else True
+
+ if self.interact:
+ self.kbd = Kbd()
+ else:
+ self.kbd = NoKbd()
+
+ if self.suppress:
+ self.draw = SuppressDraw()
+ else:
+ self.draw = AnsiDraw(height=self.height)
- newattr = termios.tcgetattr(fd)
- newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
- termios.tcsetattr(fd, termios.TCSANOW, newattr)
-
- self.oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
- fcntl.fcntl(fd, fcntl.F_SETFL, self.oldflags | os.O_NONBLOCK)
-
- self.bot = bot
-
-
- def __del__(self):
- # palautetaan terminaali takaisin alkupetäiseen uskoon
- fd = sys.stdin.fileno()
- termios.tcsetattr(fd, termios.TCSAFLUSH, self.oldterm)
- fcntl.fcntl(fd, fcntl.F_SETFL, self.oldflags)
- print()
-
-
- def draw_tile(self, tile, hilighted):
- """ "piirtää" yhden ruudun """
- for ch, colors in zip(TileTypes[tile].text, TileTypes[tile].colors):
- color, bg = colors
- Ansi.color(Ansi.BLACK if hilighted else color)
- Ansi.bg(Ansi.CYAN if hilighted else bg)
- print(end=ch)
- Ansi.reset()
-
-
- def draw_matrix(self, matrix, hx, hy):
- """ "piirtää" ruudukon """
- Ansi.cup(len(matrix[0]))
- # pylint: disable=consider-using-enumerate
- for y in range(len(matrix[0])):
- for x in range(len(matrix)):
- hilight = matrix[x][y] != 9 and x == hx and y == hy
- self.draw_tile(matrix[x][y], hilight)
- print()
+ def matrix_selector(self, matrix, x, y):
+ """ valinta matriisita """
+ # automaattipeli avaa botin vinkit heti
+ if self.autoplay:
+ action, x, y = self.bot.hint(matrix, x, y)
+ if action != Action.NOOP:
+ self.draw.matrix(matrix, -1, -1)
+ return Action.OPEN if action==Action.SAFE else action, x, y
- def read_action(self):
- """ lukee näppäimistölä käyttäjän toiminnon """
- while True:
- # Ehkä riittää jos näppäimiä luetaan 50x sekunnissa
- sleep(0.02)
- try:
- keycode = sys.stdin.read(16)
- except KeyboardInterrupt:
- return Action.QUIT
- if keycode:
- for key, action in ActionKeys.items():
- if keycode.startswith(key):
- return action
+ # ilman näppiskäsittelijää voidaan lopettaa
+ if not self.interact:
+ return Action.QUIT, 0, 0
- def matrix_selector(self, matrix, x, y):
- """ piirtää ruudukon ja antaa käyttäjän valita nuolinäppäimillä """
- self.draw_matrix(matrix, x, y)
+ w, h = len(matrix), len(matrix[0])
while True:
- action = self.read_action()
+ self.draw.matrix(matrix, x, y)
+ action, x, y = self.kbd.read_matrix_action(w, h, x, y)
match action:
case Action.QUIT:
return (action, x, y)
case Action.OPEN | Action.FLAG | Action.BOMB | Action.SAFE:
if matrix[x][y] >= 10:
return (action, x, y)
- case Action.UP:
- y = y-1 if y > 0 else 0
- case Action.LEFT:
- x = x-1 if x > 0 else 0
- case Action.DOWN:
- y = y+1 if y < len(matrix[0])-1 else y
- case Action.RIGHT:
- x = x+1 if x < len(matrix)-1 else x
- case Action.TOP:
- y = 0
- case Action.BOTTOM:
- y = len(matrix[0])-1
- case Action.BEGIN:
- x = 0
- case Action.END:
- x = len(matrix)-1
case Action.HINT:
if self.bot is not None:
return self.bot.hint(matrix, x, y)
- self.draw_matrix(matrix, x, y)
-
-
- def show_board_with_text(self, matrix, x, y, text):
- """ näyttää laudan, tekstin alla ja jää odottelemaan nappia """
- self.draw_matrix(matrix, x, y)
- print(text)
- Ansi.cup(1)
- self.read_action()
-
-
- def game_begin(self, width, height):
- """ ruudun alustus ja lähtökoordinaatien määritys """
- print(end="\n"*(height+1))
- Ansi.cup(1)
- return width//2, height//2
-
def game_over(self, matrix, x, y):
- """ näyttää pelin lopputilanteen ja odottaa nappia """
- self.show_board_with_text(matrix, x, y,
- "KUOLEMA! ...näppäimellä eteenpäin...")
-
+ """ tehtävät kun kuolee """
+ self.draw.matrix(matrix, x, y)
+ self.draw.status_line(
+ "K " if self.suppress else "Peli ohitse! Kuolit!"
+ )
+ self.kbd.read_action()
def game_win(self, matrix, x, y):
- """ näyttäää pelin lopputilanteen ja odottaa nappia """
- self.show_board_with_text(matrix, x, y,
- "VOITTO! ...näppäimellä eteenpäin...")
-
+ """ tehtävät kun voittaa """
+ self.draw.matrix(matrix, x, y)
+ self.draw.status_line(
+ "V " if self.suppress else "Peli ohitse! Voitit!"
+ )
+ self.kbd.read_action()
def game_end(self, matrix):
- """ pelin lopetus """
- self.show_board_with_text(matrix, -1, -1,
- "PELI OHI! ...näppäimellä eteenpäin...")
- print()
+ """ tehtävät ihan pelin lopuksi """
+ if self.interact:
+ self.draw.matrix(matrix, -1, -1)
+ self.draw.status_line("Kiitos! ")