本帖最后由 bumcatxian 于 2021-9-1 12:14 AM 编辑
来北侠已经有一段时间了,对于我来说,玩这个游戏的意义一直都是编程第一,江湖第二。用python也有一些年头了,python的特点之一就是工具多,不用重复造轮子,最近发现有个图形相关的工具包networkx,用于构建和操作复杂的图结构,并提供分析图的算法。正好拿来北侠小试牛刀。 一、安装 直接pip安装就行,matplotlib主要用来提供绘图能力 - pip install networkx
- pip install matplotlib
复制代码二、图的定义 接下来我会用最近刚上线的万兽山庄为例,演示如何用networkx作图。首先我们看看万兽山庄的lm: 接下来开始定义 - # -*- coding: utf-8 -*-
- import networkx as nx
- import matplotlib.pyplot as plt
- #创建一个有向图
- g = nx.DiGraph(area = '万兽山庄')
- #添加名字为1的节点,并加上一个roomname属性,赋值为'大门'
- g.add_node(1)
- g.nodes[1]['roomname'] = '大门'
- #添加节点时同时加上属性也是可以的
- g.add_node(2,roomname = '土路')
- #添加2个节点之间的边,weight表示权重,path属性用来存储出口信息
- g.add_edge(1,2, weight = 1,path = 'north')
- g.add_edge(2,1, weight = 1,path = 'south')
复制代码这样就画好了两个节点和一条边,如此类推,我把大门附近的房间也画了一下,并用matplotlib展示出来 - pos = nx.spring_layout(g)
- nx.draw(g,pos,node_size=900)
- #取出节点的roomname属性,并画出
- node_labels = nx.get_node_attributes(g,'roomname')
- nx.draw_networkx_labels(g,pos,labels = node_labels)
- #取出边的path属性,并画出
- edge_labels = nx.get_edge_attributes(g,'path')
- nx.draw_networkx_edge_labels(g,pos,edge_labels = edge_labels,label_pos=0.3)
- plt.show()
复制代码运行结果是这样子的,双向的label画上去后有些丑。。
到目前为止,一个简单的图就基本画完了。 三、路径计算 为了方便看出效果,我重新画了一幅只有房间号的图 接下来直接利用networkx自带的dijkstra_path函数计算路径,即使是像我这样的算法小白也能轻松搞定 - #使用dijkstra算法计算2点间的最短路径
- print(nx.dijkstra_path(g,6,10))
- #输出:[6, 2, 1, 5, 10]
复制代码然后配合之前的path属性,我们可以很简单的生成需要发送给mud的命令 - def cal_path(g,start,end):
- path = nx.dijkstra_path(g,start,end)
- cmd = []
- index = 0
- while index < len(path) - 1:
- cmd.append(g[path[index]][path[index+1]]['path'])
- index += 1
- return ';'.join(cmd)
- print(cal_path(g,6,10))
- #输出:east;south;enter;east
复制代码
networkx同样也为我们提供了遍历算法,下面以DFS为例 - #以节点6为起点,用DFS算法遍历图g
- print(list(nx.dfs_preorder_nodes(g,6)))
- #输出:[6, 7, 8, 2, 1, 3, 4, 5, 9, 10]
复制代码同理,获取遍历路径的命令就很容易实现了 - def DFS(g,source,depth_limit=len(g)):
- path = list(nx.dfs_preorder_nodes(g,source,depth_limit))
- path.append(source)#把起点加到最后,遍历完成后回到起点
- cmd = []
- index = 0
- while index < len(path) - 1:
- cmd.append(cal_path(g,path[index],path[index + 1]))
- index += 1
- return ';'.join(cmd)
- print(DFS(g,6))
- #输出:northeast;northdown;southup;southup;south;west;east;east;west;enter;west;east;east;west;out;north;west
复制代码
四、结尾 networkx的基本使用大概就介绍到这了,当然,只靠上面的内容是不足以做出一个可以在游戏里走路的工具的,后面我大概还会写两篇,一个是python与mush客户端的配合,讲讲如何利用trigger制作录制工具,另一个是其他问题的解决思路,例如房间的定位等等。当然也不排除就这样鸽了。 最后附上两个参考网站,对networkx有兴趣的同学可以去学习一下。 networkx是什么 networkx手册
|