| 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() |
|---|