Документ взят из кэша поисковой машины. Адрес оригинального документа : http://kodomo.cmm.msu.ru/trac/snake/browser/main.py?format=txt
Дата изменения: Tue Dec 28 17:01:41 2010
Дата индексирования: Fri Feb 11 15:10:06 2011
Кодировка:
import Tkinter as tk
import tkFileDialog as tkfd
import engine
import snake



class UI(object):
"""User Interface:

Atributes:

- 'root' - root Window game placed at
- 'engine' - engine of the game
- 'canvas' - Widget field is pictured at
- 'step_id' - current step of the game
- 'after_id' - identificator of runing game process
- 'step_legth' - length of the step (in ms)
- 'game_length' - number of the steps in one round of the game"""
def __init__ (self):
"""Create Python Battle game window.
Initialyze engige of the game."""
self.root = tk.Tk()
self.root.title("Python Battle")
self.canvas = tk.Canvas(self.root, background = "black")
self.canvas.pack(side ="top", fill="both", expand="yes")
self.buttons_pack(self.root).pack(side ="bottom", fill="both", expand="no")
self.step_id = 0
self.engine = engine.Engine(self.canvas)
self.after_id = None
self.step_length = 150
self.game_length = 200
return

def buttons_pack(self, root):
"""Packing the buttons in root frame.
Definition of button functions.

'Load' - ask for snake file load
'Run' - runs the game/next round. Next round starts with snakes survived in previous
'Step' - do the next dtep of the game
'End' - manual end of the game
'Restart" - restart the field with snakes of previous round"""
buttons = tk.Frame(root)
load_1 = tk.Button(buttons, text="Load 1", command=lambda: self.load(0))
load_1.grid(row=1, column=2, stick="news")
load_2 = tk.Button(buttons, text="Load 2", command=lambda: self.load(1))
load_2.grid(row=2, column=3, stick="news")
run_b = tk.Button(buttons, text="Run", command=lambda: self.start())
run_b.grid(row=2, column=2, stick="news")
restart_b = tk.Button(buttons, text="Restart", command=lambda: self.restart(survived="no"))
restart_b.grid(row=1, column=5, stick="news")
load_3 = tk.Button(buttons, text="Load 3", command=lambda: self.load(2))
load_3.grid(row=3, column=2, stick="news")
load_4 = tk.Button(buttons, text="Load 4", command=lambda: self.load(3))
load_4.grid(row=2, column=1, stick="news")
step_b = tk.Button(buttons, text="Step", command=lambda: self.step())
step_b.grid(row=2, column=5, stick="news")
end_b = tk.Button(buttons, text="End", command=lambda: self.end())
end_b.grid(row=3, column=5, stick="news")
for column in range(1, 6):
buttons.grid_columnconfigure(column, weight=1)
return buttons

def load (self, snake_number):
"""Ask for snake file loading.
Initialyzing snake and draw it on the field.
Return field back to default (without snakes) after end of the game."""
if self.step_id == self.game_length + 666:
self.step_id = 0
self.engine.snakes = [None, None, None, None]
pass
if self.step_id == 0:
file = tkfd.askopenfile(title="Open file")
if file == None:
return
snake = self.engine.create_snake(snake_number)
snake.load(file)
pass
self.engine.refill()
self.engine.redraw()
return

def start (self):
"""Init running of the game."""
if self.after_id != None:
return
if self.step_id == self.game_length + 666:
self.restart(survived="yes")
if self.step_id == 0:
self.engine.psnakes = self.engine.snakes[:]
self.run()

def run (self):
"""Run the game with 'step_length' ms step
After the end of the game - restarts it with snakes survived in
previous game"""
if self.step_id > self.game_length:
self.end()
return
if self.snake_dead_check() == False:
return
if self.snake_move_check() == False:
return
self.step_id = self.step_id+1
self.engine.step()
self.after_id = self.canvas.after(self.step_length, self.run)
return

def step (self):
"""Do the next game step"""
if self.snake_dead_check() == False:
return
if self.snake_move_check() == False:
return
if self.step_id == 0:
self.engine.psnakes = self.engine.snakes[:]
if self.step_id <= self.game_length:
self.run_cancel()
self.step_id = self.step_id+1
self.engine.step()
pass
else:
self.end()
pass
return

def run_cancel(self):
"""Stops runnin of the game"""
if self.after_id != None:
self.canvas.after_cancel(self.after_id)
self.after_id = None

def snake_dead_check(self):
"""Check the number of snakes alive.
End the game if alive snake number is less than two."""
dead_snakes = 0
for snake in self.engine.snakes:
if snake == None:
dead_snakes=dead_snakes+1
pass
if dead_snakes >= 3:
self.end()
return False

def snake_len_check(self):
"""Get the snake with maximum length - the winer

Return:
winer - list of snake or snakes with max length
length - this maximum length"""
length=0
winer = []
for snake in self.engine.snakes:
if snake != None:
if len(snake.cells) > length:
length = len(snake.cells)
winer = [snake]
elif len(snake.cells) == length:
winer.append(snake)
return winer, length

def snake_move_check(self):
"""Get possible movements of the snakes.
If all anakes cant move - return False."""
total_moves = 0
for snake in self.engine.snakes:
if snake != None:
legal_moves = self.engine.legal_moves(snake)
for move in legal_moves:
total_moves = total_moves+1
if total_moves == 0:
self.end()
return False


def restart(self, survived):
""""Restarts snakes positions after the end of the game

Options:
survived = "yes" - restarts next round only with snakes survived in previous round
survived = "no" - restart next roun with all snakes played in previous round"""
if survived == "yes":
snake_set = self.engine.snakes
else:
snake_set = self.engine.psnakes
self.step_id = 0
for i, snake in enumerate(snake_set):
if snake_set[i] != None:
self.engine.snakes[i] = snake
self.engine.create_snake(i, snake)
self.engine.refill()
self.engine.redraw()

def end (self):
"""End the round and raise the label that tels about it."""
self.run_cancel()
self.step_id = self.game_length + 666
(w, h), (x, y), _ = self.engine.field_geometry_calc()
self.engine.redraw()
self.canvas.create_text(x+w/2.0, y+h/2.0, text="End of the round", fill="white", font="bold")
winer, length = self.snake_len_check()
if len(winer) > 1:
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")
else:
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")
self.canvas.create_text(x+w/2.0, y+h*3.0/4.0, text="Total winer length: %s" %(length), fill="white", font="bold")
pass

if __name__ == "__main__":
snake_batle = UI()
snake_batle.root.mainloop()