Unity学习之P&D 过河游戏智能帮助实现

根据之前设计好的动作分离版过河游戏,我们进行一个简单的状态图AI实现。

转移状态图

状态图老师已经给出:

该状态图只记录了游戏过程中左岸的情况。P代表牧师,D代表魔鬼,B代表船。当船在右岸时不记录。双箭头代表两个状态可以相互转化。

构造状态图

next.boat = nowStatue;if (next.boat == Status.BLRING ||next.boat == Status.BRLING ||next.boat == Status.LOSE ||next.boat == Status.WIN || boatSize() != 0){next.boat = Status.None;return next;}else{if (next.boat == Status.BLEFT &&leftPriests.Count == 3 && leftDevils.Count == 3){int turn = randomValue();if (turn == 1)next.boataction = Boataction.PD;elsenext.boataction = Boataction.DD;}else if (next.boat == Status.BRIGHT && leftPriests.Count == 2 && leftDevils.Count == 2){next.boataction = Boataction.P;}else if (next.boat == Status.BRIGHT && leftPriests.Count == 3 &&leftDevils.Count == 2){next.boataction = Boataction.D;}else if (next.boat == Status.BRIGHT && leftPriests.Count == 3 &&leftDevils.Count == 1){next.boataction = Boataction.D;}else if (next.boat == Status.BLEFT && leftPriests.Count == 3 &&leftDevils.Count == 2){next.boataction = Boataction.DD;}else if (next.boat == Status.BRIGHT && leftPriests.Count == 3 && leftDevils.Count == 0){next.boataction = Boataction.D;}else if (next.boat == Status.BLEFT &&leftPriests.Count == 3 &&leftDevils.Count == 1){next.boataction = Boataction.PP;}else if (next.boat == Status.BRIGHT &&leftPriests.Count == 1 &&leftDevils.Count == 1){next.boataction = Boataction.PD;}else if (next.boat == Status.BLEFT &&leftPriests.Count == 2 &&leftDevils.Count == 2){next.boataction = Boataction.PP;}else if (next.boat == Status.BRIGHT &&leftPriests.Count == 0 &&leftDevils.Count == 2){next.boataction = Boataction.D;}else if (next.boat == Status.BLEFT &&leftPriests.Count == 0 &&leftDevils.Count == 3){next.boataction = Boataction.DD;}else if (next.boat == Status.BRIGHT &&leftPriests.Count == 0 &&leftDevils.Count == 1){int turn = randomValue();if (turn == 1) next.boataction = Boataction.D;else next.boataction = Boataction.P;}else if (next.boat == Status.BLEFT &&leftPriests.Count == 2 &&leftDevils.Count == 1){next.boataction = Boataction.P;}else if (next.boat == Status.BLEFT &&leftPriests.Count == 0 &&leftDevils.Count == 2){next.boataction = Boataction.DD;}else if (next.boat == Status.BLEFT &&leftPriests.Count == 1 &&leftDevils.Count == 1){next.boataction = Boataction.PD;}}

搜索路径

while (queue.Count > 0){temp = queue.Peek();if (temp == end){while (temp.parent_state != start){temp = temp.parent_state;}return temp;}queue.Dequeue();if (temp.pos){if (temp.lp > 0){GameState next = new GameState(temp);next.parent_state = new GameState(temp);next.pos = false;next.lp--;next.rp++;if (next.isValid() && !queue.Contains(next)){queue.Enqueue(next);}}if (temp.ld > 0){GameState next = new GameState(temp);next.parent_state = new GameState(temp);next.pos = false;next.ld--;next.rd++;if (next.isValid() && !queue.Contains(next)){queue.Enqueue(next);}}if (temp.ld > 0 && temp.lp > 0){GameState next = new GameState(temp);next.parent_state = new GameState(temp);next.pos = false;next.ld--;next.rd++;next.lp--;next.rp++;if (next.isValid() && !queue.Contains(next)){queue.Enqueue(next);}}if (temp.lp > 1){GameState next = new GameState(temp);next.parent_state = new GameState(temp);next.pos = false;next.lp -= 2;next.rp += 2;if (next.isValid() && !queue.Contains(next)){queue.Enqueue(next);}}if (temp.ld > 1){GameState next = new GameState(temp);next.parent_state = new GameState(temp);next.pos = false;next.ld -= 2;next.rd += 2;if (next.isValid() && !queue.Contains(next)){queue.Enqueue(next);}}}else{if (temp.rp > 0){GameState next = new GameState(temp);next.parent_state = new GameState(temp);next.pos = true;next.rp--;next.lp++;if (next.isValid() && !queue.Contains(next)){queue.Enqueue(next);}}if (temp.rd > 0){GameState next = new GameState(temp);next.parent_state = new GameState(temp);next.pos = true;next.rd--;next.ld++;if (next.isValid() && !queue.Contains(next)){queue.Enqueue(next);}}if (temp.rd > 0 && temp.rp > 0){GameState next = new GameState(temp);next.parent_state = new GameState(temp);next.pos = true;next.rd--;next.ld++;next.rp--;next.lp++;if (next.isValid() && !queue.Contains(next)){queue.Enqueue(next);}}if (temp.rd > 1){GameState next = new GameState(temp);next.parent_state = new GameState(temp);next.pos = true;next.rd -= 2;next.ld += 2;if (next.isValid() && !queue.Contains(next)){queue.Enqueue(next);}}if (temp.rp > 1){GameState next = new GameState(temp);next.parent_state = new GameState(temp);next.pos = true;next.rp -= 2;next.lp += 2;if (next.isValid() && !queue.Contains(next)){queue.Enqueue(next);}}}}return null;}

最后,更新GUI,以便正确提示输出即可

    void OnGUI(){GUIStyle fontstyle = new GUIStyle();fontstyle.normal.background = null;fontstyle.normal.textColor = new Color(255, 192, 203);fontstyle.fontSize = 50;style = new GUIStyle(){fontSize = 16};style.normal.textColor = new Color(0, 0, 0);buttonStyle = new GUIStyle("button"){fontSize = 16};if (GUI.Button(new Rect (Screen.width/2 - 50 , Screen.height- 50, 100, 40), "Reset", buttonStyle)){status = 0;userAction.Restart();}if (status == 1){GUI.Label(new Rect (Screen.width/2- 50, 50, 100, 40), "Lose", style);}else if (status == 2){GUI.Label(new Rect (Screen.width/2- 50, 50, 100, 40), "Win", style);}GUI.Button(new Rect(Screen.width/2 - 150 , 30, 400, 40), tips, style);if (GUI.Button(new Rect(Screen.width/2 - 300 , 30, 100, 40), "Tips", buttonStyle)){int[] arr = userAction.getStateInfo();leftPriests = arr[0];leftDevils = arr[1];rightPriests = arr[2];rightDevils = arr[3];if (arr[4] == 0) boat_pos = true;else boat_pos = false;start = new GameState(leftPriests, leftDevils, rightPriests, rightDevils, boat_pos, null);GameState temp = GameState.BFS(start, end);int p = leftPriests - temp.lp;int d = leftDevils - temp.ld;if (p < 0) p = -p;if (d < 0) d = -d;tips = "Move " + p + " priest(s)," + d+ " devil(s) to another side.";}}

GUI更新

最后,我们更新GUI,从而能够正确提示即可

    void OnGUI(){GUIStyle fontstyle = new GUIStyle();fontstyle.normal.background = null;fontstyle.normal.textColor = new Color(255, 192, 203);fontstyle.fontSize = 50;style = new GUIStyle(){fontSize = 16};style.normal.textColor = new Color(0, 0, 0);buttonStyle = new GUIStyle("button"){fontSize = 16};if (GUI.Button(new Rect (Screen.width/2 - 50 , Screen.height- 50, 100, 40), "Reset", buttonStyle)){status = 0;userAction.Restart();}if (status == 1){GUI.Label(new Rect (Screen.width/2- 50, 50, 100, 40), "Lose", style);}else if (status == 2){GUI.Label(new Rect (Screen.width/2- 50, 50, 100, 40), "Win", style);}GUI.Button(new Rect(Screen.width/2 - 150 , 30, 400, 40), tips, style);if (GUI.Button(new Rect(Screen.width/2 - 300 , 30, 100, 40), "Tips", buttonStyle)){int[] arr = userAction.getStateInfo();leftPriests = arr[0];leftDevils = arr[1];rightPriests = arr[2];rightDevils = arr[3];if (arr[4] == 0) boat_pos = true;else boat_pos = false;start = new GameState(leftPriests, leftDevils, rightPriests, rightDevils, boat_pos, null);GameState temp = GameState.BFS(start, end);int p = leftPriests - temp.lp;int d = leftDevils - temp.ld;if (p < 0) p = -p;if (d < 0) d = -d;tips = "Move " + p + " priest(s)," + d+ " devil(s) to another side.";}}

Unity学习之PD 过河游戏智能帮助实现相关推荐

  1. 【Unity 3D学习笔记】PD 过河游戏智能实现

    P&D 过河游戏智能帮助实现 实现状态图的自动生成 讲解图数据在程序中的表示方法 利用算法实现下一步的计算 对于过河游戏,首先需要知道其中各个状态之间的转换关系,绘制状态转移图如下: 其中,P ...

  2. unity:PD 过河游戏智能帮助实现

    P&D 过河游戏智能帮助实现 github传送门 状态图 状态图课件有 状态图(Statechart Diagram)是描述一个实体基于事件反应的动态行为,显示了该实体如何根据当前所处的状态对 ...

  3. Unity3d入门之路-PD 过河游戏智能帮助

    文章目录 P&D 过河游戏智能帮助 状态图 实现方法 图的表示方法 广度优先搜索 P&D 过河游戏拓展 结果展示 P&D 过河游戏智能帮助 本次作业基本要求是三选一,我选择了P ...

  4. 3D游戏编程实践——PD 过河游戏智能帮助实现

    P&D 过河游戏智能帮助实现 需求 实现状态图的自动生成 讲解图数据在程序中的表示方法 利用算法实现下一步的计算 实现过程 实现状态图的自动生成&讲解图数据在程序中的表示方法 牧师与魔 ...

  5. PD 过河游戏智能帮助实现

    github传送门 https://github.com/ddghost/unity3d_n/tree/R%26D%E6%99%BA%E8%83%BD%E5%B8%AE%E5%8A%A9%E6%8F% ...

  6. 3D游戏编程与设计 PD(牧师与恶魔)过河游戏智能帮助实现

    3D游戏编程与设计 P&D(牧师与恶魔) 过河游戏智能帮助实现 文章目录 3D游戏编程与设计 P&D(牧师与恶魔) 过河游戏智能帮助实现 一.作业与练习 二.设计简述 1. 状态图基础 ...

  7. 【Unity3d学习】魔鬼与牧师过河游戏智能帮助

    文章目录 写在前面 实验内容 状态图自动生成(使用DFS) 1. 状态表示 2.DFS算法实现 3.DFS生成结果 更改Controller 效果展示 写在前面 本次项目Github地址:传送门 本次 ...

  8. Unity学习笔记—二次元日系游戏制作(实践篇-游戏初始化场景制作)

    原教程:siki:二次元日系游戏制作工具 - live2dSDK入门教程 http://www.sikiedu.com/my/course/282 (上)Unity学习笔记-二次元日系游戏制作(理论篇 ...

  9. [Unity学习笔记:FPS游戏制作(3)]子弹拖尾,碰撞与枪口火焰效果

    往期博客[Unity学习笔记:FPS游戏制作(2)] 发射子弹----(2021.6.20学习笔记) 文章目录 一,实现思路 二,粒子效果的实现 (1)子弹拖尾特效的实现 (2)枪口火焰特效的实现 ( ...

最新文章

  1. golang 接口类型 interface 简介
  2. asp.net中将枚举绑定到下拉列表
  3. 实现一个登录:Mac+.NET 5+Identity+JWT+VS Code
  4. 数据结构探险——图篇
  5. Chapter 3 Phenomenon——13
  6. Android 系统(236)---了解 64 位版本
  7. Deploy Oracle 10.2.0.5 on Red Hat Enterprise Linux 6.4
  8. c语言中注释参与程序设计的编译吗,C语言程序设计(第4章函数)6
  9. 华为星环大数据_华为和星环大数据平台关键能力对比(附报告)
  10. oracle怎么删除.dat,oracle 手工删库
  11. Adobe Photoshop 中的魔棒工具
  12. vue v-for循环表格 希望第四个<th>或<td>标签自动换到下一行应该怎么做?
  13. WebSpider简介
  14. 计算机培训简报膜报,第二期计算机培训简报(第十二期)
  15. 单基因gsea_10个细胞系仅1个表达你的基因
  16. python 多态app_多态简介 | Python从入门到精通:高阶篇之三十三-阿里云开发者社区...
  17. 使用JSP/Servlet技术开发新闻发布系统
  18. 十进制转换为十六进制-八进制-二进制的进制转换计算
  19. VUE DIFF算法之双端DIFF
  20. c语言 access方法,c语言连接access数据库(odbc)方式

热门文章

  1. 你知道怎么查看微信绑定了哪些软件吗
  2. python sendmessage 鼠标_sendmessage()模拟鼠标点击
  3. 江苏魔百盒M301H_Hi3798MV300-300H-310芯片通刷-免费卡刷固件包
  4. CrystalDiskInfo磁盘工具及下载地址
  5. Excel IF 多层条件判断函数语句
  6. windows,linux 蚁剑下载与安装 与 手动安装插件disable_functions
  7. 用for的嵌套画出各种各样的图形
  8. matlab %4.3f,MATLAB程序设计教程(4)—MATLAB文件操作
  9. 基于STM32WIFI远程监控电压电流表(四)ADS122C04模块设计
  10. PROTAC与抗体偶联药物的结合