首页 > 编程语言 >【老白学 Java】休闲时刻 - 打造 CMD 战舰(三)

【老白学 Java】休闲时刻 - 打造 CMD 战舰(三)

时间:2024-11-18 15:46:47浏览次数:3  
标签:Java String int CMD 玩家 result cellsLocation 战舰 老白学

休闲时刻 - 打造 CMD 战舰(三)

码老白
文章来源:《Head First Java》修炼感悟。

上一篇,老白通过「硬编码」对战舰类的功能模块进行了简单测试。 本篇的主要任务是继续完善战舰类并反复测试,其中涉及到几个新技术,师兄们如果感兴趣,请接着往下看。


项目进度:

  • 列出必要的程序清单
  • 简单描述核心功能的实现方式
  • 根据程序清单写出空类、空方法(不要求具体实现)
  • 编写测试代码,确保功能模块之间正常调用
  • 编写战舰类方法的具体实现,测试+修改
  • 编写玩家类方法实现,测试+修改
  • 整理代码,关键位置加入注释

任务五、完善战舰类功能模块

不要忘记,Warship 类中的 setCellsLocationreturnFireResult 两个方法还没有任何代码,现在就赋予它们「超能力」。

1、实现方法 setCellsLocation()

只做一件事,就是设置自身方位。 上一篇中老白说过,这个方法会传入一个 int 数组。 不要考虑是谁传进来的(很有可能是电脑随机生成的),只考虑要怎样接收这个参数。 其实很简单,先声明一个私有变量 cellsLocation,然后把传进来的参数赋值给 cellsLocation 就可以了,就像这样:

// 用来保存战舰格子的方位数组
private int[] cellsLocation;
	
// 设置战舰格子的当前方位
public void setCellsLocation(int[] locs) {
	this.cellsLocation = locs;
}

2、实现方法 returnFireResult()

这个方法稍微有点复杂,老白把关注点列出来,然后逐条解释:

  • 需要对传入的 String 类型参数进行转换;
  • 需要实现一个循环,把自己的方位格子与传进来的猜测值逐个比较;
  • 如果检测出被击中,还需要进行二次检测,判断是否被 kill;
  • 需要返回本次攻击效果。

看看代码是如何实现的:

// 检查当前格子是否被击中,并返回信息
public String returnFireResult(String hitLoc) {

	// 把传入的字符串解析为整型数字,不要过问如何解析的
	int loc = Integer.parseInt(hitLoc);

	// 用于保存每次攻击的效果,默认为「未击中」
	String result = "miss";

	// 自身所有格子与玩家猜测的位置逐个进行比较,
	// 如果某个格子与玩家猜测值相等,则表示那个格子被玩家击中,
	// 生命值就会被减掉1点,然后直接中断循环,放弃后面的比较。
	for (int cell : cellsLocation) {
		if (loc == cell) {
			result = "hit";	// 击中
			hitPoints--;	// 减掉1点生命值
			break;			// 中断循环
		}
	}

	// 判断是否被击杀
	if (hitPoints < 1) {
		result = "kill";
	}

	// 返回本次攻击结果
	System.out.println(result);
	return result;
}
2.1、解析字符串 Integer.parseInt()
int loc = Integer.parseInt(hitLoc);

上面这条语句,我在注释中提到「不要过问怎么解析的」,因为 parseInt() 是 Java 内建的 Integer 类提供的一个静态方法。 只需知道它的作用是「把参数指定的字符串转换为整型值」就可以了,具体怎样转换的你无需关注。 在我们这个项目中,参数 hitLoc 是玩家输入的猜测值(类型为 String),经过解析后转换为 int 值赋给 loc

2.2、加强版 for 循环

紧接着是一个加强版的 for 循环,老白在前面提过,现在来详细说说。
正常情况下,我们使用的都是普通的 for 循环,比如这种形式 for(int i=0;i<5;i++){}。 从 Java1.5 开始新增了加强版的 for 循环,就像代码中使用的这样:

for (int cell : cellsLocation) {
	// 进入循环体,你可以「随心所欲」地去处理 cell
}

这种 for 循环多用于引用类型数组或集合,处理数组中的对象元素很方便。 就像注释中说的,给老白的感觉就是「随心所欲」。 它会把数组中的每一个元素都迭代一次,让你有机会对每个元素都做点什么。 目前我们正在做的是把玩家猜测值与战舰自身的每个格子都比较一次:

for (int cell : cellsLocation) {
	if (loc == cell) {
		// 能够执行到 if 中,说明战舰已经被击中
		result = "hit";	// 把返回结果标记为「击中」
		hitPoints--;	// 减掉1点生命值
		break;			// 中断循环
	}
}

注意 :

  • hitPoint-- ,这种代码称为「自减」,等效为 hitPoint = hitPoint-1
  • break,表示中断循环,直接跳出循环体外,继续执行下一条语句。
    代码中,如果检测到玩家猜测值与战舰位置一致,那么直接中断 for 循环,也没有必要继续检查余下的几个位置。 有没有感觉提高了一点点执行效率?
2.3、Kill 检查

这个判断语句很好理解,检查生命点数是否小于 1。 小于 1 意味着 0 或者以下,可以直接判定 Kill 了。

// 检查 hitPoint 点数
if (hitPoints < 1) {
	result = "kill";	// 把返回结果标记为「击杀」
}
2.4、返回打击效果

返回语句 return 没什么好说的,就是返回 hit、miss、kill 其中的一个。 必须要返回,因为方法声明时已经明确表示要返回一个 String 值。 这个返回值可以有很多用处,老白就很喜欢使用打印语句返回点信息。 如果在测试期间调用某个方法后没有任何反应,感觉心里不踏实。

3、功能模块测试

以上工作完成后,我们再来测试一次。 因为上一篇已经检验过测试类,各功能模块配合良好,所以不会担心代码结构出现问题。 只要不随便改动变量名、方法名,那么允许你在方法中「肆意妄为」。

这次只是在方法中动了「手脚」,所以测试类不需要任何改动。 Warship.java 重新编译一次,然后执行:
hit
把测试类中玩家的猜测值改为其它值再试一次(测试类需要重新编译):

// 模拟玩家猜测值
String guess = "5";

missPerfect! 程序准确地识别出本次攻击结果为「miss」。

是不是感觉小有成就? 但每次总是这样改动猜测值,确实有点痛苦。 下一篇我们将实现玩家辅助类,通过键盘输入猜测值,从此再无「烦恼」。


《 上一篇 休闲时刻 - 打造 CMD 战舰(二)

标签:Java,String,int,CMD,玩家,result,cellsLocation,战舰,老白学
From: https://blog.csdn.net/liujun_sdn/article/details/143836521

相关文章

  • [JavaScript]将数组按照parentId和id整理成树状结构
     JavaScriptfunctionarrayToTree(items){constrootItems=[];constlookup={};for(constitemofitems){constitemId=item.id;lookup[itemId]=item;constparentId=item.parentId;if(parentId===n......
  • javascript-表达式与操作符
    1.数组初始化二维数组letmatrix=[[1,2,3],[4,5,6],[7,8,9]];未定义元素undefinedletsparseArray=[1,,,,5];包含三个未定义元素2.对象初始化letp={x:2.3,y:-1.2};点对象包含x,y坐标letq={};空对象q.x=2.3;q.y=-1.2;赋值3.函数letsquare=function(x){returnx*x;};......
  • 前端必知必会-JavaScript For Of循环
    文章目录JavaScriptForOf循环循环遍历数组循环遍历字符串总结JavaScriptForOf循环ForOf循环JavaScriptforof语句循环遍历可迭代对象的值。它允许您循环遍历可迭代数据结构,例如数组、字符串、映射、节点列表等:语法for(variableofiterable){//要......
  • 前端必知必会-JavaScript Break and Continue
    文章目录JavaScriptBreak和ContinueBreak语句Continue语句JavaScript标签总结JavaScriptBreak和Continuebreak语句“跳出”循环。continue语句“跳过”循环中的一次迭代。Break语句break语句用于“跳出”switch()语句。break语句也可用于跳出......
  • 代码随想录算法训练营第三十二天| 509. 斐波那契数 、70. 爬楼梯、746. 使用最小花费
    理论基础总结一下就是:动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的。动态规划五部曲确定dp数组(dptable)以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组509.斐波那契数1.......
  • 代码随想录算法训练营第三十三天| 62.不同路径 、63. 不同路径 II、343. 整数拆分 。c
    62.不同路径思路:按照dp五步法分析,成功AC。代码随想录classSolution{publicintuniquePaths(intm,intn){int[][]dp=newint[m+1][n+1];dp[0][1]=1;for(inti=1;i<=m;i++){for(intj=1;j<=n;j++){......
  • Java 基础 - 字符串类
    字符串类重要的字符串类有String、StringBuilder、StringBuffer1、StringString是不可变类,内部是由final定义的字符数据构成。privatefinalcharvalue[];1.1String类的层次结构如下:String实现了比较接口,字符序列接口,序列化接口,具有以上接口的特性1.2重写了Obje......
  • 关于Java中算法的基础运用与讲解
    1.冒泡排序(BubbleSort)基本思路通过重复遍历要排序的列表,一次比较两个元素,如果它们的顺序错误就交换它们。这个过程会重复进行直到没有更多的交换需要做,这意味着列表已经排序完成。详细步骤外层循环:遍历数组的每个位置i,表示已经进行了多少轮比较。内层循环:从位置0......
  • javaScript交互案例
    1、模态框(弹出框)(1)、需求:点击弹出层,会弹出模态框,并且显示灰色半透明的遮挡层点击关闭按钮,可以关闭模态框,并且同时关闭半透明遮挡层鼠标放在模态框最上面一行,可以按住鼠标拖拽模态框在页面中移动鼠标松开,可以停止拖动模态框移动思路:点击弹出层,模态框和遮挡层就会显示出来d......
  • Java集合框架、集合工具类Collections、泛型 ;代码之滑动窗口总结(11.15)
    Java基础学习迭代器1、迭代器的指针一开始在集合的上方next():指针下移,下移以后返回指针指向的值2、使用迭代器遍历集合元素 //正确写法Iteratoriterator=coll.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}//错误写法,......