深入浅出制作全自动Mud机器人-随机迷宫地图
Script脚本
1
帖子
1
发布者
9
浏览
-
随机迷宫以及地图是很多Mud引入的新任务类型。
比如下面就是一个典型的迷宫地图
┌─┬─┬─┬─┬─┬─┬─┬─┐ │★│ │ │ ├ ┼─┼ ┼─┼ ┼─┼─┼ ┤ │ │ │ │ │ │ ├ ┼ ┼─┼ ┼ ┼─┼─┼ ┤ │ │ │ │ │ ├ ┼─┼ ┼─┼ ┼─┼ ┼ ┤ │ │ │ │ │ ├─┼ ┼ ┼─┼─┼─┼ ┼ ┤ │ │ │ │ │ │ │ │ ├ ┼ ┼ ┼ ┼ ┼ ┼ ┼─┤ │ │ │ │ │ │ │ ├ ┼ ┼─┼─┼─┼ ┼ ┼ ┤ │ │ │ │ ├─┼─┼ ┼─┼ ┼─┼ ┼ ┤ │ │ │ │ └─┴─┴─┴─┴─┴─┴─┴─┘这种地图本质就是在服务器创建了一系列的虚拟房间,并建立了房间中之间的联系,最后将这些方向和关系再打印成文字图案。
那么,处理方式也比较直接。
先将文字图标准化,化成比较简单的单字节图,然后再遍历建立临时房间和出口信息就可以。
参考HellMapManager.Dll的范例代码
local hmmlib=require('hmm') local hmm=hmmlib.new() hmm.DllEncoding=0 --0 for utf-8, 1 for gbk local json=require('json') local file=assert(io.open("hongchen.hmm","r")) local data=file:read("*a") file:close(); hmm:call("import",data) local extrooms={} local extpaths={} local function buildMyRoom(entry,roomid,roomname) local myroom1=hmmlib.Room.new() myroom1.Key="myroom-entry" myroom1.Name=roomname.."大厅" local myroomexit1=hmmlib.Exit.new() myroomexit1.Command="open gate;n" myroomexit1.To="myroom-home" local myroomexit2=hmmlib.Exit.new() myroomexit2.Command="out" myroomexit2.To=entry myroom1.Exits={myroomexit1,myroomexit2} local myroom2=hmmlib.Room.new() myroom2.Key="myroom-home" myroom2.Name=roomname.."卧室" local myroomexit3=hmmlib.Exit.new() myroomexit3.Command="open gate;s" myroomexit3.To="myroom-entry" myroom2.Exits={myroomexit3} table.insert(extrooms, myroom1) table.insert(extrooms, myroom2) local entrypath=hmmlib.Path.new() entrypath.From=entry entrypath.Command="go "..roomid entrypath.To="myroom-entry" table.insert(extpaths, entrypath) end buildMyRoom("2440","myhouse","大别野") local mazemaptxt=[[ ┌─┬─┬─┬─┬─┬─┬─┬─┐ │ │ │ ├─┼ ┼─┼─┼─┼─┼ ┼ ┤ │ │ │ │ │ │ ├ ┼ ┼─┼ ┼ ┼─┼ ┼ ┤ │ ♚ │ │ │ │ │ ├─┼ ┼ ┼ ┼ ┼─┼ ┼ ┤ │ │ │ │ │ ├─┼ ┼─┼ ┼─┼─┼ ┼─┤ │ │ │ │ │ │ ├ ┼ ┼─┼─┼ ┼ ┼─┼ ┤ │ │ │ │ │ │ ├ ┼ ┼─┼─┼ ┼ ┼ ┼ ┤ │ │ │ │ │ │ ├ ┼ ┼─┼ ┼ ┼ ┼ ┼─┤ │ │ │ │ │ ★│ └─┴─┴─┴─┴─┴─┴─┴─┘ ]] --♚为当前位置,★为出口 local Maze={} Maze.__index=Maze Maze.new=function() local self=setmetatable({},Maze) self.RoomPrefix="maze-" self.RoomKeys={} self.Rooms={} self.Paths={} self.EntryRoom="" self.ExitRooms={} return self end function Maze:buildRoomKey(x,y) return self.RoomPrefix..tostring(x).."-"..tostring(y) end function Maze:buildExit(room,tokey,command) local exit1=hmmlib.Exit.new() exit1.Command=command exit1.To=tokey table.insert(room.Exits, exit1) end function Maze:readmap(maptxt) local maplines={} for line in string.gmatch(maptxt, "[^\r\n]+") do if #line>0 then --因为utf8不定长,进行处理 line = string.gsub(line," "," ") line = string.gsub(line,"│","+") line = string.gsub(line,"─","+") line = string.gsub(line,"├","+") line = string.gsub(line,"┤","+") line = string.gsub(line,"┴","+") line = string.gsub(line,"┬","+") line = string.gsub(line,"└","+") line = string.gsub(line,"┘","+") line = string.gsub(line,"┌","+") line = string.gsub(line,"┐","+") line = string.gsub(line,"┼","+") line = string.gsub(line,"♚","I") line = string.gsub(line,"★","O") table.insert(maplines, line) end end local roomwidth=(#maplines[1]-1)/2 local roomheight=(#maplines-1)/2 local currentY=1 --按行处理 while currentY<=roomheight do local currentX=1 --处理每个房间 while currentX<=roomwidth do local roomkey=self:buildRoomKey(currentX-1, currentY-1) table.insert(self.RoomKeys, roomkey) local room=hmmlib.Room.new() room.Key=roomkey if maplines[currentY*2]:sub(currentX*2, currentX*2)=="I" then self.EntryRoom=roomkey end if maplines[currentY*2]:sub(currentX*2, currentX*2)=="O" then table.insert(self.ExitRooms, roomkey) end if maplines[currentY*2]:sub(currentX*2+1, currentX*2+1)==" " then self:buildExit(room,self:buildRoomKey(currentX,currentY-1),"e") end if maplines[currentY*2]:sub(currentX*2-1, currentX*2-1)==" " then self:buildExit(room,self:buildRoomKey(currentX-2,currentY-1),"w") end if maplines[currentY*2+1]:sub(currentX*2, currentX*2)==" " then self:buildExit(room,self:buildRoomKey(currentX-1,currentY),"s") end if maplines[currentY*2-1]:sub(currentX*2, currentX*2)==" " then self:buildExit(room,self:buildRoomKey(currentX-1,currentY-2),"n") end table.insert(self.Rooms, room) currentX=currentX+1 end currentY=currentY+1 end end function Maze:applyTo(environment) for _, room in ipairs(self.Rooms) do table.insert(environment.Rooms, room) end for _, path in ipairs(self.Paths) do table.insert(environment.Paths, path) end end local mymaze=Maze.new() mymaze:readmap(mazemaptxt) local query=hmmlib.QueryPathAny.new() query.From={"2522"} query.Target={"myroom-home"} query.Environment=hmmlib.Environment.new() query.Environment.Rooms=extrooms query.Environment.Paths=extpaths local result=json.decode(hmm:call("querypathany", json.encode(query))) if (result==nil) then print("No home path found") else print("Home path found:") print(json.encode(result)) end -- 遍历迷宫后离开 local queryall=hmmlib.QueryPath.new() queryall.Start=mymaze.EntryRoom queryall.Target=mymaze.RoomKeys queryall.Environment=hmmlib.Environment.new() mymaze:applyTo(queryall.Environment) result=json.decode(hmm:call("querypathall", json.encode(queryall))) if (result==nil) then print("No full maze path found") else print("Full maze path found:") print(json.encode(result)) end --遍历完成,离开路径 query=hmmlib.QueryPathAny.new() query.From={result["To"]} query.Target=mymaze.ExitRooms query.Environment=hmmlib.Environment.new() mymaze:applyTo(query.Environment) result=json.decode(hmm:call("querypathany", json.encode(query))) if (result==nil) then print("No maze path found") else print("Maze path found:") print(json.encode(result)) end在处理动态地图时,核心还是不要想的太复杂,直接找出Room的对应元素,以及相应的Exit,然后根据需要遍历或者导航即可。
-
J jarlyyn 被引用 于这个主题