| 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@166
|
86 if self.step_id == self.game_length + 666: |
|
Alex@167
|
87 self.restart(survived="yes") |
|
Alex@174
|
88 if self.step_id == 0: |
|
Alex@174
|
89 self.engine.psnakes = self.engine.snakes[:] |
|
Alex@165
|
90 self.run() |
|
Alex@165
|
91 |
|
Alex@165
|
92 def run (self): |
|
Alex@165
|
93 """Run the game with 'step_length' ms step |
|
Alex@165
|
94 After the end of the game - restarts it with snakes survived in |
|
Alex@165
|
95 previous game""" |
|
Alex@168
|
96 if self.step_id > self.game_length: |
|
Alex@168
|
97 self.end() |
|
Alex@168
|
98 return |
|
Alex@172
|
99 if self.dead_snake_check() == False: |
|
Alex@172
|
100 return |
|
martiran@32
|
101 self.step_id = self.step_id+1 |
|
martiran@28
|
102 self.engine.step() |
|
Alex@160
|
103 self.after_id = self.canvas.after(self.step_length, self.run) |
|
martiran@28
|
104 return |
|
Alex@160
|
105 |
|
martiran@28
|
106 def step (self): |
|
martiran@136
|
107 """Do the next game step""" |
|
Alex@97
|
108 if self.dead_snake_check() == False: |
|
Alex@97
|
109 return |
|
Alex@173
|
110 if self.step_id == 0: |
|
Alex@173
|
111 self.engine.psnakes = self.engine.snakes[:] |
|
Alex@166
|
112 if self.step_id <= self.game_length: |
|
martiran@32
|
113 if self.after_id != None: |
|
martiran@32
|
114 self.canvas.after_cancel(self.after_id) |
|
martiran@32
|
115 pass |
|
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@97
|
123 |
|
Alex@97
|
124 def dead_snake_check(self): |
|
martiran@136
|
125 """Check the number of snakes alive. |
|
martiran@136
|
126 End the game if alive snake number is less than two.""" |
|
Alex@97
|
127 dead_snakes = 0 |
|
Alex@97
|
128 for snake in self.engine.snakes: |
|
Alex@97
|
129 if snake == None: |
|
Alex@97
|
130 dead_snakes=dead_snakes+1 |
|
Alex@97
|
131 pass |
|
Alex@97
|
132 if dead_snakes >= 3: |
|
Alex@97
|
133 self.end() |
|
Alex@97
|
134 return False |
|
Alex@160
|
135 |
|
Alex@167
|
136 def restart(self, survived): |
|
Alex@167
|
137 """"Restarts snakes positions after the end of the game |
|
Alex@167
|
138 |
|
Alex@167
|
139 Options: |
|
Alex@167
|
140 survived = "yes" - restarts next round only with snakes survived in previous round |
|
Alex@167
|
141 survived = "no" - restart next roun with all snakes played in previous round""" |
|
Alex@167
|
142 if survived == "yes": |
|
Alex@167
|
143 snake_set = self.engine.snakes |
|
Alex@167
|
144 else: |
|
Alex@167
|
145 snake_set = self.engine.psnakes |
|
Alex@163
|
146 self.step_id = 0 |
|
Alex@167
|
147 for i, snake in enumerate(snake_set): |
|
Alex@167
|
148 if snake_set[i] != None: |
|
Alex@163
|
149 self.engine.snakes[i] = snake |
|
Alex@163
|
150 self.engine.create_snake(i, snake) |
|
Alex@163
|
151 self.engine.refill() |
|
Alex@163
|
152 self.engine.redraw() |
|
Alex@23
|
153 |
|
martiran@28
|
154 def end (self): |
|
martiran@136
|
155 """End the game and raise the window that tels about it.""" |
|
Alex@60
|
156 if self.after_id != None: |
|
Alex@60
|
157 self.canvas.after_cancel(self.after_id) |
|
Alex@60
|
158 pass |
|
Alex@166
|
159 self.step_id = self.game_length + 666 |
|
martiran@29
|
160 root = tk.Tk() |
|
martiran@29
|
161 end_label = tk.Label(root, text="End") |
|
martiran@29
|
162 end_label.pack() |
|
martiran@29
|
163 root.mainloop() |
|
martiran@18
|
164 pass |
|
martiran@32
|
165 |
|
me@42
|
166 if __name__ == "__main__": |
|
me@42
|
167 snake_batle = UI() |
|
me@42
|
168 snake_batle.root.mainloop() |