• 路径教程[置顶] 用python制造一条令人涨姿势的贪吃蛇


    这段时光个人几篇文章介绍了改路径教程的文章. 关联文章的地址

        之前看了一副大涨势姿的贪吃蛇的图,甚为震精,可以再欣赏一下:

        

        既然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..”..
      波音公司的总载一听就生气了:“胆小鬼,我还没告诉你试飞的日期呢!”

  • 相关阅读:
    做最简单的自定义控件!
    DataGridView取消默认选中行
    好看的vs皮肤
    rdlc插入图像(.net2010)
    学习c#反射的一个例子
    C#Winform中ToolTip的简单用法
    rdlc报表显示条码 .
    vb.net ctype用法
    一些常用的正则表达式 .
    C# WinForm中MenuStrip动态菜单使用总结
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3050622.html
Copyright © 2020-2023  润新知