/
client.py
241 lines (212 loc) · 6.66 KB
/
client.py
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# Copyright 2012 Andreev Alexander <carzil@yandex.ru>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from socket import socket
from argparse import ArgumentParser
from bowman.utils import Connection
import sys
import os
from bowman.lib import colorama
colorama.init()
UNIT_TYPES_SYMBOLS = ["r", "k", "h", "w", "s", "a", "dm", "lm", "dr"]
CHOICE_UNIT_TYPE_PROMT = "Enter unit type, which you prefer: "
COLORED_OUTPUT = True
class Client():
def __init__(self, remote_ip, remote_port):
'''
Constructor for class Client.
It takes destination host and port and connect to it.
'''
self.remote_ip = remote_ip
self.remote_port = remote_port
self._connect()
self.world_info = None
self.unit_type = self.choice_unit_type()
self.tr_nums = None
self.tb_nums = None
self.team = None
self.main()
def clear_screen(self):
'''
This function call os command to clear screen.
'''
if sys.platform == "win32":
os.system("cls")
else:
os.system("clear")
def _connect(self):
'''
This function connect Client class instance to remote server.
'''
self._sock = socket()
self._sock.connect((self.remote_ip, self.remote_port))
self._connection = Connection(self._sock)
data = self._connection.get_pack()
if data == "hello":
return
raise Exception("Oops! There is an server error")
def choice_unit_type(self):
'''
Reads from input string
and if there is such unit abbreviate, returns it.
'''
string = input(CHOICE_UNIT_TYPE_PROMT).strip()
while not string or string not in UNIT_TYPES_SYMBOLS:
string = input(CHOICE_UNIT_TYPE_PROMT).strip()
return string
def lose(self):
'''
This function invokes when player lose.
'''
print("You lose!")
def win(self):
'''
This function invokes when player win.
'''
print("You win!")
def miss(self):
'''
This function invokes when player missed.
'''
print("You missed!")
def colorize(self, data):
i = data.index("")
print("\n".join(data[:i]))
data = data[i:]
out = ""
for line in data:
for char in line:
if char.isdigit() and char != str(self.n):
out += colorama.Fore.RED + colorama.Style.BRIGHT + char\
+ colorama.Fore.RESET + colorama.Style.NORMAL
elif char.isdigit() and char == str(self.n):
out += colorama.Fore.YELLOW + char + colorama.Fore.RESET
elif char == "*":
out += colorama.Fore.BLUE + char\
+ colorama.Fore.RESET + colorama.Back.RESET
elif char == "+":
out += colorama.Fore.GREEN + colorama.Style.BRIGHT + char\
+ colorama.Fore.RESET
elif char == "#":
out += colorama.Fore.RED + char + colorama.Fore.RESET
else:
out += char
out += "\n"
return out
def receive_matrix(self):
'''
This function receive new battle field representation and colorize it
if COLORED_OUTPUT is True.
'''
print(colorama.Style.NORMAL)
self.clear_screen()
print("Type 'help' or 'h' for help.")
data = self._connection.get_pack().splitlines()
if COLORED_OUTPUT:
out = self.colorize(data)
print(out)
else:
print(data)
def print(self):
'''
Prints string received from server.
'''
data = self._connection.get_pack()
print(data)
def end_game(self):
'''
Notify that game was finished and close connection to server.
'''
print("Game finished!")
self._sock.close()
def abort_game(self):
'''
Notify that game was aborted and close connection to server.
'''
print(
"Game aborted, because fatal error has been raised on the server!"
)
self._sock.close()
def ally_fire(self):
'''
This function invokes when player is trying to fire his ally.
'''
print("This player is your ally!")
def team_lose(self):
'''
This function invokes when player team lose.
'''
print("Your team lose!")
def team_win(self):
'''
This function invokes when player team win.
'''
print("Your team win!")
def prompt(self):
'''
Prompt a string from user.
'''
return input(">> ").strip()
def main(self):
'''
Main loop of client.
It receives two-symbol package
and invokes function depend on package content.
'''
self._connection.send_pack(self.unit_type)
n = self._connection.get_pack()
n = int(n)
self.n = n
print("Waiting for game start...")
while True:
data = self._connection.get_pack()
if data == "go":
string = self.prompt()
while not string:
string = self.prompt()
self._connection.send_pack(string)
elif data == "lo":
self.lose()
elif data == "wi":
self.win()
elif data == "mi":
self.miss()
elif data == "nb":
self.nb()
elif data == "mx":
self.receive_matrix()
elif data == "af":
self.ally_fire()
elif data == "tw":
self.team_win()
elif data == "tl":
self.team_lose()
elif data == "eg":
self.end_game()
break
elif data == "ag":
self.abort_game()
break
elif data == "pr":
self.print()
def main():
arg_parser = ArgumentParser(
description="Bowman is a client-server console game. "
"See more: https://github.com/carzil/bowman"
)
arg_parser.add_argument(
"--host",
help="server host",
default="localhost"
)
arg_parser.add_argument(
"--port",
default=9999,
type=int,
help="server port"
)
args = arg_parser.parse_args()
Client(args.host, args.port)
if __name__ == "__main__":
main()