Python 3.3 - Non golfé
Je n'ai pas joué au golf du tout, car j'étais plus intéressé à faire fonctionner un beau jeu en premier. Je suis en fait totalement nouveau sur Tk, donc si quelqu'un a des suggestions, je les apprécierais vraiment. Les vitesses fonctionnent désormais correctement. Faites-moi savoir si vous souhaitez voir des fonctionnalités supplémentaires, par exemple des couleurs.
Code
import tkinter as tk
import queue
import random
class Lane():
def __init__(self, row=-1, lanetype="none", direction=0, speed=0, width=0, maxnumber=0, replenish=0, length=0, gap=0):
self.row = row
self.type = lanetype
self.direction = direction
self.speed = speed
self.width = width
self.maxnumber = maxnumber
self.replenish = replenish
self.length = length
self.gap = gap
self.lanelastupdate = 0
self.objects = []
if(self.type == "car"):
for index in range(self.width):
if(len(self.objects) == self.maxnumber):
break
if((self.maxnumber - len(self.objects) == self.width - index) or random.random() < self.maxnumber/self.width):
self.objects.append([index*self.direction + int((self.width-1)/2 - (self.width-1)*self.direction/2), self.row])
if(self.type == "log" or self.type == "turtle"):
if(self.direction == 1):
start = 0
else:
start = self.width - 1
lengthcounter = 0
gapcounter = 0
for index in range(self.width):
if(lengthcounter < self.length):
self.objects.append([start + index*self.direction, self.row])
lengthcounter += 1
else:
gapcounter += 1
if(gapcounter == self.gap):
lengthcounter = 0
gapcounter = 0
### end of __init__ ###
### end of Lane class ###
class Frogger():
def __init__(self):
# configure 'global' variables
self.directions = ['Up', 'Down', 'Left', 'Right']
self.width = 25
self.height = 13
self.frogstart = [12, 12]
self.pointsforup = 10
self.pointsforhome = 500
self.pointsforbug = 200
self.timerthreshold = 1000
self.timerstart = 60
self.speedchange = 2
self.waterbordertop = 1
self.waterborderbottom = 5
self.minspeed = 10
self.maxspeed = 15
self.minbugspeed = 50
self.maxbugspeed = 100
self.timerspeed = 20
# configure program state variables
self.q = queue.Queue(maxsize=1)
self.updateticks = 0
# configure game variables
self.gameover = False
self.speedup = 0
self.timer = self.timerstart
self.lives = 3
self.score = 0
self.frogposition = [0, 0]
self.frogposition[0] = self.frogstart[0]
self.frogposition[1] = self.frogstart[1]
self.highest = 12
self.movedup = False
# configure the lanes of cars, logs, and turtles
self.init_lanes()
# configure the homes and the bug
self.init_special()
# configure TK window
self.root = tk.Tk()
self.label = tk.Label(text="Score: "+str(self.score)+" Lives: "+str(self.lives)+" Time: "+str(self.timer))
self.label.pack()
self.text = tk.Text(self.root, width=self.width, height=self.height, font=("Courier New", 14))
self.text.bind("<Key>", self.key_event)
self.text.focus_set()
self.text.pack()
# configure drawing sprites
self.init_sprites()
# run the game
self.update_clock()
self.process_world()
self.root.mainloop()
### end of init ###
def init_sprites(self):
self.symbols = {"frog":chr(0x238), "rightcar":chr(187), "leftcar":chr(171), "turtle":chr(920), "log":chr(685), "bug":chr(1217), "grass":chr(993), "freehome":chr(164), "fullhome":"@", "road":"-", "water":chr(0x2248), "saferow":"*"}
self.sprites = {value:key for key, value in self.symbols.items()}
self.text.tag_configure("frog", foreground="chartreuse", background="dark green")
self.text.tag_configure("rightcar", foreground="yellow", background="black")
self.text.tag_configure("leftcar", foreground="yellow", background="black")
self.text.tag_configure("turtle", foreground="orange red", background="cyan")
self.text.tag_configure("log", foreground="sienna", background="cyan")
self.text.tag_configure("bug", foreground="maroon", background="green")
self.text.tag_configure("grass", foreground="orange", background="green")
self.text.tag_configure("freehome", foreground="forest green", background="green")
self.text.tag_configure("fullhome", foreground="red", background="green")
self.text.tag_configure("road", foreground="gray", background="black")
self.text.tag_configure("water", foreground="navy", background="cyan")
self.text.tag_configure("saferow", foreground="pink", background="black")
### end of init_sprites ###
def update_clock(self):
self.timer -= 1
self.label.configure(text="Score: "+str(self.score)+" Lives: "+str(self.lives)+" Time: "+str(self.timer))
if(self.gameover == False):
self.root.after(max(1, self.timerthreshold - self.speedup), self.update_clock)
### end of update_clock ###
def key_event(self, event):
direction = event.keysym
if(direction in self.directions):
try:
self.q.put(direction, block=False)
except:
pass
### end of key_event ###
def process_world(self):
# acquire user input and process it if necessary
if(self.q.qsize() > 0):
self.move_frog(self.q.get())
# update the state of non-frog objects
self.update_world()
# draw the world
self.draw_world()
# schedule another pass unless the game is over
if(self.gameover == False):
self.root.after(self.timerspeed, self.process_world)
else:
self.root.after(self.timerspeed, self.gameover_screen)
### end of process_world ###
def move_frog(self, d):
x = self.frogposition[0]
y = self.frogposition[1]
if(d == 'Up'):
y -= 1
elif(d == 'Down'):
y += 1
elif(d == 'Left'):
x -= 1
else:
x += 1
if(x >= 0 and y >= 0 and x < self.width and y < self.height):
self.frogposition[0] = x
self.frogposition[1] = y
self.movedup = False
if(d == 'Up' and y < self.highest):
self.movedup = True
### end of move_frog ###
def gameover_screen(self):
self.label2 = tk.Label(text="Game over! Your score was: " + str(self.score))
self.label2.pack()
### end of gameover_screen ###
def update_world(self):
# update the internal timer
self.updateticks += 1
# check for loss conditions
if((self.timer == 0) or self.hit_by_car() == True or self.in_water() == True or self.home_twice() == True or self.in_grass() == True):
self.process_death()
return
# credit good moves up
if(self.movedup == True):
self.score += self.pointsforup
self.highest = self.frogposition[1]
self.movedup = False
# check for win condition
if(self.at_home() == True):
self.process_victory()
return
# check for total win
if(self.all_done() == True):
self.process_win()
return
# update the positions of the cars, logs, and turtles
self.update_positions()
### end of update_world ###
def all_done(self):
if(len([x for x in self.homes if x[1]==False])==0):
return True
return False
### end of all_done ###
def process_win(self):
self.gameover = True
return
### end of process_win ###
def process_death(self):
self.lives -= 1
if(self.lives < 1):
self.gameover = True
return
self.frogposition[0] = self.frogstart[0]
self.frogposition[1] = self.frogstart[1]
self.highest = 12
self.timer = self.timerstart
### end of process_death ###
def hit_by_car(self):
for lane in self.lanes:
if(lane.type != "car"):
continue
for car in lane.objects:
if(car == self.frogposition):
return True
return False
### end of hit_by_car
def in_water(self):
if(self.frogposition[1] < self.waterbordertop or self.frogposition[1] > self.waterborderbottom):
return False
for lane in self.lanes:
if(lane.type == "turtle"):
for turtle in lane.objects:
if(turtle == self.frogposition):
return False
elif(lane.type == "log"):
for log in lane.objects:
if(log == self.frogposition):
return False
return True
### end of in_water
def home_twice(self):
for h in self.homes:
if(h[0] == self.frogposition and h[1] == True):
return True
return False
### end of home_twice
def in_grass(self):
if(self.frogposition[1] == 0 and self.at_home() == False):
return True
return False
### end of in_grass
def at_home(self):
for h in self.homes:
if(h[0] == self.frogposition):
return True
return False
### end of at_home ###
def process_victory(self):
self.score += self.pointsforhome
if(self.bugposition == self.frogposition):
self.score += self.pointsforbug
for h in self.homes:
if (h[0] == self.frogposition):
h[1] = True
break
self.timer = self.timerstart
self.frogposition[0] = self.frogstart[0]
self.frogposition[1] = self.frogstart[1]
self.highest = 12
self.speedup += self.speedchange
### end of process_victory ###
def init_lanes(self):
random.seed()
self.lanes = []
self.lanes.append(Lane(row=11, lanetype="car", maxnumber=10, replenish=0.1, direction=1, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
self.lanes.append(Lane(row=10, lanetype="car", maxnumber=8, replenish=0.2, direction=-1, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
self.lanes.append(Lane(row=9, lanetype="car", maxnumber=5, replenish=0.6, direction=1, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
self.lanes.append(Lane(row=8, lanetype="car", maxnumber=9, replenish=0.4, direction=-1, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
self.lanes.append(Lane(row=7, lanetype="car", maxnumber=6, replenish=0.3, direction=1, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
self.lanes.append(Lane(row=5, lanetype="turtle", direction=-1, length=3, gap=4, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
self.lanes.append(Lane(row=4, lanetype="log", direction=1, length=3, gap=3, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
self.lanes.append(Lane(row=3, lanetype="log", direction=-1, length=8, gap=9, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
self.lanes.append(Lane(row=2, lanetype="turtle", direction=1, length=2, gap=6, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
self.lanes.append(Lane(row=1, lanetype="log", direction=-1, length=4, gap=4, width=self.width, speed=random.randint(self.minspeed, self.maxspeed)))
### end of init_lanes
def init_special(self):
self.bugposition = [2, 0]
self.buglastupdate = 0
self.bugspeed = random.randint(self.minbugspeed, self.maxbugspeed)
self.homes = [[[2, 0], False], [[7, 0], False], [[12, 0], False], [[17, 0], False], [[22, 0], False]]
### end of init_special ###
def update_positions(self):
if(self.updateticks - self.buglastupdate >= self.bugspeed - self.speedup):
self.buglastupdate = self.updateticks
while(True):
freeslots = [x for x in self.homes if x[1] == False]
if(len(freeslots)==0):
self.bugposition = [-1,-1]
break
if(len(freeslots)==1):
self.bugposition = freeslots[0][0]
break
newhomeindex = random.randint(0, 4)
if(self.homes[newhomeindex][0] != self.bugposition and self.homes[newhomeindex][1] == False):
self.bugposition = self.homes[newhomeindex][0]
break
for lane in self.lanes:
lanemovedfrog=False
if(self.updateticks - lane.lanelastupdate >= lane.speed - self.speedup):
lane.lanelastupdate = self.updateticks
else:
continue
for o in lane.objects:
if(o == self.frogposition and lanemovedfrog==False):
self.move_frog(self.directions[int(0.5*lane.direction + 2.5)])
lanemovedfrog=True
o[0] += lane.direction
if((o[0] < 0) or (o[0] >= self.width)):
lane.objects.remove(o)
if(lane.type == "car" and len(lane.objects) < lane.maxnumber and random.random() < lane.replenish):
lane.objects.append([int((self.width-1)/2 - (self.width-1)*lane.direction/2), lane.row])
if(lane.type == "log" or lane.type == "turtle"):
if(lane.direction == 1):
start = min([x[0] for x in lane.objects])
nxt = min([x for x in range(start, self.width) if (len([y for y in lane.objects if y[0] == x]) == 0)])
if(start >= lane.gap or (nxt - start) < lane.length):
lane.objects.append([0, lane.row])
else:
start = max([x[0] for x in lane.objects])
nxt = max([x for x in range(start, -1, -1) if (len([y for y in lane.objects if y[0] == x]) == 0)])
if(self.width - start - 1 >= lane.gap or (start - nxt) < lane.length):
lane.objects.append([self.width - 1, lane.row])
lane.objects.sort()
### end of update_positions ###
def draw_world(self):
self.text.state = "normal"
self.text.delete('1.0', str(self.width + 1) + '.' + '0')
drawstr = ""
# draw home row
newstr = self.symbols["grass"] * self.width
for h in self.homes:
if(h[1] == False):
if(self.bugposition == h[0]):
newstr = self.str_replace(newstr, h[0][0], self.symbols["bug"])
else:
newstr = self.str_replace(newstr, h[0][0], self.symbols["freehome"])
else:
newstr = self.str_replace(newstr, h[0][0], self.symbols["fullhome"])
drawstr += newstr
drawstr += "\n"
# draw water rows
for index in range(self.waterborderbottom - self.waterbordertop + 1):
newstr = self.symbols["water"] * self.width
for lane in self.lanes:
if(lane.row == index + self.waterbordertop):
for o in lane.objects:
if(lane.type == "log"):
newstr = self.str_replace(newstr, o[0], self.symbols["log"])
elif(lane.type == "turtle"):
newstr = self.str_replace(newstr, o[0], self.symbols["turtle"])
drawstr += newstr
drawstr += "\n"
# draw safe row
drawstr += self.symbols["saferow"] * self.width
drawstr += "\n"
# draw car rows
for index in range(len([l for l in self.lanes if l.type == "car"])):
newstr = self.symbols["road"] * self.width
for lane in self.lanes:
if(lane.row == self.waterborderbottom + 2 +index):
for o in lane.objects:
if(lane.direction == 1):
newstr = self.str_replace(newstr, o[0], self.symbols["rightcar"])
elif(lane.direction == -1):
newstr = self.str_replace(newstr, o[0], self.symbols["leftcar"])
drawstr += newstr
drawstr += "\n"
# draw safe row
drawstr += self.symbols["saferow"] * self.width
# do actual drawing
self.text.insert('1.0', drawstr)
# draw frog
self.text.delete(str(1 + self.frogposition[1]) + '.' + str(self.frogposition[0]))
self.text.insert(str(1 + self.frogposition[1]) + '.' + str(self.frogposition[0]), self.symbols["frog"])
# apply colors
for sprite in self.sprites.keys():
self.highlight_pattern(sprite, self.sprites[sprite])
# turn off editability
self.text.state = "disabled"
### end of draw_world ###
def str_replace(self, targetstr, index, char):
return targetstr[:index] + char + targetstr[index+1:]
### end of str_replace ###
def highlight_pattern(self, sprite, tag):
start = self.text.index("1.0")
end = self.text.index("end")
self.text.mark_set("matchStart", start)
self.text.mark_set("matchEnd", start)
self.text.mark_set("searchLimit", end)
count = tk.IntVar()
while True:
index = self.text.search(sprite, "matchEnd", "searchLimit", count=count, regexp=False)
if(index == ""):
break
self.text.mark_set("matchStart", index)
self.text.mark_set("matchEnd", "%s+%sc" % (index, count.get()))
self.text.tag_add(tag, "matchStart","matchEnd")
### end of highlight_pattern ###
### end of Frogger class ###
# Run the game!!!
frogger = Frogger()