diff options
author | Aineopintojen-harjoitustyo-Algoritmit-j <github-hy-tiralabra@v.hix.fi> | 2024-01-29 02:34:32 +0200 |
---|---|---|
committer | Aineopintojen-harjoitustyo-Algoritmit-j <github-hy-tiralabra@v.hix.fi> | 2024-01-29 02:34:32 +0200 |
commit | e591d15abc4943a74c39f0fcab065213828a1514 (patch) | |
tree | bc22931abb08d8c213ba4eb81a85298d69e88890 /tui | |
parent | 0c034e6fbae0833f8524caf223deab450e9bb1b4 (diff) |
Updating too much. Renewed bots and tui.
Diffstat (limited to 'tui')
-rw-r--r-- | tui/__init__.py | 1 | ||||
-rw-r--r-- | tui/ansi_draw.py | 61 | ||||
-rw-r--r-- | tui/autotui.py | 27 | ||||
-rw-r--r-- | tui/kbd.py | 78 | ||||
-rw-r--r-- | tui/tui.py | 173 |
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) @@ -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! ") |