1 | importšTkinteršasštk |
---|
2 | importštkFileDialogšasštkfd |
---|
3 | importšengine |
---|
4 | importšsnake |
---|
5 | |
---|
6 | |
---|
7 | |
---|
8 | classšUI(object): |
---|
9 | š š """User Interface: |
---|
10 | |
---|
11 | š š Atributes: |
---|
12 | |
---|
13 | š š - 'root' - root Window game placed at |
---|
14 | š š - 'engine' - engine of the game |
---|
15 | š š - 'canvas' - Widget field is pictured at |
---|
16 | š š - 'step_id' - current step of the game |
---|
17 | š š - 'after_id' - identificator of runing game process |
---|
18 | š š - 'step_legth' - length of the step (in ms) |
---|
19 | š š - 'game_length' - number of the steps in one round of the game""" |
---|
20 | š š defš__init__š(self): |
---|
21 | š š š š """Create Python Battle game window. |
---|
22 | š š š š Initialyze engige of the game.""" |
---|
23 | š š š š self.root =štk.Tk() |
---|
24 | š š š š self.root.title("Python Battle") |
---|
25 | š š š š self.canvas =štk.Canvas(self.root,šbackground =š"black") |
---|
26 | š š š š self.canvas.pack(side ="top",šfill="both",šexpand="yes") |
---|
27 | š š š š self.buttons_pack(self.root).pack(side ="bottom",šfill="both",šexpand="no") |
---|
28 | š š š š self.step_id =š0 |
---|
29 | š š š š self.engine =šengine.Engine(self.canvas) |
---|
30 | š š š š self.after_id =šNone |
---|
31 | š š š š self.step_length =š150 |
---|
32 | š š š š self.game_length =š200 |
---|
33 | š š š š return |
---|
34 | š š |
---|
35 | š š defšbuttons_pack(self,šroot): |
---|
36 | š š š š """Packing the buttons in root frame. |
---|
37 | š š š š Definition of button functions. |
---|
38 | |
---|
39 | š š š š 'Load' - ask for snake file load |
---|
40 | š š š š 'Run' - runs the game/next round. Next round starts with snakes survived in previous |
---|
41 | š š š š 'Step' - do the next dtep of the game |
---|
42 | š š š š 'End' - manual end of the game |
---|
43 | š š š š 'Restart" - restart the field with snakes of previous round""" |
---|
44 | š š š š buttons =štk.Frame(root) |
---|
45 | š š š š load_1 =štk.Button(buttons,štext="Load 1",šcommand=lambda:šself.load(0)) |
---|
46 | š š š š load_1.grid(row=1,šcolumn=2,šstick="news") |
---|
47 | š š š š load_2 =štk.Button(buttons,štext="Load 2",šcommand=lambda:šself.load(1)) |
---|
48 | š š š š load_2.grid(row=2,šcolumn=3,šstick="news") |
---|
49 | š š š š run_b =štk.Button(buttons,štext="Run",šcommand=lambda:šself.start()) |
---|
50 | š š š š run_b.grid(row=2,šcolumn=2,šstick="news") |
---|
51 | š š š š restart_b =štk.Button(buttons,štext="Restart",šcommand=lambda:šself.restart(survived="no")) |
---|
52 | š š š š restart_b.grid(row=1,šcolumn=5,šstick="news") |
---|
53 | š š š š load_3 =štk.Button(buttons,štext="Load 3",šcommand=lambda:šself.load(2)) |
---|
54 | š š š š load_3.grid(row=3,šcolumn=2,šstick="news") |
---|
55 | š š š š load_4 =štk.Button(buttons,štext="Load 4",šcommand=lambda:šself.load(3)) |
---|
56 | š š š š load_4.grid(row=2,šcolumn=1,šstick="news") |
---|
57 | š š š š step_b =štk.Button(buttons,štext="Step",šcommand=lambda:šself.step()) |
---|
58 | š š š š step_b.grid(row=2,šcolumn=5,šstick="news") |
---|
59 | š š š š end_b =štk.Button(buttons,štext="End",šcommand=lambda:šself.end()) |
---|
60 | š š š š end_b.grid(row=3,šcolumn=5,šstick="news") |
---|
61 | š š š š foršcolumn inšrange(1,š6): |
---|
62 | š š š š š buttons.grid_columnconfigure(column,šweight=1) |
---|
63 | š š š š returnšbuttons |
---|
64 | š š |
---|
65 | š š defšloadš(self,šsnake_number): |
---|
66 | š š š š """Ask for snake file loading. |
---|
67 | š š š š Initialyzing snake and draw it on the field. |
---|
68 | š š š š Return field back to default (without snakes) after end of the game.""" |
---|
69 | š š š š ifšself.step_id ==šself.game_length +š666: |
---|
70 | š š š š š š self.step_id =š0 |
---|
71 | š š š š š š self.engine.snakes =š[None,šNone,šNone,šNone] |
---|
72 | š š š š š š pass |
---|
73 | š š š š ifšself.step_id ==š0: |
---|
74 | š š š š š š fileš=štkfd.askopenfile(title="Open file") |
---|
75 | š š š š š š ifšfileš==šNone: |
---|
76 | š š š š š š š š return |
---|
77 | š š š š š š snake =šself.engine.create_snake(snake_number) |
---|
78 | š š š š š š snake.load(file) |
---|
79 | š š š š š š pass |
---|
80 | š š š š self.engine.refill() |
---|
81 | š š š š self.engine.redraw() |
---|
82 | š š š š return |
---|
83 | |
---|
84 | š š defšstartš(self): |
---|
85 | š š š š """Init running of the game.""" |
---|
86 | š š š š ifšself.after_id !=šNone: |
---|
87 | š š š š š š return |
---|
88 | š š š š ifšself.step_id ==šself.game_length +š666: |
---|
89 | š š š š š š self.restart(survived="yes") |
---|
90 | š š š š ifšself.step_id ==š0: |
---|
91 | š š š š š š self.engine.psnakes =šself.engine.snakes[:] |
---|
92 | š š š š self.run() |
---|
93 | š š š š |
---|
94 | š š defšrunš(self): |
---|
95 | š š š š """Run the game with 'step_length' ms step |
---|
96 | š š š š After the end of the game - restarts it with snakes survived in |
---|
97 | š š š š previous game""" |
---|
98 | š š š š ifšself.step_id >šself.game_length: |
---|
99 | š š š š š š self.end() |
---|
100 | š š š š š š return |
---|
101 | š š š š ifšself.snake_dead_check()š==šFalse: |
---|
102 | š š š š š š return |
---|
103 | š š š š ifšself.snake_move_check()š==šFalse: |
---|
104 | š š š š š š return |
---|
105 | š š š š self.step_id =šself.step_id+1 |
---|
106 | š š š š self.engine.step() |
---|
107 | š š š š self.after_id =šself.canvas.after(self.step_length,šself.run) |
---|
108 | š š š š return |
---|
109 | š š |
---|
110 | š š defšstepš(self): |
---|
111 | š š š š """Do the next game step""" |
---|
112 | š š š š ifšself.snake_dead_check()š==šFalse: |
---|
113 | š š š š š š return |
---|
114 | š š š š ifšself.snake_move_check()š==šFalse: |
---|
115 | š š š š š š return |
---|
116 | š š š š ifšself.step_id ==š0: |
---|
117 | š š š š š š self.engine.psnakes =šself.engine.snakes[:] |
---|
118 | š š š š ifšself.step_id <=šself.game_length: |
---|
119 | š š š š š š self.run_cancel() |
---|
120 | š š š š š š self.step_id =šself.step_id+1 |
---|
121 | š š š š š š self.engine.step() |
---|
122 | š š š š š š pass |
---|
123 | š š š š else: |
---|
124 | š š š š š š self.end() |
---|
125 | š š š š š š pass |
---|
126 | š š š š return |
---|
127 | |
---|
128 | š š defšrun_cancel(self): |
---|
129 | š š š š """Stops runnin of the game""" |
---|
130 | š š š š ifšself.after_id !=šNone: |
---|
131 | š š š š š š self.canvas.after_cancel(self.after_id) |
---|
132 | š š š š š š self.after_id =šNone |
---|
133 | š š |
---|
134 | š š defšsnake_dead_check(self): |
---|
135 | š š š š """Check the number of snakes alive. |
---|
136 | š š š š End the game if alive snake number is less than two.""" |
---|
137 | š š š š dead_snakes =š0 |
---|
138 | š š š š foršsnake inšself.engine.snakes: |
---|
139 | š š š š š š ifšsnake ==šNone: |
---|
140 | š š š š š š š š dead_snakes=dead_snakes+1 |
---|
141 | š š š š š š š š pass |
---|
142 | š š š š ifšdead_snakes >=š3: |
---|
143 | š š š š š š self.end() |
---|
144 | š š š š š š returnšFalse |
---|
145 | š š š š |
---|
146 | š š defšsnake_len_check(self): |
---|
147 | š š š š """Get the snake with maximum length - the winer |
---|
148 | |
---|
149 | š š š š Return: |
---|
150 | š š š š winer - list of snake or snakes with max length |
---|
151 | š š š š length - this maximum length""" |
---|
152 | š š š š length=0 |
---|
153 | š š š š winer =š[] |
---|
154 | š š š š foršsnake inšself.engine.snakes: |
---|
155 | š š š š š š ifšsnake !=šNone: |
---|
156 | š š š š š š š š ifšlen(snake.cells)š>šlength: |
---|
157 | š š š š š š š š š š length =šlen(snake.cells) |
---|
158 | š š š š š š š š š š winer =š[snake] |
---|
159 | š š š š š š š š elifšlen(snake.cells)š==šlength: |
---|
160 | š š š š š š š š š š winer.append(snake)š š |
---|
161 | š š š š returnšwiner,šlength |
---|
162 | |
---|
163 | š š defšsnake_move_check(self): |
---|
164 | š š š š """Get possible movements of the snakes. |
---|
165 | š š š š If all anakes cant move - return False.""" |
---|
166 | š š š š total_moves =š0 |
---|
167 | š š š š foršsnake inšself.engine.snakes: |
---|
168 | š š š š š š ifšsnake !=šNone: |
---|
169 | š š š š š š š š legal_moves =šself.engine.legal_moves(snake) |
---|
170 | š š š š š š š š foršmove inšlegal_moves: |
---|
171 | š š š š š š š š š š total_moves =štotal_moves+1 |
---|
172 | š š š š ifštotal_moves ==š0: |
---|
173 | š š š š š š self.end() |
---|
174 | š š š š š š returnšFalse |
---|
175 | š š š š š š |
---|
176 | š š š š |
---|
177 | š š defšrestart(self,šsurvived): |
---|
178 | š š š š """"Restarts snakes positions after the end of the game |
---|
179 | |
---|
180 | š š š š Options: |
---|
181 | š š š š survived = "yes" - restarts next round only with snakes survived in previous round |
---|
182 | š š š š survived = "no" - restart next roun with all snakes played in previous round""" |
---|
183 | š š š š ifšsurvived ==š"yes": |
---|
184 | š š š š š š snake_set =šself.engine.snakes |
---|
185 | š š š š else: |
---|
186 | š š š š š š snake_set =šself.engine.psnakesš š š š š |
---|
187 | š š š š self.step_id =š0 |
---|
188 | š š š š forši,šsnake inšenumerate(snake_set): |
---|
189 | š š š š š š ifšsnake_set[i]š!=šNone: |
---|
190 | š š š š š š š š self.engine.snakes[i]š=šsnake |
---|
191 | š š š š š š š š self.engine.create_snake(i,šsnake) |
---|
192 | š š š š self.engine.refill() |
---|
193 | š š š š self.engine.redraw() |
---|
194 | |
---|
195 | š š defšendš(self): |
---|
196 | š š š š """End the round and raise the label that tels about it.""" |
---|
197 | š š š š self.run_cancel() |
---|
198 | š š š š self.step_id =šself.game_length +š666 |
---|
199 | š š š š (w,šh),š(x,šy),š_ =šself.engine.field_geometry_calc() |
---|
200 | š š š š self.engine.redraw() |
---|
201 | š š š š self.canvas.create_text(x+w/2.0,šy+h/2.0,štext="End of the round",šfill="white",šfont="bold") |
---|
202 | š š š š winer,šlength =šself.snake_len_check() |
---|
203 | š š š š ifšlen(winer)š>š1: |
---|
204 | š š š š š š self.canvas.create_text(x+w/2.0,šy+h*2.0/3.0,štext="Number of winers: %s"š%(len(winer)),šfill="white",šfont="bold") |
---|
205 | š š š š else: |
---|
206 | š š š š š š self.canvas.create_text(x+w/2.0,šy+h*2.0/3.0,štext="Winer: %s(%s)"š%(winer[0].name,šwiner[0].color),šfill="white",šfont="bold") |
---|
207 | š š š š self.canvas.create_text(x+w/2.0,šy+h*3.0/4.0,štext="Total winer length: %s"š%(length),šfill="white",šfont="bold") |
---|
208 | š š š š pass |
---|
209 | |
---|
210 | ifš__name__ ==š"__main__": |
---|
211 | š š snake_batle =šUI() |
---|
212 | š š snake_batle.root.mainloop() |
---|