Katas编写的Java教程:Mars Rover

编程kata是一种练习,可以帮助程序员通过练习和重复练习来磨练自己的技能。

本文是“ 通过Katas进行Java教程 ”系列的一部分。

本文假定读者已经具有Java的经验,熟悉单元测试的基础知识,并且知道如何从他最喜欢的IDE(我是IntelliJ IDEA )运行它们。

下面显示证明解决方案正确的测试。 解决此问题的推荐方法是使用测试驱动的开发方法(编写第一个测试的实现,确认它通过并转到下一个测试)。 一旦所有测试通过,就可以认为解决了问题。 有关最佳做法的更多信息,请阅读“ 测试驱动开发(TDD):使用Java范例的最佳做法” 。

测试下方提供了一种可能的解决方案。 尝试先自己解决kata。

火星漫游者

开发一个可在网格上移动漫游车的API。

规则:

  • 您将获得流动站的初始起点(x,y)及其面向的方向(N,S,E,W)。
  • 流动站接收命令的字符数组。
  • 实施使漫游车前进/后退(f,b)的命令。
  • 实现使流动站左/右(l,r)旋转的命令。
  • 实现从网格的一个边缘到另一边缘的环绕。 (行星毕竟是球体)
  • 每次移动到新的广场之前,请执行障碍检测。 如果给定的命令序列遇到障碍物,则流动站将移动到最后一个可能的点并报告障碍物。

测验

以下是一组可用于以TDD方式解决此问题的单元测试。

package com.technologyconversations.kata.marsrover;import org.junit.Before;
import org.junit.Test;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;import static org.assertj.core.api.Assertions.*;/*
Source: http://dallashackclub.com/roverDevelop an api that moves a rover around on a grid.
* You are given the initial starting point (x,y) of a rover and the direction (N,S,E,W) it is facing.
* - The rover receives a character array of commands.
* - Implement commands that move the rover forward/backward (f,b).
* - Implement commands that turn the rover left/right (l,r).
* - Implement wrapping from one edge of the grid to another. (planets are spheres after all)
* - Implement obstacle detection before each move to a new square.
*   If a given sequence of commands encounters an obstacle, the rover moves up to the last possible point and reports the obstacle.
*/
public class RoverSpec {private Rover rover;private Coordinates roverCoordinates;private final Direction direction = Direction.NORTH;private Point x;private Point y;private List<Obstacle> obstacles;@Beforepublic void beforeRoverTest() {x = new Point(1, 9);y = new Point(2, 9);obstacles = new ArrayList<Obstacle>();roverCoordinates = new Coordinates(x, y, direction, obstacles);rover = new Rover(roverCoordinates);}@Testpublic void newInstanceShouldSetRoverCoordinatesAndDirection() {assertThat(rover.getCoordinates()).isEqualToComparingFieldByField(roverCoordinates);}@Testpublic void receiveSingleCommandShouldMoveForwardWhenCommandIsF() throws Exception {int expected = y.getLocation() + 1;rover.receiveSingleCommand('F');assertThat(rover.getCoordinates().getY().getLocation()).isEqualTo(expected);}@Testpublic void receiveSingleCommandShouldMoveBackwardWhenCommandIsB() throws Exception {int expected = y.getLocation() - 1;rover.receiveSingleCommand('B');assertThat(rover.getCoordinates().getY().getLocation()).isEqualTo(expected);}@Testpublic void receiveSingleCommandShouldTurnLeftWhenCommandIsL() throws Exception {rover.receiveSingleCommand('L');assertThat(rover.getCoordinates().getDirection()).isEqualTo(Direction.WEST);}@Testpublic void receiveSingleCommandShouldTurnRightWhenCommandIsR() throws Exception {rover.receiveSingleCommand('R');assertThat(rover.getCoordinates().getDirection()).isEqualTo(Direction.EAST);}@Testpublic void receiveSingleCommandShouldIgnoreCase() throws Exception {rover.receiveSingleCommand('r');assertThat(rover.getCoordinates().getDirection()).isEqualTo(Direction.EAST);}@Test(expected = Exception.class)public void receiveSingleCommandShouldThrowExceptionWhenCommandIsUnknown() throws Exception {rover.receiveSingleCommand('X');}@Testpublic void receiveCommandsShouldBeAbleToReceiveMultipleCommands() throws Exception {int expected = x.getLocation() + 1;rover.receiveCommands("RFR");assertThat(rover.getCoordinates().getX().getLocation()).isEqualTo(expected);assertThat(rover.getCoordinates().getDirection()).isEqualTo(Direction.SOUTH);}@Testpublic void receiveCommandShouldWhatFromOneEdgeOfTheGridToAnother() throws Exception {int expected = x.getMaxLocation() + x.getLocation() - 2;rover.receiveCommands("LFFF");assertThat(rover.getCoordinates().getX().getLocation()).isEqualTo(expected);}@Testpublic void receiveCommandsShouldStopWhenObstacleIsFound() throws Exception {int expected = x.getLocation() + 1;rover.getCoordinates().setObstacles(Arrays.asList(new Obstacle(expected + 1, y.getLocation())));rover.getCoordinates().setDirection(Direction.EAST);rover.receiveCommands("FFFRF");assertThat(rover.getCoordinates().getX().getLocation()).isEqualTo(expected);assertThat(rover.getCoordinates().getDirection()).isEqualTo(Direction.EAST);}@Testpublic void positionShouldReturnXYAndDirection() throws Exception {rover.receiveCommands("LFFFRFF");assertThat(rover.getPosition()).isEqualTo("8 X 4 N");}@Testpublic void positionShouldReturnNokWhenObstacleIsFound() throws Exception {rover.getCoordinates().setObstacles(Arrays.asList(new Obstacle(x.getLocation() + 1, y.getLocation())));rover.getCoordinates().setDirection(Direction.EAST);rover.receiveCommands("F");assertThat(rover.getPosition()).endsWith(" NOK");}}

以下是一种可能的解决方案。

package com.technologyconversations.kata.marsrover;/*
Method receiveCommands should be used to transmit commands to the rover.*/
public class Rover {private Coordinates coordinates;public void setCoordinates(Coordinates value) {coordinates = value;}public Coordinates getCoordinates() {return coordinates;}public Rover(Coordinates coordinatesValue) {setCoordinates(coordinatesValue);}public void receiveCommands(String commands) throws Exception {for (char command : commands.toCharArray()) {if (!receiveSingleCommand(command)) {break;}}}public boolean receiveSingleCommand(char command) throws Exception {switch(Character.toUpperCase(command)) {case 'F':return getCoordinates().moveForward();case 'B':return getCoordinates().moveBackward();case 'L':getCoordinates().changeDirectionLeft();return true;case 'R':getCoordinates().changeDirectionRight();return true;default:throw new Exception("Command " + command + " is unknown.");}}public String getPosition() {return getCoordinates().toString();}}

完整源代码位于GitHub存储库[https://github.com/vfarcic/mars-rover-kata-java)中。 上面的代码仅表示主类的代码。 还有其他几个类/对象及其相应的规范。 除了测试和实现之外,存储库还包括build.gradle,可用于下载AssertJ依赖项并运行测试README.md包含有关如何设置项目的简短说明。

您有什么解决方案? 将其发布为评论,以便我们可以比较解决此kata的不同方法。

翻译自: https://www.javacodegeeks.com/2014/10/java-tutorial-through-katas-mars-rover.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362364.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

es6 includes(), startsWith(), endsWith()

传统上&#xff0c;JavaScript 只有 indexOf方法&#xff0c;可以用来确定一个字符串是否包含在另一个字符串中。ES6 又提供了三种新方法。includes()&#xff1a;返回布尔值&#xff0c;表示是否找到了参数字符串。startsWith()&#xff1a;返回布尔值&#xff0c;表示参数字符…

Rails之格式化价格方法

一种是直接在试图中队价格信息进行格式化如&#xff1a;<div class"price"><%sprintf("&#xffe5;%0.02f",product.price)%></div>另外一种是用单独的辅助方法来处理价格格式化&#xff0c;即number_to_currency&#xff0c;如&#x…

CodeCombat代码全记录(Python学习利器)--Kithgard地牢代码1

Kithgard地牢注意&#xff1a;在调用函数时&#xff0c;要在函数的后面加上括号内容&#xff0c;否则在python中&#xff0c;将不会认为你在调用这个函数内容&#xff0c;而你的英雄将像木头一样站在原地不会执行上左下右的移动&#xff01;&#xff01;&#xff01; hero.move…

layui upload阻止文件上传问题,及多选文件上传

1、效果展示&#xff1a; 2、需求&#xff1a; 下拉框及月份都为不空&#xff0c;且有文件数据才能提交上传。 3、环境&#xff1a; 目前项目中引用的 layui 版本是 2.4.5。在 before 中进行判断&#xff0c;使用 return false 想要阻止文件上传没反应&#xff0c;文件仍然会…

JPA教程:实体映射-第2部分

在上一篇文章中&#xff0c;我展示了一种持久保存实体的简单方法。 我解释了JPA用于确定实体默认表的默认方法。 假设我们要覆盖此默认名称。 我们之所以喜欢这样做&#xff0c;是因为数据模型是以前设计和修复的&#xff0c;并且表名与我们的类名不匹配&#xff08;例如&#…

Vue DOM事件

本文参考自&#xff1a;https://mp.weixin.qq.com/s?src3&timestamp1527154113&ver1&signaturetWGeTa86gyK*RL0P7nwlA6-8V14FjzxUTh7CM9kQLjl0DV3sx*2hKauMGZKoYBkTSp14Zw6MOD8pU-haYmJoNTSBI5rptCZwf3wTIXLUMUOYDOPZtxm9wJaSm0l7vqshH98ToXQCcfm-5jR-Y66eAYzuFM5…

2019.06.17课件:[洛谷P1310]表达式的值 题解

P1310 表达式的值 题目描述 给你一个带括号的布尔表达式&#xff0c;其中表示或操作|&#xff0c;*表示与操作&&#xff0c;先算*再算。但是待操作的数字&#xff08;布尔值&#xff09;不输入。 求能使最终整个式子的值为0的方案数。 题外话 不久之前我在codewars上做过一…

vue+element 封装日期范围组件(双向绑定)

像这样的日期组件&#xff0c;在后台管理项目中是比较多的&#xff0c;而且加了快捷选项&#xff0c;代码量较多&#xff0c;因此封装成组件。 封装这一类型的组组件&#xff0c;主要是了解输入框双向绑定 v-model 的过程。 1、了解输入框双向绑定的过程&#xff1a; 官网&am…

句柄是什么?1

句柄是什么&#xff1f; 1.句柄是什么&#xff1f; 在windows中&#xff0c;句柄是和对象一一对应的32位无符号整数值。对象可以映射到唯一的句柄&#xff0c;句柄也可以映射到唯一的对象。2.为什么我们需要句柄&#xff1f; 更准确地说&#xff0c;是windows需要句柄。w…

用Hystrix保护您的应用程序

在之前的帖子http://www.javacodegeeks.com/2014/07/rxjava-java8-java-ee-7-arquillian-bliss.html中&#xff0c;我们讨论了微服务以及如何使用&#xff08;RxJava&#xff09;的Reactive Extensions编排微服务。 但是&#xff0c;如果一项或多项服务由于已被暂停或引发异常而…

python方法未绑定错误

相信 Python 程序员多多少少都和我一样遇到过 Method Unbound Error&#xff0c;直译过来就是 “方法未绑定错误”&#xff0c;虽然搜索之后知道了使用 classmethod 这样的装饰起后就可以解决问题&#xff0c; 但是一直没有得到完全解惑。 我们知道&#xff0c;Python 是一个动…

若依 从下载到成功运行及打包

官网&#xff1a;http://www.ruoyi.vip/ 目录 一、下载并运行项目 二、关于 若依 接口地址配置 2.1 若依的跨域代理介绍 2.2 配置跨域代理&#xff0c;调用后台接口 2.2.1 配置 后台 ip 地址 2.2.2 页面报“系统接口404”错误 三、打包配置 3.1 打包之后静态资源404…

Windows平台下 找回已丢失的MySql root 用户密码

该随笔供初学MySql者作为参考&#xff0c;本人第一次写博客&#xff0c;欢迎各位大虾拍砖&#xff01; 主要步骤&#xff1a; 1.关闭MySql服务 2.在控制台下键入cd命令&#xff0c;进入MySql的安装目录的Bin目录下 3.键入命令 mysqld --skip-grant-tables(参数大致意思&#xf…

JPA教程:实体映射-第3部分

在上一篇文章中&#xff0c;我展示了两种读取/写入持久实体状态的不同方法-字段和属性。 使用字段访问模式时&#xff0c;JPA使用反射直接从实体的字段读取状态值。 如果我们没有明确指定列名&#xff0c;它将直接将字段名转换为数据库列名。 在属性访问模式下&#xff0c;使用…

uniAPP小程序 子组件使用watch不生效,H5正常,小程序不正常(其实是子组件model选项的问题)

第一次用 uniapp 写小程序&#xff0c;还是遇到挺多问题的。写了一个下拉多选组件&#xff0c;发现同样的代码&#xff0c;在H5上运行效果正常&#xff0c;在小程序上压根不走 watch 。 uniapp官网&#xff1a;【全局配置 | uni-app官网】 看文档 watch 是支持H5、小程序的&…

jQuery EasyUI/TopJUI创建日期时间输入框

jQuery EasyUI/TopJUI创建日期时间输入框 日期时间输入框组件 HTML 和日期输入框类似&#xff0c;日期时间输入框允许用户选择日期和指定的时间并按照指定的输出格式显示。相比日期输入框&#xff0c;它在下拉面板中添加了一个时间微调器。 <div class"topjui-containe…

使用oracle 的 PL/Sql 定时执行一个存储过程

/*使用oracle 的 PL/Sql 定时执行一个存储过程 测试目的&#xff1a;在表 tab 中间隔一分钟插入一条数据 实现方案&#xff1a;1.通过 oracle 中 dbms_job 完成存储过程的定时调用2.在存储过程中完成相应的逻辑操作 脚本说名&#xff1a;以下代码为 dbms_job 操作的基本写法&am…

JPA教程:映射实体–第1部分

在本文中&#xff0c;我将讨论JPA中的实体映射过程。 至于我的示例&#xff0c;我将使用与 我以前的一篇文章中使用的模式相同的模式 。 在前两篇文章中&#xff0c;我解释了如何在Java SE环境中设置JPA。 我不打算为Web应用程序编写安装过程&#xff0c;因为Web上的大多数教程…

table 设置边框

本文引自&#xff1a;https://www.cnblogs.com/leona-d/p/6125896.html 示例代码&#xff1a; <!DOCTYPE html><html lang"zh"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width…

uniapp小程序 设置自定义导航栏

如下截图&#xff0c;通过 wx.getSystemInfoSync 计算得到的整个导航栏高度&#xff0c;其实是有3个部分的&#xff1a; 黄色&#xff1a;状态栏高度&#xff0c;uniapp文档中有给出&#xff1b;红色&#xff1a;胶囊高度&#xff0c;可以计算得出&#xff1b;绿色&#xff1a;…