Документ взят из кэша поисковой машины. Адрес оригинального документа : http://kodomo.fbb.msu.ru/hg/snake/raw-annotate/5c6edbf73eae/engine.py
Дата изменения: Unknown
Дата индексирования: Fri Feb 11 14:48:55 2011
Кодировка:

martiran@12: import random as rnd
martiran@15: import Tkinter as tk
Alex@66: import snake
martiran@12:
martiran@6: directions = [(0,1), (1,0), (0,-1), (-1,0)]
martiran@1:
martiran@111: class Dict(dict):
martiran@142: """Create a dictionary."""
martiran@111: pass
martiran@111:
martiran@5: class Cell(object):
martiran@142: """Cells.
martiran@142:
martiran@142: Atributes:
martiran@142: - 'x' - absciss of the cell in field
martiran@142: - 'y' - ordinate of the cell in field
martiran@142: - 'canvas' - Widget the cell belongs to
martiran@142: - 'snake' - snake the cell belongs to, possible values:
martiran@142: snake
martiran@142: None
martiran@142: 'my' \
martiran@142: 'enemy' / for patterns only
martiran@142:
martiran@142: - 'type' - type of the cell, possible values:
martiran@142: 'empty'
martiran@142: 'wall'
martiran@142: 'body'
martiran@142: 'head'
martiran@142: 'tail'
martiran@142: 'any' } for patterns only
martiran@142: 'void' } for cells out of the field
martiran@142: """
martiran@15: def __init__(self, x, y, canvas = None):
martiran@142: """Initialyze the cell with default parameters:
martiran@142: type = 'empty'
martiran@142: snake = None"""
martiran@1: self.x = x
martiran@1: self.y = y
martiran@1: self.canvas = canvas
martiran@1: self.snake = None
martiran@28: self.type = 'empty'
martiran@1: return
martiran@142:
martiran@113: def redraw(self, offset, c_size):
martiran@142: """Draw a cell based on it content"""
martiran@113: x0=offset[0] + self.x*c_size
martiran@113: y0=offset[1] + self.y*c_size
martiran@113: x1=offset[0] + (self.x+1)*c_size
martiran@113: y1=offset[1] + (self.y+1)*c_size
martiran@113: x2=offset[0] + (self.x+1/2.0)*c_size
martiran@15: if self.type == 'wall':
Alex@101: self.canvas.create_rectangle(x0, y0, x1, y1, fill="grey")
martiran@15: pass
martiran@15: elif self.type == 'empty':
Alex@101: self.canvas.create_rectangle(x0, y0, x1, y1, fill="black")
martiran@15: pass
martiran@15: elif self.type == 'body':
Alex@101: self.canvas.create_rectangle(x0, y0, x1, y1, fill=self.snake.color)
martiran@15: pass
martiran@15: elif self.type == 'head':
Alex@101: self.canvas.create_oval(x0, y0, x1, y1, fill=self.snake.color)
martiran@15: pass
martiran@15: elif self.type == 'tail':
Alex@101: self.canvas.create_polygon(x0, y0, x1, y0, x2, y1, fill=self.snake.color)
martiran@15: pass
martiran@15: return
martiran@142:
martiran@6: def __eq__(self, pattern):
martiran@142: """Check the equaliation of the cell to the pattern cell."""
martiran@52: if pattern.type == 'any':
martiran@6: return True
martiran@52: if pattern.type != self.type:
martiran@6: return False
martiran@52: if pattern.snake_type == 'my' and pattern.snake != self.snake:
martiran@52: return False
martiran@52: elif pattern.snake_type == 'enemy' and pattern.snake == self.snake:
martiran@52: return False
martiran@52: return True
martiran@126:
martiran@126: def __ne__(self, pattern):
martiran@142: """Check the discrepancy of the cell to the pattern cell."""
martiran@126: return not self == pattern
martiran@126:
martiran@6: def clear(self):
martiran@142: """Change the cell parameters back to default."""
martiran@1: self.snake = None
martiran@1: self.type = 'empty'
martiran@1: return
martiran@1:
martiran@2:
martiran@5: class Engine(object):
martiran@142: """Engine
martiran@142:
martiran@142: Atributes:
martiran@142:
martiran@142: - 'field' - game field:
martiran@142: 'field.w' - width of the field count in cells
martiran@142: 'field.h' - hight of the field count in cells
martiran@142: - 'canvas' - Widget game field is showing on
martiran@142: - 'snakes' - list of snakes loaded
martiran@142: - 'start_snake_length' - starting length of the snake"""
martiran@142:
martiran@6: def __init__(self, canvas):
martiran@142: """Initialyze the engine:
martiran@142: start_snake_length = 10"""
martiran@1: self.canvas = canvas
martiran@12: self.snakes = [None, None, None, None]
martiran@9: self.init_field()
martiran@111: self.start_snake_length = 10
martiran@9: return
martiran@142:
martiran@9: def init_field (self):
martiran@142: """Initialyze the field:
martiran@142: width = 31
martiran@142: hieght = 31
martiran@142: perimeter is made by walls"""
martiran@111: self.field = Dict()
martiran@117: self.field.w = 31
martiran@117: self.field.h = 31
martiran@113: f_w = self.field.w
martiran@113: f_h = self.field.h
martiran@113: for x in range(f_w):
martiran@113: for y in range(f_h):
martiran@9: self.field[x, y] = Cell(x, y, self.canvas)
martiran@113: for y in range(f_h):
martiran@9: self.field[0, y].type = 'wall'
martiran@113: self.field[f_w-1, y].type = 'wall'
martiran@113: for x in range(1,f_w-1):
martiran@9: self.field[x, 0].type = 'wall'
martiran@113: self.field[x, f_h-1].type = 'wall'
Alex@103: self.refill()
Alex@93: self.redraw()
martiran@1: return
martiran@142:
martiran@6: def step(self):
martiran@142: """Do the step of the game."""
Alex@62: for i, snake in enumerate(self.snakes):
Alex@103: if snake != None:
Alex@103: if len(snake.cells) == 0:
Alex@103: self.snakes[i] = None
Alex@103: continue
Alex@66: self.legal_moves(snake)
martiran@12: self.move_snake(snake)
martiran@12: self.refill()
martiran@9: self.redraw()
martiran@9: return
martiran@142:
martiran@9: def move_snake(self, snake):
martiran@142: """Check of movement direction based on the snake rule list and actual
martiran@142: enviroment."""
martiran@105: head = snake.cells[0]
martiran@12: for rule in snake.rules:
martiran@105: for direction in snake.legal_dir:
martiran@105: rule.rotate(direction)
martiran@105: if rule.applies(self.field, head.x, head.y) == True:
martiran@105: self.move_do(snake, direction)
martiran@105: return
martiran@105: if snake.legal_dir != []:
Alex@99: self.move_do(snake, snake.legal_dir[0])
martiran@12: pass
martiran@14: return
martiran@142:
Alex@94: def move_do(self, snake, applied_dir):
martiran@142: """Do the move of the snake."""
martiran@107: head = snake.cells[0]
martiran@107: dir_cell = self.field[head.x + applied_dir[0], head.y + applied_dir[1]]
Alex@90: if dir_cell.type == 'empty':
Alex@90: snake.cells.insert(0,dir_cell)
Alex@90: del snake.cells[-1]
Alex@90: pass
Alex@90: elif (dir_cell.type == 'tail' and dir_cell.snake != snake):
Alex@90: snake.cells.insert(0,dir_cell)
Alex@90: del dir_cell.snake.cells[-1]
Alex@90: pass
Alex@90:
martiran@6: def create_snake(self, snake_number):
martiran@142: """Create the snake:
martiran@142: position choice is based on number or placement of 'Load' button
martiran@142: color is chosen accorting to fen shui tradition"""
martiran@46: cells_id = []
martiran@113: f_h = self.field.h
martiran@113: f_w = self.field.w
martiran@111: for y in range(self.start_snake_length):
martiran@114: cells_id.append(((f_w-1)/2, y+1))
martiran@46: for rot_num in range(snake_number - 1):
Alex@62: for i, cell in enumerate(cells_id):
martiran@122: cells_id[i] = (min(f_h, f_w)-1-cell[1],cell[0])
martiran@46: cells = []
martiran@46: for cell in cells_id:
Alex@60: cells.append(self.field[cell])
martiran@46: color_dic = {
martiran@46: 1:'blue',
martiran@46: 2:'green',
martiran@46: 3:'yellow',
martiran@46: 4:'red',}
martiran@46: self.snakes[snake_number-1] = snake.Snake(cells, color_dic[snake_number])
Alex@77: return self.snakes[snake_number-1]
martiran@142:
martiran@6: def refill(self):
martiran@142: """Refill the field cells types and snakes according to the actual
martiran@142: position"""
martiran@113: f_w = self.field.w
martiran@113: f_h = self.field.h
martiran@113: for x in range(1,f_w-1):
martiran@113: for y in range(1,f_h-1):
martiran@12: self.field[x, y].type = 'empty'
martiran@31: self.field[x, y].snake = None
martiran@12: pass
martiran@12: for snake in self.snakes:
martiran@12: if snake == None:
martiran@12: pass
martiran@12: else:
martiran@31: snake.fill()
martiran@12: pass
martiran@14: return
martiran@142:
martiran@9: def redraw(self):
martiran@142: """Clear the field Widget and redraw cells images on it"""
martiran@117: self.canvas.delete("all")
martiran@113: w = self.canvas.winfo_width()
martiran@113: h = self.canvas.winfo_height()
martiran@113: cw = w/float(self.field.w)
martiran@113: ch = h/float(self.field.h)
martiran@113: c = min(cw, ch)
martiran@113: field_geometry = (self.field.w*c,self.field.h*c)
martiran@113: offset = ((w - field_geometry[0])/2.0, (h - field_geometry[1])/2.0)
martiran@32: for cell_coord in self.field:
martiran@113: self.field[cell_coord].redraw(offset, c)
martiran@15: return
martiran@142:
martiran@6: def legal_moves(self, snake):
martiran@142: """Check for snake legal move directions according to the game rules."""
martiran@6: snake.legal_dir = []
martiran@108: head = snake.cells[0]
martiran@6: for direction in directions:
martiran@108: dir_cell = self.field[head.x + direction[0], head.y + direction[1]]
martiran@12: if (dir_cell.type == 'empty' or (dir_cell.type == 'tail' and dir_cell.snake != snake)):
martiran@6: snake.legal_dir.append(direction)
Alex@90: rnd.shuffle(snake.legal_dir)
martiran@6: return
martiran@6: