一:题目
扫雷小游戏:在MN的地图中找出所有地雷的位置每个正方形中的数字表示在它周围有几个地雷(周围即包围这个小正方形的8个小正方形)。输入将由任意数量的字段组成,每个字段的第一行包含两个整数n和m(n,m<100)组成,n,m代表行和列的数量。接下来的n行包括m个字符代表和扫雷地图。用字符.表示的是无雷区,用字符表示的是雷区。要求输出扫雷完成后的地图,地雷仍用*表示,无雷区用数字表示其周围的地雷数。
二:分析
首先用二位字符数组来存储地图,双重循环遍历地图。当遇到地雷时,什么都不做;当遇到无雷区时,定义一个计数变量count,然后内嵌双层循环,遍历寻找无雷区周围的地雷并用count计数(注意要在地图边界内寻找,不要越界!)。
三:代码
package week2;
import java.util.Scanner;
public class Main {
private static final Exception MineInputException = null;
public static void main(String[] args) throws Exception {
System.out.println("请输入扫雷地图的大小:");
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
char mine[][]=new char[n][m];
System.out.println("请画出扫雷地图,'.'表示非雷,'*'表示雷,符号以空格隔开!");
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
mine[i][j]=in.next().charAt(0);
}
try
{
sweeper(mine,n,m);
}
catch(MineInputException e)
{
System.out.println("捕获异常:"+e.toString()+"\n");
}
System.out.println("field #1:");
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
System.out.print(mine[i][j]+" ");
}
System.out.println("");
}
}
static void sweeper(char a[][],int n,int m)throws MineInputException
{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(a[i][j]=='*')
{
continue;
}
else if(a[i][j]=='.')
{
int count = 0;
for(int p=i-1;p<=i+1;p++)
for(int q=j-1;q<=j+1;q++)
{
if(p>=0&&q>=0&p<n&&q<m) //查找周围雷,注意地图边界
{
if(a[p][q]=='*')
count++;
}
}
String temp=String.valueOf(count); //int转换为char借助String实现
a[i][j]=temp.charAt(0);
}
else
{
MineInputException e = new MineInputException("输入非法,请输入'.'或'*'!");
throw e;
}
}
}
}
另外,我还添加了一个异常抛出,当输入的地图中字符既不是.也不是*时,抛出异常显示异常信息。
package week2;
public class MineInputException extends Exception{
MineInputException(String s)
{
super(s);
}
}
四:遇到的问题
1.整型变量转换为字符型变量
直接将整型强制转换为字符型,输出的其实是ASCII码表中该整数所代表的字符。
a[i][j]=(char) count;
结果是下图这种符号
创建一个String类型的中转变量,借助valueOf函数将整数转换为String型,然后再用String的charAt函数转换为char型
String temp=String.valueOf(count);
a[i][j]=temp.charAt(0);
结果:
2.添加异常捕获块
首先自定义一个异常类继承Exception类,在可能发生异常的代码部分中的函数声明throws 异常,if语句判断当放生错误,抛出异常。在主函数中使用try catch语句捕获异常并输出异常信息。