[Tutor] engines
Gregor Lingl
glingl@aon.at
Fri, 19 Jul 2002 07:58:58 +0200
This is a multi-part message in MIME format.
--------------030100030702070606010305
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
Marc schrieb:
>I noticed that you named variables with english/german words.
>Well, I can barely read english, let alone german.
>So, can u send me a translated version? *grin*.
>Maybe post it on list again.Im sure several people will be interested
>in your code.
>
Here it is!
Gregor
--------------030100030702070606010305
Content-Type: text/plain;
name="esnake.py"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="esnake.py"
""" snake - OOP training (V. OOP12) - ENGLISH VERSION
author: gregor lingl, vienna. email: glingl@aon.at """
from Tkinter import *
from Canvas import Rectangle
import sys, random
class Gameboard(Canvas):
def __init__(self, root, NX, NY, fieldwidth=12, **kwargs):
Canvas.__init__(self, root, kwargs)
w,h = NX*fieldwidth, NY*fieldwidth
self.config(width=w+2, height=h+2, bg = 'yellow')
self.grid = {}
for row in range(NY):
for column in range(NX):
x0 = 2 + column * fieldwidth
y0 = 2 + row * fieldwidth
x1 = x0 + fieldwidth
y1 = y0 + fieldwidth
r = Rectangle(self, x0, y0, x1, y1,
fill='yellow', outline='yellow' )
self.grid[(column,row)] = r
def set(self,field,colour):
self.grid[field]['fill'] = colour
class Snake:
def __init__(self, size):
self.N = size
self.food = None
self.reset()
def reset(self):
self.snake= [(self.N/2,self.N/2)]
self.food = None
self.newFood()
self.direction = None
self.alive = 1
def newFood(self):
while not self.food or self.food in self.snake:
self.food = (random.randrange(self.N), random.randrange(self.N))
def getscore(self):
return "Score: " + str(max(0,len(self.snake)-4))
def cutoffTail(self):
self.snake = self.snake[1:]
def newHead(self,field):
self.snake.append(field)
def nextField(self):
x,y = self.snake[-1]
if self.direction == 'Up':
y=y-1
elif self.direction == 'Down':
y=y+1
elif self.direction == 'Left':
x=x-1
elif self.direction == 'Right':
x=x+1
else:
return None
return (x,y)
def onBoard(self, next):
x,y=next
return 0 <= x < self.N and 0 <= y < self.N
def step(self, newDirection):
changed = {}
if newDirection:
if (newDirection,self.direction) not in (('Up','Down'),('Down','Up'),
('Right','Left'),('Left','Right')):
self.direction = newDirection
next = self.nextField()
# Case 1: hit edge or bit herself
if not self.onBoard(next) or next in self.snake:
self.alive = 0
for member in self.snake:
changed[member]='black'
# Fall 2: food found
elif next == self.food:
self.newHead(next)
changed[next]='red'
self.newFood()
changed[self.food]='blue'
# Fall 3: normal step
else:
if len(self.snake) > 3:
changed[self.snake[0]]='yellow'
self.cutoffTail()
self.newHead(next)
changed[next]='red'
return changed
class SnakeEngine:
def __init__(self, N):
self.N = N
root = Tk()
root.title("SNAKE")
root.bind('<KeyPress>', self.taste)
self.board = Gameboard(root,N,N)
self.board.pack()
self.scorelabel = Label(root,width=22,text="",font=("Courier",14,"bold"),fg='red')
self.hintlabel = Label(root,width=22,text="",font=("Courier",14,"normal"))
self.scorelabel.pack()
self.hintlabel.pack()
self.snake = Snake(N)
self.reset()
def taste(self,event):
key = event.keysym
if key == 'Return':
sys.exit(0)
if key in ['Up','Down','Left','Right','space']:
self.eventlist.append(key)
def reset(self):
for field in self.board.grid:
self.board.set(field,'yellow')
self.eventlist = []
self.state = "waiting"
self.snake.reset()
self.board.set(self.snake.snake[0],'red')
self.board.set(self.snake.food,'blue')
self.board.update()
self.hintlabel.config(text="Control: arrow keys")
self.scorelabel.config(text=self.snake.getscore())
def run(self):
changed = {}
taste = None
if self.eventlist:
taste = self.eventlist[0]
self.eventlist = self.eventlist[1:]
if self.state == "waiting":
if taste in ['Up','Down','Right','Left']:
self.state = "running"
if self.state == "running":
if taste in ['Up','Down','Right','Left', None]:
changed = self.snake.step(taste)
self.scorelabel.config(text=self.snake.getscore())
if not self.snake.alive:
self.state="over"
self.hintlabel.config(text="New game: space bar")
elif self.state == "over":
if taste == 'space':
self.reset()
for field in changed:
self.board.set(field, changed[field])
self.board.update()
self.board.after(100, self.run)
SnakeEngine(21).run()
mainloop()
--------------030100030702070606010305--