-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathui.py
More file actions
180 lines (145 loc) · 5.59 KB
/
ui.py
File metadata and controls
180 lines (145 loc) · 5.59 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
__author__ = 'Camtr0n'
import player
from abc import ABCMeta, abstractmethod
class AbstractIO(metaclass=ABCMeta):
invalid_input_message = "\nInvalid input; Please select a number 1-"
move_already_taken_message = "\nInvalid move, square is already taken; Please select an available square."
tie_message = "DRAW! You just can't win, can you?"
@staticmethod
def get_decision_occurred_message(decided_player):
return "\n" + str(decided_player.player_type) + "[Player " + str(decided_player.number) + "] has decided."
@staticmethod
def get_winner_message(winning_player):
return "Player [" + str(winning_player.number) + "] is the WINNER!!! #Sorrynotsorry"
@abstractmethod
def display_intro(self):
""" Display instructions for game """
pass
@abstractmethod
def display_board(self):
""" Display game board"""
pass
@abstractmethod
def get_choice(self, human_player, board):
""" Get move from a player """
pass
@abstractmethod
def notify_invalid_input(self, size):
""" Notify user that input is not a valid move, depends on size of board to give accurate prompt """
pass
@abstractmethod
def notify_move_taken(self):
""" Notify user that selected move has already been taken """
pass
@abstractmethod
def get_player_type(self, number):
""" Prompt user for selection of player type (Human, Computer, etc) """
pass
@abstractmethod
def play_again(self):
""" Prompt player to play again at end of game """
pass
@abstractmethod
def notify_decision_occurred(self, decider):
""" Notify that human or computer has made a decision to help with tracking turns"""
pass
@abstractmethod
def notify_winner(self):
""" Notify user that human or computer won the game """
pass
@abstractmethod
def notify_tie(self):
""" Notify user that tie game has been reached """
pass
class Terminal(AbstractIO):
@staticmethod
def display_intro():
print("Welcome to Unbeatable Tic-Tac-Toe!")
print("Proceed without hope...")
print("")
print("Player one is: ", player.Symbol(1).name)
print("Player two is: ", player.Symbol(2).name)
print("")
print("For 3x3 game (default), use the number pad to select your move.")
print("(Note: you may need to press the Num Lock key to activate your numeric keypad)")
print("")
@staticmethod
def display_board(board):
print(" " + " | ".join(board.rows[0]))
for row in board.rows[1:]:
print("-" * (board.size * 4 - 1))
print(" " + " | ".join(row))
print("\n")
@staticmethod
def display_number_board(board):
print(" " + " | ".join(map(str, board.rows[0])))
for row in board.rows[1:]:
print("-" * ((board.size * 5) - 1))
print(" " + " | ".join(row))
print("\n")
@staticmethod
def notify_turn(player_number):
print("Player[" + str(player_number) + "], your turn.")
@staticmethod
def notify_thinking(player_type):
print(str(player_type) + " is thinking...")
@staticmethod
def notify_move_taken():
print(AbstractIO.move_already_taken_message)
@staticmethod
def notify_decision_occurred(decider):
print(AbstractIO.get_decision_occurred_message(decider))
@staticmethod
def notify_tie():
print(AbstractIO.tie_message)
@staticmethod
def notify_invalid_input(size):
print(AbstractIO.invalid_input_message + str(size ** 2))
@staticmethod
def notify_winner(winner):
print("Player " + str(winner.number) + " has won the game!")
@staticmethod
def get_human_input(human_player, board):
Terminal.notify_turn(human_player.number)
choice = input("Press 'n' then <ENTER> to redraw board with numbers in empty squares, or\n" +
"Press 1-" + str(board.size ** 2) + " to select move and press <ENTER>: ")
if choice in ("n", "N"):
return choice
try:
choice = int(choice)
except:
choice = Terminal.get_human_input(human_player, board)
return choice
@staticmethod
def get_choice(human_player, board):
choice = Terminal.get_human_input(human_player, board)
if choice in ("n", "N"):
Terminal.display_number_board(board.numbers)
choice = Terminal.get_choice(human_player, board)
elif choice not in board.valid_inputs:
Terminal.notify_invalid_input(board.size)
choice = Terminal.get_choice(human_player, board)
if board.map_to_move(choice) not in board.available:
Terminal.notify_move_taken()
choice = Terminal.get_choice(human_player, board)
return choice
@staticmethod
def play_again():
answer = input("Would you like to play again? Y/N: ")
if answer in ("Y", "y"):
print("\n\n")
return True
elif answer in ("N", "n"):
exit()
else:
return Terminal.play_again
@staticmethod
def get_player_type(player_number):
print("What type of player will " + player_number + " be: Human[1] or Computer[2]?")
choice = input("Enter the number corresponding to the player type: ")
try:
choice = int(choice)
except:
choice = Terminal.get_player_type(player_number)
print("")
return choice if choice in (1, 2) else Terminal.get_player_type(player_number)