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