|
楼主 |
发表于 2019-4-9 21:33:43
|
显示全部楼层
弄清Lua函数具体的作用,有个简单技巧可以理清思路:
1 看是否有return
2 看是否有全局变量,如果有是否被赋值
3 函数是否调用了其他函数,只要发生了函数调用,函数就必须返回,返回值可以是任何值。
开始正题:
首先明确find()函数的作用:在目标房间进行l_distance深度的遍历(默认是6),遍历行走深度范围内和目标房间相连的所有房间。下面介绍函数调用过程:
- function find(l_area,l_room)
- do return search() end
- end
复制代码
1) 有return,调用函数search();
- function search()
- tmp.find = true
- if flag.find==1 then return end
- searchPre()
- cntr1 = countR(15)
- exe('look;halt')
- tmpsearch=3
- return check_halt(searchStart,1)
- end
复制代码
2)有全局变量 tmp.find ,暂时先不管;调用函数searchPre(),这个函数是find()函数的核心
- road.rooms={}
- local p_room = map.rooms[road.id].name
- local p_dest = getLookCity(road.id)
- local l_distance = 6
- if p_dest==nil then
- p_dest=map.rooms[road.id].outdoor
- end
- local rooms = getAroundRooms(p_room,p_dest,l_distance,'all')
- starttime=os.clock() --测试计算时间
- newrooms = {}
- for id in pairs(rooms) do
- table.insert(newrooms,id)
- end
复制代码
发现三个全局变量,其实是两个,很重要。
road.rooms是一个表,最终储存所有需要遍历的房间id,当然现在是空的。
road.id就是前面说的目标房间id,通过函数path_consider()确定。
newrooms等同于road.rooms的另一种存储方式,方便后面处理。
- myrt={}
-
- for _,roomid in pairs(newrooms) do --插入房间链表
- roomV = List.new(roomid)
- local node = roomV
- for k,v in pairs(newrooms) do --所有的房间id
- for route,link_way in pairs(map.rooms[roomid].ways) do --当前id的出口
- local routeLength = map.rooms[roomid]:length(route)
- if routeLength then
- if routeLength ==1 or routeLength >1 and flag.times>1 then
- if v==link_way then
- node = List.addNode(node,List.new(k)) --插入节点生成第一个房间的出口链表
- end
- end
- end
- end
- end
- table.insert(myrt,roomV)
- end
复制代码
又发现新的全局变量myrt,中间的循环过程涉及到链表(一种数据结构),不展开讲,记住结论:myrt和newrooms其实是一回事,road.rooms的不同存储方式而已。
- for i=1 ,countTab(newrooms) do
- if visited[i]==false then--未曾访问的节点测试一下跟第一个起点的连通性,如果能联通,则递归这个节点
- local path, len = map:getPath(myrt[1].index,myrt[i].index)
- if path then
- FastDFS(myrt,i) --继续遍历指定的myrt[i]这个节点
- end
- end
- end
复制代码
发现新的函数FastDFS(),控制权交到该函数手上,这个函数是很经典的深度遍历算法。
- function FastDFS(myrt,i)
- visited[i] = true --设置下标为I的顶点为已访问
- table.insert(road.rooms,myrt[i].index)
- local p = myrt[i].pnext --下一个边表结点
- if p==nil then return end
- while p~=nil do
-
- if(not visited[p.index]) then--如果是未访问的则递归
- visited[p.index]=true
- FastDFS(myrt,p.index)
- end
- p = p.pnext
-
- end
- end
复制代码
重点看 table.insert(road.rooms,myrt.index),是不是发现老朋友road.rooms了,饶了一大圈,最后的结论就是searchPre()的作用是给road.rooms这个table赋值了,里面储存所有需要遍历的房间id。
searchPre()函数调用完成,回到search(),继续往下走,发现return了,调用函数searchStart()。
searchStart()和searchFunc(path)、walk_wait()、walk_goon()都是好基友,怎么发生基情后面再说,今天先到这。
|
|