-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgame.py
98 lines (82 loc) · 3 KB
/
game.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
from seabattle import player
class GameSession:
_ready_players = 0
_current_turn = None
def __init__(self):
self._players = []
def new_player(self, to_client_func, on_game_end):
"""
Creates new player and return it
:param to_client_func: Func which will be called when player wants to send data to the client
:type to_client_fund: `callable`
:param on_game_end: Func which will be called when player wants to end the game
:type on_game_end: `callable`
:rtype: :class:`seabattle.player.Player` or None if game is full
"""
if len(self._players) < 2:
new_player = player.Player(len(self._players), self, to_client_func, on_game_end)
self._players.append(new_player)
return new_player
def ready_for_begin(self, player):
"""
Callback when player is ready to begin the battle
"""
self._ready_players += 1
if len(self._players) == 2 and self._ready_players == len(self._players): # all players are ready
self.next_turn()
else: # some player are not ready at this moment
player.wait_other_player_ready()
def fire(self, player, col, row):
"""
Callback when active player do fire
"""
passive_player = self._get_passive_player()
fire_result = passive_player.enemy_fire(col, row)
if fire_result:
player.my_hit(col, row)
if not passive_player.has_ships():
player.win()
passive_player.lost()
self.finish_game()
else:
player.my_miss(col, row)
self.next_turn()
def player_disconnect(self, player):
"""
When some player leave the game. We notify other players and finish game
"""
for pl in self._all_players_except(player):
pl.error_other_player_leave()
pl.finish_game()
self._players = []
def finish_game(self):
"""
When game is finished
"""
for pl in self._players:
pl.finish_game()
self._players = []
def next_turn(self):
if self._current_turn is None:
self._current_turn = 0
else:
self._current_turn += 1
active_player = self._get_active_player()
passive_player = self._get_passive_player()
active_player.your_turn()
passive_player.wait_other_player_turn()
def _get_active_player(self):
"""
Return player who can fire now
"""
return self._players[self._current_turn % len(self._players)]
def _get_passive_player(self):
"""
Return player who can't fire now
"""
return self._players[(self._current_turn + 1) % len(self._players)]
def _all_players_except(self, except_player):
for current_player in self._players:
if current_player != except_player:
yield current_player
raise StopIteration