北大侠客行MUD论坛

 找回密码
 注册
搜索
热搜: 新手 wiki 升级
查看: 9185|回复: 12

[python]networkx-我在北侠学画图

[复制链接]
发表于 2021-9-1 00:15:14 | 显示全部楼层 |阅读模式
本帖最后由 bumcatxian 于 2021-9-1 12:14 AM 编辑

来北侠已经有一段时间了,对于我来说,玩这个游戏的意义一直都是编程第一,江湖第二。用python也有一些年头了,python的特点之一就是工具多,不用重复造轮子,最近发现有个图形相关的工具包networkx,用于构建和操作复杂的图结构,并提供分析图的算法。正好拿来北侠小试牛刀。

一、安装

直接pip安装就行,matplotlib主要用来提供绘图能力

  1. pip install networkx
  2. pip install matplotlib
复制代码

二、图的定义

接下来我会用最近刚上线的万兽山庄为例,演示如何用networkx作图。首先我们看看万兽山庄的lm:

接下来开始定义

  1. # -*- coding: utf-8 -*-
  2. import networkx as nx
  3. import matplotlib.pyplot as plt
  4. #创建一个有向图
  5. g = nx.DiGraph(area = '万兽山庄')

  6. #添加名字为1的节点,并加上一个roomname属性,赋值为'大门'
  7. g.add_node(1)
  8. g.nodes[1]['roomname'] = '大门'

  9. #添加节点时同时加上属性也是可以的
  10. g.add_node(2,roomname = '土路')

  11. #添加2个节点之间的边,weight表示权重,path属性用来存储出口信息
  12. g.add_edge(1,2, weight = 1,path = 'north')
  13. g.add_edge(2,1, weight = 1,path = 'south')
复制代码

这样就画好了两个节点和一条边,如此类推,我把大门附近的房间也画了一下,并用matplotlib展示出来

  1. pos = nx.spring_layout(g)
  2. nx.draw(g,pos,node_size=900)
  3. #取出节点的roomname属性,并画出
  4. node_labels = nx.get_node_attributes(g,'roomname')
  5. nx.draw_networkx_labels(g,pos,labels = node_labels)
  6. #取出边的path属性,并画出
  7. edge_labels = nx.get_edge_attributes(g,'path')
  8. nx.draw_networkx_edge_labels(g,pos,edge_labels = edge_labels,label_pos=0.3)
  9. plt.show()
复制代码

运行结果是这样子的,双向的label画上去后有些丑。。


到目前为止,一个简单的图就基本画完了。

三、路径计算

为了方便看出效果,我重新画了一幅只有房间号的图

接下来直接利用networkx自带的dijkstra_path函数计算路径,即使是像我这样的算法小白也能轻松搞定

  1. #使用dijkstra算法计算2点间的最短路径
  2. print(nx.dijkstra_path(g,6,10))

  3. #输出:[6, 2, 1, 5, 10]
复制代码

然后配合之前的path属性,我们可以很简单的生成需要发送给mud的命令

  1. def cal_path(g,start,end):
  2.     path = nx.dijkstra_path(g,start,end)
  3.     cmd = []
  4.     index = 0
  5.     while index < len(path) - 1:
  6.         cmd.append(g[path[index]][path[index+1]]['path'])
  7.         index += 1
  8.     return ';'.join(cmd)

  9. print(cal_path(g,6,10))
  10. #输出:east;south;enter;east
复制代码

networkx同样也为我们提供了遍历算法,下面以DFS为例

  1. #以节点6为起点,用DFS算法遍历图g
  2. print(list(nx.dfs_preorder_nodes(g,6)))
  3. #输出:[6, 7, 8, 2, 1, 3, 4, 5, 9, 10]
复制代码

同理,获取遍历路径的命令就很容易实现了

  1. def DFS(g,source,depth_limit=len(g)):
  2.     path = list(nx.dfs_preorder_nodes(g,source,depth_limit))
  3.     path.append(source)#把起点加到最后,遍历完成后回到起点
  4.     cmd = []
  5.     index = 0
  6.     while index < len(path) - 1:
  7.         cmd.append(cal_path(g,path[index],path[index + 1]))
  8.         index += 1
  9.     return ';'.join(cmd)
  10. print(DFS(g,6))
  11. #输出:northeast;northdown;southup;southup;south;west;east;east;west;enter;west;east;east;west;out;north;west
复制代码

四、结尾

networkx的基本使用大概就介绍到这了,当然,只靠上面的内容是不足以做出一个可以在游戏里走路的工具的,后面我大概还会写两篇,一个是python与mush客户端的配合,讲讲如何利用trigger制作录制工具,另一个是其他问题的解决思路,例如房间的定位等等。当然也不排除就这样鸽了。

最后附上两个参考网站,对networkx有兴趣的同学可以去学习一下。

networkx是什么

networkx手册





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2021-9-1 10:00:00 | 显示全部楼层
不明觉厉
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2021-9-1 10:01:04 | 显示全部楼层
哇,膜拜
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2021-9-1 13:32:48 | 显示全部楼层
其实dijkstra 自己实现下也不复杂

建议在做mapper的时候加入几个元素

第一,路径实际花费时间,和你权重类似,最后应该可以算出来路上花的时间

第二,tag,就是可以通过tag来开启和关闭一些路径

第三,直接到达的路径。就是任何地方都能直接前往的地方。
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2021-9-1 13:35:36 | 显示全部楼层
给一个我用go实现的mapper做参考,其实没几行代码

https://github.com/jarlyyn/hellc ... es/mapper/mapper.go

原始结构

https://github.com/jarlyyn/hellc ... s/mapper/walking.go

寻路逻辑

还有部分优化空间
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2021-9-1 13:51:33 | 显示全部楼层
另外这一块本身是完全可以在js/lua等脚本语言里实现的。

但由于mushclient非常老,性能上是有点问题的(以我玩的mud为例,同样的配置,同样的js机器人,用mushclient 5跑5个id会阿卡,用mushclient 4 10个id会卡 我用的客户端我收集到的信息是能挂18个id)

所以,推荐在mushclient里实现的话,还是用dll甚至acrtivex的形式实现
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
 楼主| 发表于 2021-9-1 14:48:55 | 显示全部楼层
jarlyyn 发表于 2021-9-1 01:51 PM
另外这一块本身是完全可以在js/lua等脚本语言里实现的。

但由于mushclient非常老,性能上是有点问题的(以 ...

感谢大佬提供代码学习,我有空去研究一下。用python更多的原因是出于个人喜好,而且在游戏之外的领域也是我主要使用的语言。客户端的确是比较棘手的问题,支持py的客户端并不多,我所知的就只有mush或tintin。个人也对大量账号同时在线没啥需求,就先用mush 凑合着吧。
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2021-9-1 14:50:38 | 显示全部楼层
好贴留名
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2021-9-2 00:35:00 | 显示全部楼层
学习学习
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
发表于 2021-9-3 10:41:19 | 显示全部楼层
膜拜
北大侠客行Mud(pkuxkx.net),最好的中文Mud游戏!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|北大侠客行MUD ( 京ICP备16065414号-1 )

GMT+8, 2024-11-23 10:05 PM , Processed in 0.016093 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表