Tetris(初学Java第六篇)
欢迎来到bruno的blog。
- Tetris
- 应用介绍
- El-Tetris算法
- 单元测试
- 总结
Tetris
此次项目学习涉及了多方面的知识,如:单元测试,AI算法基础,注解等方面。
应用介绍
在El-AI算法的帮助下,游戏得分突破了6万大关(本人手残只能玩到200分)
El-Tetris算法
El-Tetris 算法是通过检测每一次掉落的骨牌的形状和位置来将其放置到最佳位置,其前身为Pierre Delacherie 算法。
在讲算法之前,我们应该先了解俄罗斯方块应该得怎么玩:
- 得放到哪个位置才好?
- 要怎么旋转到哪个方向?
然后再根据高玩得出的经验,我们再把游戏得分经验拆分成下面几点:
- 怎么放才能尽量不造成“空洞”?
- 放的时候要怎么才能清除最多的行数?
- 目前最高处的位置有多高?
- 清除了多少行?
- 清除了多少列?
- “空洞”的深度有多深?
所以根据这6个经验,我们的AI算法主要着重于这6个方面:
- Landing Height。表示当前方块放置之后的高度。
- Rows eliminated。表示当前方块落下后被消减的行数。
- Row Transitions。代表行变换的次数。
- Column Transitions。代表列变换的次数。
- Number of Holes。代表图中空洞的个数。
- Well Sums。表示 “(原翻译为 井)” 深度的连加和。在此 一个 (原翻译为 井) 代表左右都有方块,而中间处为 “空洞” 的地方。
算法根据这6个方面的权重来算出评估函数,权重主要通过 particle swarm optimization 训练而出。
权重:
Feature # | Weight |
---|---|
1 | -4.500158825082766 |
2 | 3.4181268101392694 |
3 | -3.2178882868487753 |
4 | -9.348695305445199 |
5 | -7.899265427351652 |
6 | -3.3855972247263626 |
这样我们在把骨牌放置的所有情况通过算法算出最佳放置的方式,再通过比较目前位置和旋转方向来移动骨牌,最终实现AI玩游戏的效果。
单元测试
什么是单元测试?
定义:单元测试是对软件或程序的基本(最小)组成单元的测试
对象:方法、类
特点:
我们为什么要写单元测试?
通过上面了解了单元测试的含义后,我们再通过Junit来进行单元测试(Junit是Java用来做单元测试的API, 是通过注解来识别测试用例的)。
@Rule
类似于拦截器,用于在测试方法执行前后添加额外的处理。实际上是@Before,@After的另一种实现。 使用时需要修饰符为public。Rule会应用于该类每个测试方法。
@Rulepublic Timeout timeout = Timeout.millis(100);//为全部测试程序设置时限
@Before
当编写测试方法时,经常会发现一些方法在执行前需要创建相同的对象;
使用@Before注解一个public void 方法会使该方法在@Test注解方法被执行前执行(那么就可以在该方法中创建相同的对象);
父类的@Before注解方法会在子类的@Before注解方法执行前执行。
@Test
@Test注解的public void方法将会被当做测试用例,JUnit每次都会创建一个新的测试实例,然后调用@Test注解方法
任何异常的抛出都会认为测试失败
@Test注解提供2个参数:
1,“expected”,定义测试方法应该抛出的异常,如果测试方法没有抛出异常或者抛出了一个不同的异常,测试失败
2,“timeout”,如果测试运行时间长于该定义时间,测试失败(单位为毫秒)
@Test
public void gamingAreaTest() {//常用的assert(断言)用法
assertEquals(a, b) 测试a是否等于b(a和b是原始类型数值(primitive value)或者必须为实现比较而具有equal方法)assertFalse(a) 测试a是否为false(假),a是一个Boolean数值。assertTrue(a) 测试a是否为true(真),a是一个Boolean数值assertNotNull(a) 测试a是否非空,a是一个对象或者null。assertNull(a) 测试a是否为null,a是一个对象或者null。assertNotSame(a, b) 测试a和b是否没有都引用同一个对象。assertSame(a, b) 测试a和b是否都引用同一个对象。
}
@Ignore
有时候我们想暂时不运行某些测试方法\测试类,可以在方法前加上这个注解。在运行结果中, junit会统计忽略的用例数,来提醒你。但是不建议经常这么做,因为这样的坏处时,容易忘记去更新这些测试方法,导致代码不够干净,用例遗漏。
@BeforeClass
当我们运行几个有关联的用例时,可能会在数据准备或其它前期准备中执行一些相同的命令,
这个时候为了让代码更清晰,更少冗余,可以将公用的部分提取出来,放在一个方法里,并为这个方法注解@BeforeClass。意思是在测试类里所有用例运行之前,运行一次这个方法。例如创建数据库连接、读取文件等。
@AfterClass
跟@BeforeClass对应,在测试类里所有用例运行之后,运行一次。用于处理一些测试后续工作,例如清理数据,恢复现场。
注意:同样必须是public static void,即公开、静态、无返回。这个方法只会运行一次。
总结
该项目主要让我学会了单元测试,了解了AI算法的概念、历史及应用,希望后面回顾的时候能有更多的理解。
Tetris(初学Java第六篇)相关推荐
- 魔域-文字rpg(初学Java第四篇)
Zork 前言 游戏界面及特性介绍 一.Code Refactoring 二.Composition and Inheritance 1.继承 2.组合 三.I/O Streams 总结 前言 学习目 ...
- java监听数据库操作_第十六篇——JDBC操作数据库之监听器
JavaWeb应用中,很多的地方都和session有关.因此session相关的事件监听器,在日常工作中非常有用. 有时候我们需要统计当前在线的人数和访问人数总数,此时就可以使用监听器技术来很简单的实 ...
- 第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单
我们来了解一下 自定义菜单创建接口: http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_to ...
- 初学Java (不要再删了!!!)
前言 这是我学Java时的作业.大概用了半个月时间.之前写出来一篇篇放到QQ空间,现在总结到一块.内容很多,都是Java基础内容.有很多写好的代码.有个朋友请教Java内容.我就把作业给她看,备她使用 ...
- 初学Java的那段日子
最近因为一个朋友想要学习Java,在帮助他找教程的过程中回想到了我自己当年学习Java的那段岁月,故写了此篇文章总结了一下初学Java所必须要掌握的知识点,然后把一部分常见的面试题罗列出来.给予刚刚开 ...
- 初学Java该学哪些知识?这6大知识必学
目前,Java是开发人员的热宠,很多论坛都有不少热爱Java的开发人员,也有不少想成为Java程序员,但苦于不知道该如何学习Java,也不清楚该学些什么知识才能成为一个Java程序员.小千在这里抛砖引 ...
- 史上最简单的SpringCloud教程 | 第六篇: 分布式配置中心(Spring Cloud Config)
转:https://blog.csdn.net/forezp/article/details/70037291 最新版本: 史上最简单的SpringCloud教程 | 第六篇: 分布式配置中心(Spr ...
- objective-c 编程总结(第六篇)运行时操作 - 方法交换
objective-c 编程总结(第六篇)运行时操作 - 方法交换 后面主要介绍oc类的运行时行为.这里面包括运行时方法的更换,消息的转发,以及动态属性.这些对于面向方面编程AOP的热爱者还是很有用的 ...
- EnjoyingSoft之Mule ESB开发教程第六篇:Data Transform - 数据转换
目录 1. 数据转换概念 2. 数据智能感知 - DataSense 3. 简单数据转换组件 3.1 Object to JSON 3.2 JSON to XML 3.3 JSON to Object ...
最新文章
- jquery总结和注意事项
- [MFC] MFC编译程序,缺少MFC动态链接库的解决
- python编写测试小工具-Python与游戏测试(小工具篇)
- Erlang虚拟机的启动
- 年年岁岁花相似,岁岁年年竟相同
- 怎样用注解的方式配置Spring?
- day9-Python学习笔记(二十)数据库备份,修改父类的方法
- 阿里云物联网 .NET Core 客户端 | CZGL.AliIoTClient:4. 设备上报属性
- 转载杨绛《一百岁感言》
- net修复工具_Stimulsoft Ultimate v2020.3.2修复性更新升级!| 附下载
- input标签中使输入文本向右偏移像素解决方案(亲测有效)
- 0712 - 坚守,加强老本
- Vue.js(8)- 父组件给子组件传值
- 以上是对图像的椒盐噪声处理,在p_temp[j*wide+i]=0;这句程序中为什么要乘以wide,求解,谢谢!
- 【T3】运行时错误3709
- SuperMap根据栅格数据制作专题图
- 网站服务器访问ip带宽限速,巧用IP带宽控制实现路由器限速
- 二维码条形码生成打印软件C#源码,根据变量自动添加抬头
- 《VALORANT》: 双塔迷城的诞生
- 广州首发跨境电商“全球卖”-成都扬帆牧哲跨境电商