==游戏介绍==
吃豆豆游戏规则介绍:如图1所示,黄色的是吃豆豆主角PacMan,你需要在避免被数个颜色的怪物Ghost追杀的同时把画面内所有白色的豆豆都吃掉。如果被怪物追上就会被怪物吃掉并因此减少一条性命。唯一不怕被怪物追上的情况是PacMan吃到了白色的大豆豆(图1中的2处红圈),这个时候会变成图2中的情况,所有的Ghost都变色了,这个时候的Ghost还可以被PacMan吃掉(获得的分数比吃到豆豆的分数还高!!)。一次游戏PacMan总共有3条命,我们希望你能设计自己的PacMan,尽可能地通过游戏提供的4个关卡(图1,3,4,5);如果通关的难度比较大,那么希望你在每一关中尽可能获得比较高的分数(左下角的“S”表示当前的分数)。
[imageright|图5|{UP}course_ai15_hw3/5.png][imageright|图4|{UP}course_ai15_hw3/4.png][imageright|图3|{UP}course_ai15_hw3/3.png][imageright|图2|{UP}course_ai15_hw3/2.png][imageright|图1|{UP}course_ai15_hw3/1.png]
[{UP}course_ai15_hw3/PacMan.zip|点击下载(5月20日更新)],包含
* src目录,为PacMan实验源代码
* data目录,为游戏的资源,放在运行目录下
* weka.jar, 为机器学习开源软件包WEKA,详细信息请见[^http://www.cs.waikato.ac.nz/ml/weka/]
* j48.model, 我训练的一个简单模型
==程序包介绍==
程序需要使用 weka.jar 中的学习算法,确保weka.jar加载到路径中,让Java能找到。
程序总共分成3个包:
# 游戏运行: Exe包。主要用于选择相应的PacMan和Ghost,并启动游戏进行测试。在Exe包中,已写好了DataCollect.java,Executor.java,和MyPacMan.java
## DataCollect.java,用于收集人的控制数据
## Executor.java,用于AI自动玩游戏
## MyPacMac,使用训练好的模型自动控制PacMan
# 控制: pacman.controllers。其中Controller是父类,HumanController是通过键盘的“上下左右”手工控制Pacman的类,而examples包中的类都是提供给大家参考的PacMan和Ghost的示例,比如:RandomPacMan就是采取随机动作的PacMan,NearestPillMan就是采取贪心策略,每次朝着最近的豆豆移动的PacMan。
# 游戏相关设置: pacman.game。比较重要的是Constants类和Game类。Constants类包括了很多游戏中常量参数的定义,比如:PacMan和Ghost能够采取的动作;而Game类则是游戏运行时可以获得相关信息的接口,对于设计自己的PacMan的决策相当重要,里面可用的信息会在后面说明。而其余的类主要用于游戏内部逻辑的设计,比如:节点类Node,地图类Maze。
==熟悉代码==
主要在Exe包中的Executor类中,我们在main函数中写了三种不同的运行方式:
# 可视化+简单自动PacMan:可以直观地看到PacMan的运行情况{{{{exec.runGame(new NearestPillPacMan(),new RandomGhosts(),visual,delay);}}}}
** 请阅读 RandomPacMan()和NearestPillPacMan() 类,了解如何控制PacMan
# 批量测试+简单自动PacMan:可以快速测出PacMan的得分,{{{{exec.runExperiment(new RandomPacMan(),new RandomGhosts(),numTrials);}}}}
# 可视化+使用训练好的模型:{{{{exec.runGame(new MyPacMan("j48.model"),new RandomGhosts(),visual,delay);}}}}这里的j48.model是我预先训练的模型
同学们可以运行Executor来看看有什么效果。
==可使用的信息==
# PacMan和ghost的动作有五个:UP,RIGHT,DOWN,LEFT,NEUTRAL(当前动作=上一次动作)。具体参见:包pacman.game中的Constants.java。
# 图中点与点之间的距离,提供了三种不同的测量方式:路径距离: 地图上的距离 (比如从当前位置到达目标位置需要采用的步数);欧氏距离和曼哈顿距离(同离散数学课本中的定义)。具体参见:包pacman.game中的Constants.java。
# 关卡选择:游戏共有四个不同的关卡,可以通过创建不同的Game类示例获得:{{{{Game game = Game(long seed, int initialMaze)}}}} 中的参数initialMaze(0,1,2,3)选择具体的游戏关卡,另外一个参数seed对应游戏中某些情况下产生随机数(比如:RandomGhost的随机动作选择)所需要的随机种子。
下面主要介绍一下通过Game类可以获得的一些游戏运行时重要的相关信息:
# 得到PacMan的当前index(图中的每个位置除了坐标{x,y}表示外,还有唯一的index){{{{public double getDistance(int fromNodeIndex, int toNodeIndex, DM distanceMeasure)}}}}
# 得到图中所有还没被吃掉的小豆豆的index集合{{{{public int
[] getActivePillsIndices()}}}}
# 得到图中所有还没被吃掉的大豆豆的index集合{{{{public int
[] getActivePowerPillsIndices()}}}}
# 得到两点之间基于distanceMeasure模式的距离{{{{public double getDistance(int fromNodeIndex, int toNodeIndex, DM distanceMeasure)}}}}
# 得到基于distanceMeasure模式下,距离fromNode最近的targetNode集合中的点的index{{{{public int getClosestNodeIndexFromNodeIndex(int fromNodeIndex, int
[] targetNodeIndices, DM distanceMeasure) }}}}
# 得到基于distanceMeasure模式下,得到从fromNode到targetNode最短路线的下一步动作{{{{public MOVE getNextMoveTowardsTarget(int fromNodeIndex, int toNodeIndex, DM distanceMeasure) }}}}
# 判断游戏是否结束{{{{public boolean gameOver() }}}}
# 得到某个Ghost上一步的动作{{{{Public MOVE GhostLastMoveMade(GHOST ghostType)}}}}
# 得到某个Ghost还有多久才会恢复到正常的颜色(PacMan吃了大豆豆之后){{{{public int getGhostEdibleTime(GHOST ghostType) }}}}
# 得到当前得分{{{{public int getScore()}}}}
==训练自己的PacMan==
* 设计特征
我已写好一个简单的特征提取函数,在 Game.getFeature(int classValue) 中。请根据自己的想法设计特征,修改该函数。
* 收集数据
运行 Exe 包中的 DataCollect.java,并操作游戏,直到你认为数据已充足。你的操作数据和特征会被纪录到运行目录下的 PacManControlData.arff 文件中。该文件为文本文件,可以查看以理解文件结构。
* 训练模型{BR}使用下面命令可以启动weka图形界面{{{{java -Xmx1000m -jar weka.jar}}}}其中 -Xmx1000m 表示 java 最大可用内存为1000MB。
** 在weka启动界面中选择 Explorer,进入实验环境。
** 在“Preprocess”页面点击“Open file”来读入 PacManControlData.arff 文件
** 然后切换到 “Classify” 页面,训练分类器
*** 在 “Classifier” 部分选择 “Choose” 按钮,多种算法可选择,选择算法后,点击 “Choose” 按钮右边的文字栏,可修改算法参数
*** 在 “Test options” 部分选择 “Use training set” 后点击 “Start” 按钮,可用所有数据来训练模型。选择“”Cross-validation” 后点击 “Start” 按钮,可通过切分样本来估计算法的精度
*** 在 “Result list” 列出训练的模型,点击右键可保存模型
* 测试模型
在Executor.java中的代码 {{{{exec.runGame(new MyPacMan("j48.model"),new RandomGhosts(),visual,delay);}}}} 将读入模型进行PacMan控制。请将 “j48.model” 改为你训练的模型文件。
==作业内容==
# 解释 NearestPillPacMan 类对PacMan的控制方法
# 设计自己的特征,并介绍
# 选择学习方法,在收集的数据上训练模型,并解释你选择的学习方法的原理,以及有何优缺点
# 测试你的模型
==作业报告==
对于以上4点,使用 [{UP}course_ai15_hw1/template-2.doc|这个文档模版(点击下载)] 撰写实验报告。
==作业提交==
将
作业报告 存储为PDF文件,用学号命名,例如131221001.pdf,与你修改的源码打包为 学号命名的.zip文件
上传到 {{ftp://lamda.nju.edu.cn/AI/assignment3/}} (用户名: ai15, 密码: ai15)
(注意:该ftp不能替换文件,上传一次后,如果需要修改,请在文件名后加上版本号再上传,例如131221001-1.pdf)
注意:
作业严禁抄袭!