本文分析的是三国杀标准包+EX扩展包所带的功能如何在我的程序里实现的,不包括其他的扩展包。实际的程序可以支持2至10人在控制台下进行网络对战。博主仅仅凭兴趣写的,设计有缺陷,请多多包涵。

代码下载地址(素将版,没有实现具体武将,有具体武将的会在2、3月,比赛评比完毕后公布):

http://download.csdn.net/detail/ilovevista/3514209

刚才看了大家下载后的回复,让我倍受鼓舞,谢谢你们!

三国杀实体牌分游戏牌、体力牌、身份牌、武将牌,进行游戏时以玩家的座次顺序来依次进行游戏,大家都共同遵守同样的游戏规则。程序的设计就以此为切入点设计。

一、游戏牌(Poker)

所有的游戏牌主动打出时大致的流程就是:确定使用->指定目标->进入结算流程(生效或失效),被动打出则较为简单。所以定义一个基类,保存牌的基本信息以及执行牌的通用动作,例如存取牌的数字、花色、名称等;不同的牌继承自这个基类(基本牌、锦囊牌、装备牌),具体实现各自不同的“确定使用” “指定目标” “进入结算流程”的函数。在代码中这三个函数分别是Poker::selected()、Poker::use()、TrickPoker::effect()

1,、杀、闪、桃。继承自基本牌,类名分别为Slash、Jink、Peach。闪不能主动使用,桃的使用也比较简单,杀的使用就较为复杂了,涉及目标合法性检查、武器技能发动(每个武器的技能有不同的发动时机)、对方防具技能的选择发动等等,需要在设计时充分考虑后再动手编码,以免有遗漏导致实现出来的功能不正确。

2、各种武器、防具、马。继承自装备牌,类名与中文的对应见各自的头文件注释。装备牌的特点是在使用后要确定装备于玩家的装备区,所以每个装备牌在初始化时就有一个变量:这张牌应该处于什么位置(enum EquipPoker::Location)。

3、锦囊牌,分为延时锦囊和即时锦囊。它们在使用后要在全场询问无懈可击,在没有人打出或者一共打出偶数个无懈可击后才生效,进入结算。

4、虚牌。它用于武将技能发动、卡牌转换,在代码中它包含一个子卡的集合、记录相关信息。比如制衡、仁德,就是将相应的卡牌作为一张虚牌的子牌,提交处理;或者大乔的国色、甘宁的奇袭,是将方片牌或者黑色牌转换成乐不思蜀或者过河拆桥进行结算。

二、牌堆(deskPoker)

牌堆分为未用牌堆、弃牌堆、正在结算牌堆。其中要注意考虑武将技能对牌堆的影响,比如诸葛亮的观星。正在结算牌堆,在结算杀闪、五谷丰登等等的时候所有的牌先置于这里,结算完毕时这个牌堆里的牌统一清理到弃牌堆。

在具体实现时,我一开始用自己写的链表去保存相应的数据(按照《数据结构》书上讲的方法)。结果在测试时,发现如果对这个链表进行上万次操作后它会随机崩溃,我拿着代码请教老师,他也说不出来什么错误。最后我在程序里,所有包含多个数据的东西用的是vector来做,比如玩家的手牌、装备、判定区等等。

三、服务(Service)

在游戏里,这个服务扮演裁判的角色。计算玩家之间的距离、进行杀结算流程的一部分、在玩家打出锦囊时进行询问无懈可击、处理转换卡牌(前面的虚卡)等等,最重要的功能是指导游戏进行流程(Service::setPhase):在游戏开始时,服务通知N号位玩家进行他的回合的某一阶段(回合开始阶段、判定阶段、摸牌阶段、出牌阶段、弃牌阶段、回合结束阶段),玩家返回这个阶段是怎样结束的(是正常结束还是跳过某一阶段,亦或是触发胜利条件),服务对这个返回值检查并处理之后,再通知N+1位玩家进行他的回合。

四、玩家(Player)

玩家的设计曾经困扰我很长时间,直到现在的设计也不是让我很满意。在只有标准包+EX时,我认为玩家所用武将就是“素将+技能”,而且我认为“玩家=素将”,所以我在Player类里面实现了所有素将的功能,具体的武将从素将继承,并改写相关函数实现武将技能。

在这里我说一点,在三国杀“神话再临”版本里,武将与技能的关系不再是一一对应的,也就是说有可能你用的是“孙权”,但是你的技能有可能不再是“制衡”和“救援”,所以技能和武将设计时一定要解耦,我的实现方式直接决定我不能实现“神话再临”里面的武将。

Player里面最重要的函数是Player::setPhase()和Player::askLeadPoker()。前者在自己回合内通过接收Service的传值知道自己处于什么阶段,并提示玩家进行相应操作、选择,比如玩家在出牌阶段要出什么牌,是在这个函数里程序向玩家询问的;后者在玩家回合外提示玩家被要求出什么牌,比如别的玩家杀自己、打出南蛮入侵、万箭齐发时,这个函数通知自己要打出“杀”或者"闪"。其他函数是为了配合对应牌的功能而实现的,比如丢弃牌、亮出牌、交出一张牌等等。

具体武将的类名是武将名称的拼音,基本上是重写Player::setPhase()和Player::askLeadPoker()。

五、服务器内部消息传递

在struct.h里面定义了一些消息结构体,比如用于传递“杀”消息的SlashEffectStruct、用于锦囊消息的TrickEffectStruct等等。主要传递的消息就是“来源”、“目标”、“牌”。其中来源一定是单一的,但是目标和牌有可能是单一的,也有可能是多个。存在多个目标时一定要按照游戏规则的结算顺序来依次结算。

六、服务器/客户端消息传递

在开始时我编写的代码是为了单机玩的,所以没有设计通信协议,基本上都是cout一段中文提示让用户进行一种选择,再cin一个数字,进行检查合法后继续流程。在单机版写完后突然想加入网络功能,这时候改中文重新设计通信协议已经来不及了。我的折中办法就是将客户端做成一个“屏幕”,客户端仅仅是用于显示文字并接受用户的输入,将数据回传至服务器进行相关检查、操作等等,也就是说客户端根本没有关于游戏的内部数据,不知道本玩家手里有什么牌。

原来的所有cin cout,有的东西是要求所有玩家都知道的、有的东西只能让一个人知道,消息一共有三种类型:向所有人通知、向单个人通知、向单个人询问。前两个客户端仅仅需要接收数据并显示,最后一个要求在显示数据之后让用户输入一个选择之后回传至服务器。

在实现上,我写了一个GameServer类,用于网络通信,采用TCP方式连接。因为TCP是流式协议,服务器/客户端内部用了string用于接发数据,也方便进行格式转换,比如让用户进行选择时,用户只需要输入一个数字作为选择,服务器接受的“数字”其实是字符串格式的,用StringStream可以很方便地进行字符串/数字类型的转换。

七、健壮性

1、输入输出健壮性

这个程序的输出都是字符串格式的,不会出现什么错误。所有输入仅仅是一个整数作为选择,在服务器接受用户做出某种选择时,用StringStream去接收,再进行转换,比如:

string recv="4";//接收到的字符串格式的数据

StringStream ss;//用于转换的字符串流

int a=0;//真正能用于服务器内部处理的int型变量

while(输入不合法){

ss<<recv;//字符串导入字符串流的缓冲区

ss>>a;//从字符串流中读取一个int型数据并保存

if(a在范围内)  输入合法跳出循环

}

这样就能保证即使输入错误也不会导致程序崩溃。

2、网络通信健壮性

这方面比较遗憾,因为时间紧迫所以没有做更好的处理,在代码里规定,如果网络通信出现中断,则所有人断开与主机联系。

到此为止,这个三国杀的设计思想差不多介绍完了。

自己写三国杀之架构分析相关推荐

  1. pass基础架构分析

    pass基础架构分析 Relay 和 TVM IR,包含一系列优化passes,可提高模型的性能指标,如平均推理,内存占用,或特定设备的功耗.有一套标准优化,及特定机器学习的优化,包括常量折叠,死代码 ...

  2. 转:秒杀系统架构分析与实战

    原文出处: 陶邦仁   欢迎分享原创到伯乐头条 0 系列目录 秒杀系统架构 秒杀系统架构分析与实战 1 秒杀业务分析 正常电子商务流程 (1)查询商品:(2)创建订单:(3)扣减库存:(4)更新订单: ...

  3. 大型网站系统架构分析--转

    大型网站系统架构分析 原文地址:http://www.cnblogs.com/Mainz/archive/2009/04/28/1445424.html 千万级的注册用户,千万级的帖子,nTB级的附件 ...

  4. Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化-[Android取经之路]

    摘要:本节主要来讲解Android10.0 日志系统的架构分析,以及logd.logcat的初始化操作 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级 ...

  5. 【转】秒杀系统架构分析与实战

    0 系列目录 秒杀系统架构 秒杀系统架构分析与实战 1 秒杀业务分析 正常电子商务流程 (1)查询商品:(2)创建订单:(3)扣减库存:(4)更新订单:(5)付款:(6)卖家发货 秒杀业务的特性 (1 ...

  6. 研究项目: JBoss架构分析

    原文转自:http://www.huihoo.org/jboss/jboss.cn.html 研究项目: JBoss架构分析 Jenny Liu School of Information Techn ...

  7. tomcat架构分析 (Session管理)【转】

    原文地址:https://www.iteye.com/blog/gearever-1546423 Session管理是JavaEE容器比较重要的一部分,在app中也经常会用到.在开发app时,我们只是 ...

  8. 分布式MySQL数据库TDSQL架构分析

     分布式MySQL数据库TDSQL架构分析 发表于11小时前| 次阅读| 来源程序员电子刊| 0 条评论| 作者雷海林 MySQLTDSQL腾讯架构 width="22" he ...

  9. 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】PowerPC + Linux2.6.25平台下的I2C驱动架构分析

    PowerPC + Linux2.6.25平台下的I2C驱动架构分析 Sailor_forever  sailing_9806#163.com (本原创文章发表于Sailor_forever 的个人b ...

最新文章

  1. 从电视到网络,vivo营销之变
  2. SBO应用技术一则-格式化
  3. thinkphp无法加载模块解决办法
  4. 确定一组矩形是否有两个重叠的算法
  5. CodeIgniter模型
  6. springboot忽略证书_SpringBoot获取resource下证书失败
  7. Gartner发布2020年十大战略科技发展趋势
  8. 选数(洛谷P1036题题解,Java语言描述)
  9. Element中 el-tag 点击事件 el-tag添加@click事件无效
  10. 【CSS3】纯CSS代码实现模拟时钟,+js对时功能。
  11. Python:批量转换图片格式
  12. 多线程获取豆瓣网页的网络爬虫(Python实现)
  13. Python-Selenium自动化登陆QQ空间
  14. python-转义字符及其使用
  15. 新浪微博热门话题(字符串处理)
  16. 云原生的年代service mesh不止Istio,还有另一个选择-Kuma
  17. OpenStack核心组件原理与应用之Glance
  18. 泛微OA集成ERP,助力制造业实现供应商、销售全面数字化管理
  19. 数据分析学习(一)数据分析和Numpy基础
  20. 基于JAVA模拟考试系统计算机毕业设计源码+数据库+lw文档+系统+部署

热门文章

  1. 空气净化器的新亮点:增加语音功能
  2. [渝粤教育] 中国地质大学 机械设计 复习题
  3. Httpclient调用短信验证码接口
  4. 服务器监控系统哪家性价比高,伊利智能安防监控系统哪家专业
  5. vce 题库导入_PDF题库转VCE文件总汇.docx
  6. instagram android 登陆,采集,私信,协议分析
  7. VB 隐藏任务栏和显示任务栏
  8. 基于JavaSwing开发连连看游戏(单机版) 课程设计 大作业源码 毕业设计
  9. 一年java经验总结
  10. 面试必备:深入了解冒泡、选择和插入排序的优缺点