-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
193 lines (148 loc) · 6.45 KB
/
main.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
#########################################################
# I test the code here so the run.py file stays clean. #
#########################################################
import time
from random import choice
import pygame
import settings
from snakes_battle import logic
from snakes_battle.board import Board
from snakes_battle.exceptions import InvalidDirection
from snakes_battle.fruit import Fruit, FruitKind
from snakes_battle.graphics import GameGraphics
from snakes_battle.snakes_ai.ari_snake import AriSnake
from snakes_battle.snakes_ai.chaim_snake import ChaimSnake
from snakes_battle.snakes_ai.dumpster import Dumpster
from snakes_battle.snakes_ai.elitz_snake import ElitzSnake
from snakes_battle.snakes_ai.manual_control_snake import ManualSnake
from snakes_battle.snakes_ai.manual_control_snake_wasd import ManualSnakeWASD
from snakes_battle.snakes_ai.moshes_snake import MoshesSnake
from snakes_battle.snakes_ai.yakov_snake import Yakov
from snakes_battle.snakes_ai.yoav_snake import YoavSnake
def main():
ai_classes_available = [
{'class': Dumpster, 'should_play': False},
# {"class": RandomSnake, "should_play": False},
{'class': YoavSnake, 'should_play': False},
# {"class": SimpleSnake, "should_play": False},
# {"class": ManualSnake, "should_play": False},
# {"class": ManualSnakeWASD, "should_play": False},
{'class': MoshesSnake, 'should_play': False},
# {"class": WorstSnakeEU, "should_play": False},
{'class': ElitzSnake, 'should_play': False},
{'class': ChaimSnake, 'should_play': False},
{'class': AriSnake, 'should_play': False},
{'class': Yakov, 'should_play': False},
]
should_exit = False
game_running = False
game_menus = True
run_num = 0
graphics = GameGraphics(ai_classes_available)
while not should_exit:
if game_running:
playing_classes = [x['class'] for x in ai_classes_available if x['should_play']]
if len(playing_classes) > 0:
run_num += 1
print(f'\n\n######################### Game Number {run_num} #########################\n')
run_game(playing_classes, ai_classes_available)
print('\n#################################################################')
game_menus = True
game_running = False
elif game_menus:
menus_return = run_menus(graphics, ai_classes_available)
if menus_return['action'] == 'Exit':
pygame.quit()
should_exit = True
elif menus_return['action'] == 'Play':
game_menus = False
game_running = True
def run_menus(graphics, ai_classes_available):
menu_running = True
main_menu = True
snake_picker = False
while menu_running:
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
return 'Exit'
if event.type == pygame.KEYDOWN:
for index, class_dict in enumerate(ai_classes_available):
if event.key == settings.PYGAME_START_NUMBER_PRESS_VALUE + index:
class_dict['should_play'] = not class_dict['should_play']
if main_menu:
menu_action = graphics.draw_menu(ai_classes_available, events)
if menu_action == 'Exit':
return {'action': menu_action, 'args': ''}
elif menu_action == 'Play':
return {'action': menu_action, 'args': ''}
elif snake_picker:
pass
def run_game(playing_classes, ai_classes_available):
graphics = GameGraphics(ai_classes_available)
board = Board(graphics.board_size)
frames_delay = settings.DELAY_BETWEEN_SCREEN_UPDATES
snakes_array = []
for snake_class in playing_classes:
snakes_array.append(
snake_class(board.border_cells, color=graphics.get_unique_snake_color(), name=snake_class.__name__)
)
for snake in snakes_array:
# The position of the head is determined by the rules and the board state.
head_pos = logic.get_unique_snake_head_position(board)
snake._body_position = [head_pos]
snake._grow(settings.STARTING_SNAKE_LENGTH - 1)
board.add_snake(snake)
for _ in range(settings.NUMBER_OF_BENEFICIAL_FRUITS_ON_BOARD):
board.add_fruit(Fruit(choice(FruitKind.beneficial_fruits), logic.get_new_fruit_position(board)))
while not board.is_game_timed_out() and len(board.snakes) > 0:
time.sleep(frames_delay)
should_exit = False
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
should_exit = True
if event.type == pygame.KEYDOWN:
if event.unicode == '+':
frames_delay *= 0.9
if event.unicode == '-':
frames_delay *= 1.1
if should_exit:
break
# The AI Snake Should make a decision in which direction to go.
for snake in board.snakes:
try:
if snake.__class__ in [ManualSnake, ManualSnakeWASD]:
new_direction = snake.make_decision(board.get_board_state(), events)
else:
new_direction = snake.make_decision(board.get_board_state())
except Exception as e:
print(snake._name, 'was removed from the game: ', e)
snake._lost = True
if settings.DEBUG:
raise e
continue
if new_direction in [0, 1, 2, 3, 4, None]:
snake._change_direction(new_direction)
else:
print(
snake._name,
'was removed from the game: ',
'snake not returned a valid direction',
f'({new_direction})',
)
snake._lost = True
if settings.DEBUG:
raise InvalidDirection(f'Snake not returned a valid direction ({new_direction})')
for snake in board.snakes:
snake._move_one_cell()
logic.apply_logic(board, events)
graphics.update_screen(board)
winners = logic.get_first_place(board)
if len(winners) == 1:
print(winners[0]._name + ' is the winner!!!')
else:
print('There is a tie between', winners, '!!!')
time.sleep(2)
if __name__ == '__main__':
main()