这段时光个人几篇文章介绍了改路径教程的文章. 关联文章的地址
之前看了一副大涨势姿的贪吃蛇的图,甚为震精,可以再欣赏一下:
既然talk is cheap,show me the code ,我就按照http://hawstein.com/posts/snake-ai.html的教程写了一个,当然并没有能像上图那么人令涨势姿,但是让贪吃蛇主动跑很长时光还是做到了的
首先是照教程所说,网上下了一个可以根据方向键来控制贪吃蛇的一个码代版本,直接在下面行进造改,所以面下的码代有些地方可能有点无厘头=,=
第一步,当然是让贪吃蛇自己跑起来,这个很简单,但由于事先没仔细看教程,想想又要保存蛇和,什物之间的路径,就直接试了试dfs,码代很简单,码代很简单,但是会写码代的人就道知这不是最短路径啊!!!每次都要绕好长一圈才能到食品,这有什么意思?然后就思考了下bfs(),bfs()实确该应是最短路径了,但是用bfs怎么示表路径了,想了一会想到可以建个组数来示表点的父节点,于是bfs版本又写好了=,=能跑一段时光了,到后来才现发教程里就直接写着bfs路径的处理方法!!惋惜事先没看到,自己想一遍懂得也刻深点吧。。。。。。。
到前目的止,蛇能自己运行一段时光,但是万一蛇身的长度超越x轴或者y轴,蛇的智商就比拟捉急了,这时候由于找不到路径蛇就会直一停留在原地。
按照教程所说的,该应义定一个安全模式:在吃掉食品后,蛇头到蛇尾之间还有路径(就算蛇头到食品之间没有路径,舌头可以着跟蛇尾跑,跑动过程当中可能涌现到食品的路径)因为挪动过程当中蛇尾会直一释放出新的空间,所以每次找到到食品的路径后,该应派出一条虚拟蛇去吃食品,吃完后该应判断是否是安全,安全了派真蛇吃,不安全就着跟蛇尾跑(这里教程说跟蛇尾跑要用最长路径,本人比拟知无,用了dfs来替换),但其实在试验过程当中,种这思绪也会有bug(在现还没处理= =):就是虽然这一步你判断为安全,你朝食品进了一步,单手一步以后你现发安全了,只能着跟蛇尾跑,这样会涌现蛇直一在一个环循里跑的象现。。。。。。
实现了下面的思绪,面下是我自己的贪吃蛇的截图:
@代表蛇头,#代表蛇身,-代表蛇尾,+代表食品
talk is cheap,show me the code:
每日一道理
盈盈月光,我掬一杯最清的;落落余辉,我拥一缕最暖的;灼灼红叶,我拾一片最热的;萋萋芳草,我摘一束最灿的;漫漫人生,我要采撷世间最重的———毅力。
#!/usr/bin/python
# -*- coding: utf8 -*-
import curses, sys, random
from time import sleep
# init -------------------------------------------------------------------------
DIR_UP = 0
DIR_RIGHT = 1
DIR_DOWN = 2
DIR_LEFT = 3
directions = [[1,0],[-1,0],[0,1],[0,-1]]
field = []
snake = [[10,5], [9,5], [8,5], [7,5]]
dir = DIR_RIGHT;
food = []
grow_snake = False
is_game_over = False
paths = []
# init curses library
win = curses.initscr();
# enable arrow keys
win.keypad(1)
# do not wait for keypress
win.nodelay(1)
# hide cursor
curses.curs_set(0)
# read keys instantaneously
curses.cbreak()
# do not print stuff when key is presses
curses.noecho()
# get terminal size
rows, cols = win.getmaxyx()
rows -= 1
map = []
headX = 0
headY = 0
foodX = 0
foodY = 0
def initMap(snake1,targetX,targetY):
global map,headX,headY,foodX,foodY
map = []
for x in range(cols):
line = []
for y in range(rows):
line.append(False)
map.append(line)
for pos in snake1:
x = pos[0]
y = pos[1]
map[x][y] = True
map[targetX][targetY]=False
headX = snake1[0][0]
headY = snake1[0][1]
foodX = targetX
foodY = targetY
def bfs(targetX,targetY,snake1,trueSnake):
global map
initMap(snake1,targetX,targetY)
l = []
father = [0 for x in range(100000)]
l.append([headX,headY])
father[0] = 0
index = 0
while len(l)>index:
cur = l[index]
curX = cur[0]
curY = cur[1]
if curX == foodX and curY == foodY:
if trueSnake == True:
endPoint = index
temp = []
while endPoint != father[endPoint]:
temp.insert(0,l[endPoint])
endPoint = father[endPoint]
temp.insert(0,l[0])
return temp
break
else:
return True
for direction in directions:
nextX = curX + direction[0]
nextY = curY + direction[1]
if nextX>=0 and nextX<cols and nextY >0 and nextY<rows and map[nextX][nextY]==False:
l.append([nextX,nextY])
father[len(l)-1] = index
map[nextX][nextY]=True
index += 1
if trueSnake ==True:
return []
else:
return False
def dfsTail(targetX,targetY):
global map
initMap(snake,targetX,targetY)
map[targetX][targetY]=False
l = []
l.append([headX,headY])
while len(l)>0:
index = 0
cur = l[-1]
curX = cur[0]
curY = cur[1]
if curX == foodX and curY == foodY:
return l
break
for direction in directions:
nextX = curX + direction[0]
nextY = curY + direction[1]
if nextX>=0 and nextX<cols and nextY >0 and nextY<rows and map[nextX][nextY]==False:
l.append([nextX,nextY])
map[nextX][nextY]=True
break
else:
index += 1
if index == 4:
l.pop()
return []
def createHead(head,direction):
if direction == DIR_UP:
head = [head[0], head[1]-1]
elif direction == DIR_RIGHT:
head = [head[0]+1, head[1]]
elif direction == DIR_DOWN:
head = [head[0], head[1]+1]
elif direction == DIR_LEFT:
head = [head[0]-1, head[1]]
return head
def createDirection(diffX,diffY):
direction = 0
if diffX == 0 and diffY == -1:
direction = 0
elif diffX == 0 and diffY == 1:
direction = 2
elif diffX == 1 and diffY == 0:
direction = 1
else:
direction = 3
return direction
def isSafe(paths):
global map
count = 0
fakeSnake = snake[:]
for direction in paths:
dir = direction
head = fakeSnake[0]
count += 1
# remove tail
if count != len(paths):
fakeSnake.pop()
# calculate where head will be
head = createHead(head,dir)
fakeSnake.insert(0, head)
snakeTail = fakeSnake[-1]
initMap(fakeSnake,snakeTail[0],snakeTail[1])
return bfs(snakeTail[0],snakeTail[1],fakeSnake,False)
def nextPaths():
global paths,snake
path = bfs(food[0][0],food[0][1],snake,True)
paths = []
for x in range(1,len(path)):
diffX = path[x][0]-path[x-1][0]
diffY = path[x][1]-path[x-1][1]
direction = createDirection(diffX,diffY)
paths.append(direction)
if not isSafe(paths) or len(paths)==0:
snakeTail = snake[-1]
path = dfsTail(snakeTail[0],snakeTail[1])
paths = []
for x in range(1,len(path)):
diffX = path[x][0]-path[x-1][0]
diffY = path[x][1]-path[x-1][1]
direction = createDirection(diffX,diffY)
paths.append(direction)
# redraw and refresh entire screen
def redraw():
win.erase()
drawCaption(" snake "+str(len(snake))+" ")
drawFood()
drawSnake()
win.refresh()
# draw top border with specified text
def drawCaption(text):
global cols
win.addstr(0, 0, "." * cols)
win.addstr(0, (cols - len(text)) / 2, text)
# draw snake
def drawSnake():
try:
n = 0
for pos in snake:
if n == 0:
win.addstr(pos[1], pos[0], "@")
elif n == len(snake)-1:
win.addstr(pos[1], pos[0], "-")
else:
win.addstr(pos[1], pos[0], "#")
n += 1
except:
pass
# draw all the food
def drawFood():
try:
for pos in food:
win.addstr(pos[1], pos[0], "+")
except:
pass
# check if snake has just eaten the food
def isFoodCollision():
for pos in food:
if pos == snake[0]:
food.remove(pos)
return True
return False
# check if snake has just commited suicide
def isSuicide():
for i in xrange(0, len(snake)):
if i > 0 and snake[i] == snake[0]:
return True
return False
# end game gracefully
def endGame():
curses.nocbreak();
win.keypad(0);
curses.echo()
curses.endwin()
# move snake one step forward
def moveSnake():
global snake
global grow_snake
global cols, rows
# get head
head = snake[0]
# remove tail
if (grow_snake == False):
snake.pop()
else:
grow_snake = False
# calculate where head will be
head = createHead(head,dir)
# insert new head
snake.insert(0, head)
# drop new food, but not on snake or on another food
def dropFood():
x = random.randint(0, cols-1)
y = random.randint(1, rows-1)
for pos in food:
if pos == [x,y]:
dropFood()
return
for pos in snake:
if pos == [x,y]:
dropFood()
return
f = open('record.txt','w')
f.write('food: '+str(x)+' '+str(y)+'\n')
food.append([x,y])
# stop all the action and print the sad news
def gameOver():
global is_game_over
is_game_over = True
drawCaption("game over")
# start -------------------------------------------------------------------------
dropFood()
redraw()
while (True):
if is_game_over == False:
redraw()
key = win.getch()
nextPaths()
dir = paths[0]
if (isSuicide()):
gameOver()
if (isFoodCollision()):
dropFood()
grow_snake = True
moveSnake()
else:
break
endGame()
意注windows下要装安curse才能运行
文章结束给大家分享下程序员的一些笑话语录: IBM和波音777
波音777是有史以来第一架完全在电脑虚拟现实中设计制造的飞机,所用的设备完全由IBM公司所提供。试飞前,波音公司的总裁非常热情的邀请IBM的技术主管去参加试飞,可那位主管却说道:“啊,非常荣幸,可惜那天是我妻子的生日,So..”..
波音公司的总载一听就生气了:“胆小鬼,我还没告诉你试飞的日期呢!”