1、游戏入口
package com.game;
public class AircraftModelTestDriver {
public static void main(String[] args) {
BombAirplaneGame game = new BombAirplaneGame();
game.startGame();
}
}
2、飞机模型
package com.game;
class AircraftModel {
int ROW = 4;
int COLUMN = 5;
int[] head;
int[][] position = new int[10][2];
/**
* 获取飞机头的坐标
*
* @return 飞机头坐标
*/
public int[] getHead() {
head = new int[]{position[0][0], position[0][1]};
return head;
}
/**
* 飞机头向上的飞机整体坐标
*
* @return 整体坐标
*/
public int[][] directionUp() {
position = NewPosition();
return position;
}
/**
* 飞机头向下的飞机整体坐标
*
* @return 整体坐标
*/
public int[][] directionDown() {
position = makeNegate(NewPosition());
return position;
}
/**
* 飞机头向右的飞机整体坐标
*
* @return 整体坐标
*/
public int[][] directionRight() {
position = makeExchange(NewPosition());
return position;
}
/**
* 飞机头向左的飞机整体坐标
*
* @return 整体坐标
*/
public int[][] directionLeft() {
position = makeExchange(makeNegate(NewPosition()));
return position;
}
/**
* 通过左下角坐标,更新整个飞机位置坐标
*
* @param location:"54" 代表 X轴 = 5,Y轴 = 4
* @return 更新后的飞机位置坐标
*/
public int[][] updateLocation(String location) {
for (int i = 0; i < position.length; i++) {
position[i][0] = position[i][0] + (int) location.charAt(0) - (int) ('0');
position[i][1] = position[i][1] + (int) location.charAt(1) - (int) ('0');
}
return position;
}
/**
* 通过左下角坐标,更新整个飞机位置坐标
*
* @param location:{5, 4} 代表 X轴 = 5,Y轴 = 4
* @return 更新后的飞机位置坐标
*/
public int[][] updateLocation(int[] location) {
for (int i = 0; i < position.length; i++) {
position[i][0] = position[i][0] + location[0];
position[i][1] = position[i][1] + location[1];
}
return position;
}
/**
* 通过左下角坐标,更新整个飞机位置坐标
*
* @param location:{5, 4} 代表 X轴 = 5,Y轴 = 4
* @param data:需要更新的坐标
* @return 更新后的飞机位置坐标
*/
public int[][] updateLocation(int[] location, int[][] data) {
for (int i = 0; i < data.length; i++) {
data[i][0] = data[i][0] + location[0];
data[i][1] = data[i][1] + location[1];
}
return data;
}
/**
* 随机返回一个方向的飞机模型
*
* @return 模型坐标
*/
public int[][] getRandomLocation() {
int num = (int) (Math.random() * 4);
switch (num) {
case 0:
position = directionUp();
break;
case 1:
position = directionDown();
break;
case 2:
position = directionLeft();
break;
case 3:
position = directionRight();
break;
}
return position;
}
/**
* 飞机初始坐标
*
* @return 飞机初始坐标
*/
private int[][] NewPosition() {
return new int[][]{
{2, 3},
{0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2},
{2, 1},
{1, 0}, {2, 0}, {3, 0},
};
}
/**
* 飞机坐标上下翻转
*
* @param data 飞机坐标
* @return 上下翻转后的坐标
*/
private int[][] makeNegate(int[][] data) {
for (int i = 0; i < data.length; i++) {
data[i][1] = ROW - data[i][1];
}
return data;
}
/**
* 飞机坐标左右翻转
*
* @param data 飞机坐标
* @return 左右翻转后的坐标
*/
private int[][] makeExchange(int[][] data) {
for (int i = 0; i < data.length; i++) {
int a = data[i][0];
int b = data[i][1];
data[i][0] = b;
data[i][1] = a;
}
return data;
}
}
3、游戏生成、规则判定、绘制棋盘
package com.game;
import java.util.Scanner;
import java.util.regex.Pattern;
class BombAirplaneGame {
// 定义三个模型
AircraftModel airmodel1;
AircraftModel airmodel2;
AircraftModel airmodel3;
// 棋盘 10 × 10
int SIZE = 10;
int[][] CHECKERBOARD = new int[SIZE][SIZE];
int[][] CHECKERBOARD_GUESS = new int[SIZE][SIZE];
// 击落数量
int KILL_NUM = 0;
// 绘制棋盘
String DRAWCHESSBOARD_1 = " *-----*-----*-----*-----*-----*-----*-----*-----*-----*-----*";
String DRAWCHESSBOARD_2 = " 0 1 2 3 4 5 6 7 8 9 ";
// 输入坐标校验
Pattern pattern = Pattern.compile("[0-9][0-9]");
/**
* 游戏入口
*/
public void startGame() {
// 实例化 三个飞机初始模型
airmodel1 = new AircraftModel();
airmodel2 = new AircraftModel();
airmodel3 = new AircraftModel();
// 获取飞机随机方向,与模型方位,输出棋盘坐标
do {
checkerboardLayout(airmodel1);
checkerboardLayout(airmodel2);
checkerboardLayout(airmodel3);
} while (!aircraftModelToCheckerBoard(airmodel1, airmodel2, airmodel3));
// 画出棋盘
// printCheckerBoard();
int n = 1;
while (true) {
// 先画出坐标
printCheckerBoardGuess();
// 输入猜想的坐标
String coordinate = "";
while (!pattern.matcher(coordinate).matches()) {
System.out.print("请输入一个 00~99 的位置坐标(" + n + "):");
Scanner input= new Scanner(System.in);
coordinate = input.next();
}
n++;
// 写入猜想坐标
if (writeGuessPosition(coordinate)) {
System.out.flush();
if (KILL_NUM == 3) {
break;
}
}
}
// 画出棋盘
printCheckerBoardGuess();
System.out.println("游戏结束~ 共猜想 " + n + " 次!");
printCheckerBoard();
}
/**
* 随机获取一个模型左下角坐标,然后根据坐标生成一个方向随机的模型,然后输出到棋盘
* @param airmodel 飞机模型
*/
public void checkerboardLayout(AircraftModel airmodel) {
do {
// 棋盘内 随机三个位置 作为飞机模型左下角坐标
int[] coordinate = getRandomList();
// 获取飞机随机方向,结合模型方位,输出棋盘坐标
airmodel.updateLocation(coordinate, airmodel.getRandomLocation());
} while (!boundaryJudgment(airmodel.position));
// 打印坐标信息
// printList(airmodel);
}
/**
* 把全部模型位置写入棋盘,如果位置有重叠,则返回false,反之返回true并写入棋盘
* @param airmodels 模型类表
* @return 无重叠,返回true;有重叠,返回false
*/
public boolean aircraftModelToCheckerBoard(AircraftModel... airmodels) {
int[][] checkerboard = new int[SIZE][SIZE];
for (AircraftModel airmodel : airmodels) {
for (int[] i : airmodel.position) {
if (checkerboard[i[0]][i[1]] == 0) {
checkerboard[i[0]][i[1]] = 1;
} else {
return false;
}
}
checkerboard[airmodel.getHead()[0]][airmodel.getHead()[1]] = 2;
}
CHECKERBOARD = checkerboard;
return true;
}
/**
* 判断输入坐标是否超出索引
* @param data 方位坐标
* @return 超出索引,返回false;反之,返回true
*/
public boolean boundaryJudgment(int[][] data) {
for (int[] i : data) {
try {
int j = CHECKERBOARD[i[0]][i[1]];
} catch (ArrayIndexOutOfBoundsException e) {
return false;
}
}
return true;
}
/**
* 输入坐标命中情况,未命中标记’1‘;命中非头部标记’2‘;命中头部标记’3‘
* @param coordinate 坐标
* @return 坐标重复 或者 异常,返回false;反之,返回true
*/
public boolean writeGuessPosition(String coordinate) {
int y = (int) coordinate.charAt(0) - (int) ('0');
int x = (int) coordinate.charAt(1) - (int) ('0');
try {
if (CHECKERBOARD_GUESS[x][y] != 0) {
System.out.println("重复坐标!请重新输出!");
return false;
}
switch (CHECKERBOARD[x][y]) {
case 0:
CHECKERBOARD_GUESS[x][y] = 1;
// System.out.println("MISS!");
break;
case 1:
CHECKERBOARD_GUESS[x][y] = 2;
// System.out.println("HIT!");
break;
case 2:
CHECKERBOARD_GUESS[x][y] = 3;
KILL_NUM++;
// System.out.println("KILL!");
break;
}
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("坐标异常!请重新输出!");
return false;
}
return true;
}
/**
* 随机获取两个 0~9 的整数,组成数组输出
* @return 两个整数的数组
*/
public int[] getRandomList() {
int[] nums = new int[2];
nums[0] = (int) (Math.random() * 10);
nums[1] = (int) (Math.random() * 10);
return nums;
}
/**
* 棋盘布局图输出
*/
public void printCheckerBoard() {
System.out.println(DRAWCHESSBOARD_1);
for (int i = CHECKERBOARD.length - 1; i >= 0; i--) {
StringBuilder printText = new StringBuilder(i + " *");
for (int j = 0; j < CHECKERBOARD[i].length; j++) {
switch (CHECKERBOARD[i][j]) {
case 0:
printText.append(" |");
break;
case 1:
printText.append(" ● |");
break;
case 2:
printText.append(" ✪ |");
break;
}
}
System.out.println(printText);
System.out.println(DRAWCHESSBOARD_1);
}
System.out.println(DRAWCHESSBOARD_2);
}
/**
* 猜测结果图输出
*/
public void printCheckerBoardGuess() {
System.out.println(DRAWCHESSBOARD_1);
for (int i = CHECKERBOARD_GUESS.length - 1; i >= 0; i--) {
StringBuilder printText = new StringBuilder(i + " *");
for (int j = 0; j < CHECKERBOARD_GUESS[i].length; j++) {
switch (CHECKERBOARD_GUESS[i][j]) {
case 0:
printText.append(" |");
break;
case 1:
printText.append(" △ |");
break;
case 2:
printText.append(" ● |");
break;
case 3:
printText.append(" ✪ |");
break;
}
}
System.out.println(printText);
System.out.println(DRAWCHESSBOARD_1);
}
System.out.println(DRAWCHESSBOARD_2);
}
}