1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
""" tui/tui.py - teksikäyttöliittymä """
# pylint: disable = multiple-imports
import termios, fcntl, sys, os
from time import sleep
from tui.static import Action, ActionKeys, TileTypes
from tui.ansi import Ansi
class Tui():
""" Tui - Luokka käyttäjän interaktiota varten """
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)
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 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 matrix_selector(self, matrix, x, y):
""" piirtää ruudukon ja antaa käyttäjän valita nuolinäppäimillä """
self.draw_matrix(matrix, x, y)
while True:
action = self.read_action()
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
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, size):
""" ruudun alustus ja lähtökoordinaatien määritys """
print(end="\n"*(size+1))
Ansi.cup(1)
return size//2, size//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...")
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...")
def game_end(self, matrix):
""" pelin lopetus """
self.show_board_with_text(matrix, -1, -1,
"PELI OHI! ...näppäimellä eteenpäin...")
print()
|