算法简单就是美

                             算法简单就是美

                      Horin | horin153@msn.com

                      Blog: http://blog.csdn.net/horin153/

在设计算法时, 我们可能会潜意识的把问题复杂化. 复杂的算法不仅难懂低效, 还可能隐藏着 bug. 简单的算法, 不仅简洁易懂运行高效, 还可能更能解决问题. 在我现在开发的这个 MMO 游戏中, 我举两个实际的例子. 其中, 旧算法是代码中别人写的, 新算法是我修改后的.


-------------- 自动寻路进入死角时的处理 --------------

在一幢建筑物的门口是一个较高的台阶, 台阶下端的两侧各有一个装饰用的石柱, 石柱和台阶之间有一定空隙. 在从外面自动寻路到建筑物内的 NPC 时, 一般会先走到石柱和台阶间的缝隙中, 和台阶的侧面发生碰撞. 此时, 就需要一个算法找到一个行走方向, 走出缝隙. 在寻找出路的过程中, 会尝试 20 次. 如果 20 次都失败了, 就放弃寻找, 寻路任务失败.

last_dir: 当前的行走方向角
dir: 新的行走方向角
pi: 数学上的角度常量

旧算法:
# mid: 用来计算方向角的一个变量, 初始值为 0.
a, mid -= sign(last_dir) # 减去当前方向的符号
   mid = (mid>5) ? 5 : ((mid<-5) ? -5 : mid)
b, last_dir = dir = randint(mid-3, mid+3) # 在给定闭区间产生一个随机整数
c, dir = dir * pi / 16
该算法约 50% 的几率寻路成功.

新算法:
在当前行走方向的反面半圆中随机选择一个角度作为新的行走方向.
dir = last_dir + (random()+0.5) * pi
该算法测试 100% 寻路成功, 一般也只需尝试1,2次就可以成功.


-------------- 物品快照id的编码 --------------

游戏中在聊天窗口发送物品快照链接时, 首先 server 会把生成的快照 id(一个 int64整数) 返回给 client. client 再把快照 id 和物品名字按照一个特定的格式, 格式化到聊天字符串中. 经过敏感词汇等过滤后, 就把字符串发送给 server.
如果在过滤时破坏了快照格式, 就会导致解析失败, 触发程序异常. 因为快照 id 是动态生成的, 导致很长一段时间后, 我才怀疑到这方面来. 这个问题困扰了我们好久, 每天都会回收到大量该 bug 的异常脚本, 我们后来已经不好意思回收了.

旧算法:
# 用 chr 编码, ord 解码
把 int64 从低位到高位, 逐字节用 chr() 转换为字符, 8 个字符构成的字符串就代表快照 id.
因为 chr 的返回值是任意字符, 这就导致在词汇过滤时有可能被误杀. 如果玩家是在世界频道发送物品链接, 被误杀时就会影响到所有在线玩家, 产生很不好的用户体验.

新算法:
编码: "%.16x" % int64
解码: int(nuid, 16)
因为 int64 编码后是 16 个 16 进制的字符, 这组字符基本上是不会被过滤时误杀的(迄今为止还没有发现).
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值