自己写的贪吃蛇(4)

本文介绍了一款贪吃蛇游戏中实现AI路径寻找的方法。通过不断优化算法,解决了红块出现在蛇身上的情况下无法找到最短路径的问题,并通过创建假蛇预判蛇吃下食物后的状态进一步提升了算法的有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

增加一个最短路径的显示,让蛇移动的直观点
修改doAI如下

function SnakeGame:doAI(target)
    if #self.targetLines > 0 then
        return
    end
    target = target or self.tail   
    for k, v in ipairs(self.lineSquare) do 
        v:removeFromParent()
    end
    self.lineSquare = {}   
    local closed = self:checkAWay(self.snakes, target)
    if closed then
        self.targetLines = {}
        table.insert(self.targetLines, closed[#closed].dir)
        local parent = closed[#closed].parent
        local ii = 1            
        while parent and parent ~= closed[1] do
            local index = parent.index            
            local x = self.cells[index]
            table.insert(self.targetLines, parent.dir)
            if target == self.tail then
                table.insert(self.fakeSnakes, parent)
            end
            -- 显示最短路径
            local m = tsixi.TLabel:create(ii, 14, cc.c3b(0, 0,0))
            m:setPosition(x)
            m:setAnchorPoint(0,0)
            self:addChild(m)
            table.insert(self.lineSquare, m)
            ii = ii + 1
            parent = parent.parent
        end          
    else
        print("not find a way!")
    end
end

这里写图片描述

当生成的红块在蛇身体部位时,最短路径就找不到。
可以这样处理,当找不到最短路径时,先让蛇去找自己的尾巴的一个最短路径,然后再去找红块的最短路径
修改doAI

function SnakeGame:doAI(target)
    if #self.targetLines > 0 then
        return
    end
    target = target or self.tail    
    for k, v in ipairs(self.lineSquare) do 
        v:removeFromParent()
    end
    self.lineSquare = {}  
    local closed = self:checkAWay(self.snakes, target)
    if closed then
        self.targetLines = {}
        table.insert(self.targetLines, closed[#closed].dir)
        local parent = closed[#closed].parent
        local ii = 1            
        while parent and parent ~= closed[1] do
            local index = parent.index            
            local x = self.cells[index]
            table.insert(self.targetLines, parent.dir)
            if target == self.tail then
                table.insert(self.fakeSnakes, parent)
            end
            -- 显示最短路径
            local m = tsixi.TLabel:create(ii, 14, cc.c3b(0, 0,0))
            m:setPosition(x)
            m:setAnchorPoint(0,0)
            self:addChild(m)
            table.insert(self.lineSquare, m)
            ii = ii + 1
            parent = parent.parent
        end          
    else
        print("not find a way!")
        -- 去搜寻到尾巴的最短路径
        self:doAI(self.snakes[#self.snakes])
    end
end

同时修改onEnter让它在搜寻尾巴最短路径后再去搜寻红块

function SnakeGame:onEnter()
    local time1 = tsixi.THelper:currentMilliseconds()
    local update = function(dt)
        if not self.is_failed then
            local now = tsixi.THelper:currentMilliseconds()
            if not self.parse and (now - time1 >= 50 or self.must) then
                self.must = false
                time1 = now
                self.direction = self.targetLines[#self.targetLines]
                table.remove(self.targetLines)
                if self.direction == nil then
                    -- 到达上一个尾巴后再去搜寻红块
                    self:doAI()
                    self.direction = self.targetLines[#self.targetLines]
                    table.remove(self.targetLines)
                end        
                self:doMove()

            end     
        end
    end
    self:scheduleUpdateWithPriorityLua(update, 0) 
end

现在基本可以解决红块在蛇身体的情况了

再做一些优化,增加一条假蛇来表示吃了红块后蛇的样子,如果假蛇可以找到最短路径到其假蛇尾巴,则去吃那个红点, 否则不吃红点而是去搜寻真蛇的尾巴

function SnakeGame:doAI(target)
    if #self.targetLines > 0 then
        return
    end
    target = target or self.tail
    for k, v in ipairs(self.lineSquare) do 
        v:removeFromParent()
    end
    self.lineSquare = {}
    self.fakeSnakes = {}    
    local closed = self:checkAWay(self.snakes, target)
    if closed then
        self.targetLines = {}
        self.find_index = -1
        table.insert(self.targetLines, closed[#closed].dir)
        local parent = closed[#closed].parent
        local ii = 1

        while parent and parent ~= closed[1] do
            local index = parent.index            
            local x = self.cells[index]
            table.insert(self.targetLines, parent.dir)
            if target == self.tail then
                table.insert(self.fakeSnakes, parent)
            end
            local m = tsixi.TLabel:create(ii, 14, cc.c3b(0, 0,0))
            m:setPosition(x)
            m:setAnchorPoint(0,0)
            self:addChild(m)
            table.insert(self.lineSquare, m)
            ii = ii + 1
            parent = parent.parent
        end     
        if target == self.tail then            
            table.insert(self.fakeSnakes, 1, closed[#closed])
            local delta = #self.snakes - #self.fakeSnakes            
            if delta >= 0 then
                for i = 1, delta + 1 do 
                    table.insert(self.fakeSnakes, self.snakes[i])
                end
            else
                while #self.fakeSnakes - #self.snakes > 1 do 
                    table.remove(self.fakeSnakes)
                end
            end
            closed = self:checkAWay(self.fakeSnakes, self.fakeSnakes[#self.fakeSnakes])
            if not closed then
                print("mmmmmmmmmmmmmmmmmmm")
                self:doAI(self.snakes[#self.snakes])
            end
        end   
    else
        print("not find a way!")
        self.find_index = 0--self.find_index + 1
        self:doAI(self.snakes[#self.snakes - self.find_index])
    end
end

现在基本可以吃100多个红块了,但有时候还是会找不到最短路径或者死循环。。。以后有空了再看看怎么回事吧。
好了,传统贪吃蛇小游戏就写在这里。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值