加入了xkx地图数据,通过寻路算法,找到两点间的通路,然后再走。
地图数据来自xkx论坛gps定位的sqlite数据库,转换成lua格式输出处理。修改其中的一些错误的,"符号
- room={
- [1]={
- ["id"]=1,
- ["name"]="中心广场",
- ["desc"]="这是泉州的中心地带,树荫浓郁,整齐划一。人山人海,摩肩接踵,来来",
- ["ways"]="east|north|south|west",
- ["link"]={["w"]=2,["w"]=11,["e"]=10,["s"]=9},
- ["zone"]="福建泉州",
- ["npc"]="",
- ["cmd"]=""
- },
- [2]={
- ["id"]=2,
- ["name"]="刺桐西路",
- ["desc"]="这是泉州的主要干道,笔直宽广,车水马龙,热闹非凡。西边便是著名的",
- ["ways"]="east|north|west",
- ["link"]={["w"]=3,["w"]=19,["s"]=17},
- ["zone"]="福建泉州",
- ["npc"]="",
- ["cmd"]=""
- },
- .
- .
- .
- }
通过触发器获取place,ways,desc表示当前看到的地点,出路,地点描述。
trywalk.lua含半自动行走实现
- --[[
- 1、修改wait.regexp使得匹配后该行保持有效,触发器仍旧为临时触发(一劳永逸。)
- 2、需要全局变量 place 获取房间名建立1个触发器
- 3、需要全局变量ways获取出路建立18个出发器
- 4、使用举例
- 可以建立mush alias walk/((.*),(.*)/)
- 发送到脚本
- local target="%1"
- local allow="%2"
- function walk()
- rectilineal_walk(target,allow)
- end
- require "wait"
- wait.make(walk)
- 从武当三清殿走到玄岳门可以在命令行walk(玄岳,n.nd.nu)
- 再从玄岳门走到三不管walk(三不管,e.eu.ed.nw.n)
- ]]--
- require "wait"
- require "tprint"
- place=nil
- desc=nil
- ways=nil
- --脚本建立出发器的方法
- function way_t()
- local l,w
- local find=string.find
- while 1 do
- l,w=wait.regexp("这里没有任何明显的出路|这里唯一的出口是 ([a-z]+)。|这里明显的出口是 ([a-z]+) 和 ([a-z]+)|这里明显的出口是 ([a-z]+)、([a-z]+) 和 ([a-z]+)|这里明显的出口是 ([a-z]+)、([a-z]+)、([a-z]+) 和 ([a-z]+)|这里明显的出口是 ([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+) 和 ([a-z]+)|这里明显的出口是 ([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+) 和 ([a-z]+)|这里明显的出口是 ([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+) 和 ([a-z]+)|这里明显的出口是 ([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+) 和 ([a-z]+)|(> )*(.*) /- $|(> )*(.*) /- ([a-z]+)$|(> )*(.*) /- ([a-z]+)、([a-z]+)$|(> )*(.*) /- ([a-z]+)、([a-z]+)、([a-z]+)$|(> )*(.*) /- ([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)$|(> )*(.*) /- ([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)$|(> )*(.*) /- ([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)$|(> )*(.*) /- ([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)$|(> )*(.*) /- ([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)、([a-z]+)$")
- ways=nil
- ways={}
- local id=1
- if find(l,"-") then
- for i,v in ipairs(w) do
- if v~=nil and v~=false and (not find(v,">")) and v~="" and i>2 then
- --Note(v)
- ways[id]=v
- id=id+1
- end
- end
- else
- for i,v in ipairs(w) do
- if v~=nil and v~=false and v~="" then
- --Note(v)
- ways[id]=v
- id=id+1
- end
- end
- end
- --tprint(ways)
- end
- end
- function place_t()
- local l,w
- local find=string.find
- local ways_str
- while 1 do
- l,w=wait.regexp("(> )*(.*) /- ([a-z、]*)")
- place=w[2]
- desc=nil
- ways=nil
- npc=""
- --Note("地点:"..place)
- end
- end
- function desc_t()
- local l,w
- local find=string.find
- while 1 do
- l,w=wait.regexp(" (.*)")
- if desc==nil then
- desc=w[1]
- --Note(desc)
- end
- end
- end
- function init()
- wait.make(way_t)
- wait.make(desc_t)
- wait.make(place_t)
- end
- init()
- --上面这一段可以自己不用脚本,通过操作mush的触发器设置实现(我实现好了,用脚本方便点)
- function rectilineal_walk(target,allows)
- local find=string.find
- local l,w,t
- local walkmap_s,walkmap_l,walkmap
- local bad=false
- --映射
- walkmap_s="e;w;s;n;eu;ed;wu;wd;su;sd;nu;nd;se;sw;ne;nw;d;u"
- walkmap_l="east;west;south;north;eastup;eastdown;westup;westdown;southup;southdown;northup;northdown;southeast;southwest;northeast;northwest;down;up"
- local ws=utils.split(walkmap_s,";")
- local wl=utils.split(walkmap_l,";")
- local path=""
- walkmap={}
- for i,v in ipairs(ws) do
- walkmap[v]=wl[i]
- end
- for i,v in ipairs(wl) do
- walkmap[v]=ws[i]
- end
- --获取允许方位
- if allows~=nil then
- if allows~="" then t=utils.split(allows,".") end
- end
- --t中有可行方位,有优先级
- Execute("look")
- task="walking"
- while task=="walking" do
- l,w=wait.regexp("这里明显的出口是|这里唯一的出口是|这里没有任何明显的出路|(> )*(.*) /- ([a-z、]+)",10)
- if l==nil then
- else
- if find(place,target) then
- Note("到达"..target)
- break
- end
- if ways~=nil then
- --通过出口,尝试走
- local walked=false
- for i,v in ipairs(t) do
- for ii,vv in ipairs(ways) do
- if vv=="" or vv==false or vv==nil then else
- if vv==v or walkmap[vv]==v then
- Execute("h;"..v) --发送一个halt再行走
- --Execute(v) --网速好时可以快速行走
- path=path..v..";"
- walked=true
- break
- end
- end
- end
- if walked==true then break end
- end
- --不能再走了
- if walked==false then
- Note("能力有限,走到这里,不只如何走了")
- bad=true
- break
- end
- else
- Note("这里没有出路,机器人解决不了")
- bad=true
- break
- end
- end
- end
- Note("我走的路径:"..path)
- if bad==false then
- return path
- else
- return nil
- end
- end
全自动寻路行走实现
autowalk.lua
- require "xkx_room"
- require "tprint"
- require "trywalk"
- local wait=wait
- local find=string.find
- local ways_ok=function (ways1,ways2)
- local w1=utils.split(ways1,"|")
- --local w1=ways1
- local w2=utils.split(ways2,"|")
- local i,v,ii,vv
- if table.getn(w1)==table.getn(w2) then
- for i,v in ipairs(w1) do
- local ok=false
- for ii,vv in ipairs(w2) do
- if vv==v then
- ok=true
- break
- end
- end
- if ok==false then return false end
- end
- --all ok
- return true
- else
- return false
- end
- end
- --地址描述用触发得到是完整的,find找数据中匹配项,不可以反,因为数据中有不完整的。
- function findroom(name,desc,ways)
- Note("开始寻找"..name)
- local ret={}
- local id=1
- local i,v
- for i,v in ipairs(room) do
- if v["name"]==name then
- if (desc~=nil and desc~="") or ( ways~=nil and ways~="") then
- if (desc~=nil and desc~="") and ( ways~=nil and ways~="") then
- --两个都有
- if find(desc,v["desc"]) and ways_ok(ways,v["ways"]) then
- ret[id]=v["id"]
- id=id+1
- end
- else
- if ( ways~=nil and ways~="") then
- --ways有desc无
- if ways_ok(ways,v["ways"]) then
- ret[id]=v["id"]
- id=id+1
- end
- else
- --desc有ways无
- if find(desc,v["desc"]) then
- ret[id]=v["id"]
- id=id+1
- end
- end
- end
- else
- --两个空
- ret[id]=v["id"]
- id=id+1
- end
- end
- end
- Note("寻找"..name.."结束")
- tprint(ret)
- return ret
- end
- function showroom(roomid)
- tprint(room[roomid])
- end
- function pathbyid(startroomid,endroomid)
- local ret=""
- local tree={}
- local tree_grow_at=function (id)
- local k,v
- local ret=false
- if id~=nil then
- local links={}
- if (room[id])["link"]~=nil and (room[id])["link"]~={} then
- for k,v in pairs( (room[id])["link"] ) do
- if tree[v]~=nil or v==0 then
- --已经处理了,是正常顺序
- else
- tree[v]={}
- tree[v]={
- ["uplink"]=id,
- ["path"]=k,
- ["link"]={}
- }
- table.insert(links,v)
- if v == endroomid then
- ret=true
- break
- end
- end
- end
- (tree[id])["link"]=links
- if ret==true then return true else return links end
- else
- return nil
- end
- return links
- else
- tree[startroomid]={
- ["uplink"]=nil,
- ["path"]=nil,
- ["link"]={[1]=startroomid}
- }
- if startroomid==endroomid then
- return true
- end
- return (tree[startroomid])["link"]
- end
- end
- --
- local tree_grow=function()
- local root,links,leaf
- local i,v,ii,vv,iii,vvv
- local trycount=0
- local ret=false
- local closed={}
- root=tree_grow_at(nil)
- if root==true then
- --找到
- return true
- else
- while root~=nil and root~={} and table.getn(tree)<table.getn(room) and trycount<table.getn(room) do
- leaf={}
- for i,v in ipairs(root) do
- table.insert(closed,v)
- links=tree_grow_at(v)
- if links==true then
- --找到
- return true
- else
- if links~=nil then
- for ii,vv in ipairs(links) do
- local new=true
- for iii,vvv in ipairs(closed) do
- if vvv==vv then
- new=false
- break
- end
- end
- if new==true then
- table.insert(leaf,vv)
- else
- --print("but old place")
- end
- end
- end
- end
- end
- root=leaf
- trycount=trycount+1
- end
- end
- --从这里出,失败
- return false
- end
- --
- if tree_grow()==true then
- Note("找到了!")
- local id=endroomid
- while id~=startroomid do
- ret=(tree[id])["path"]..";"..ret
- id=(tree[id])["uplink"]
- end
- Note(ret)
- else
- Note("抱歉没找到通路,请修改地图room.lua数据,确保连通")
- end
- return ret
- end
- function where()
- local roomidt={}
- while table.getn(roomidt)~=1 do
- place=nil
- ways=nil
- desc=nil
- Execute("look")
- while 1 do
- if place~=nil and ways~=nil and desc~=nil then
- break
- end
- wait.time(2)
- end
- local wlen=table.getn(ways)
- local ran=math.random(wlen)
- local ranway=ways[ran]
- roomidt=findroom(place,desc,table.concat(ways,'|'))
- if table.getn(roomidt)~=1 then
- Note("此处不好定位,换个地方。走:"..ranway)
- Execute("h;"..ranway)
- end
- end
- Note("当前房间:"..roomidt[1])
- return roomidt[1]
- end
- function walk(toname,tozone)
- local rooms=findroom(toname)
- local startid=where()
- local i,v,ii,vv
- local path
- local find=string.find
- if rooms~=nil and rooms~={} then
- if tozone~=nil then
- for ii,vv in ipairs(rooms) do
- if find((room[vv])["zone"],tozone) then
- else
- Note("区域:"..(room[vv])["zone"].."不合要求"..tozone)
- rooms[ii]=0
- end
- end
- end
- --只处理到第一个位置
- for i,v in ipairs(rooms) do
- if v~=nil and v~=0 then
- path=pathbyid(startid,v)
- if path~=nil and path~="" then break end
- end
- end
- if path~=nil and path~="" then
- --找到了通路,执行咯!
- local patht=utils.split(path,";")
- for i,v in ipairs(patht) do
- wait.time(1)
- Execute("h;"..v)
- end
- else
- Note("奇怪,没有通路")
- end
- else
- Note("无法定位目标房间号")
- end
- end
- function to_npc(tonpc)
- --无数据,有数据很好实现,把目标找到和上面就一样了。
- end