如何创建 Battleship 战舰游戏算法
How to create a Battleship Warship game algorithm
我在随机化和将 2x2 飞船添加到游戏板时遇到问题。我需要它看起来像下面这样:
目前我似乎只能得到一艘 1x1 的船并且不太理解添加 2x2 并随机化它们以便它们全部连接的逻辑。
另外,当用户在主菜单中输入“2”时,我需要显示解决方案,即船只所在的位置。我也可以使用一些帮助。
尚未完成,但请在判断我的代码时提出批评意见,一切都会有所帮助!
提前致谢。
import java.util.Scanner;
public class Battleship
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int [][] board = new int [5][5];
int [][] ship = new int [4][2];
int [] shot = new int[2];
boolean done = false;
resetboard(board);
while(!done)
{
displayBoard(board);
displayMenu();
for(int ships=0 ; ships < 4 ; ships++)
{
ship[ships][0]=(int) Math.random() * 5 + 1;
ship[ships][1]=(int) Math.random() * 5 + 1;
}
int choice = getMenuInput(input);
if(choice == 1)
{
getRow(shot);
getColumn(shot);
if(fireShot(shot,ship) == true)
{
board[shot[0]][shot[1]]= 1;
}
else
{
board[shot[0]][shot[1]]= 0;
}
}
else if(choice == 2)
{
for (int x = 0; x < 5; x++)
{
for(int y = 0; y < 5; y++)
{
for(int z = 0; z < 3; z++)
{
if(board[x][y] == ship[z][0] && board[x][y] == ship[z][1] )
{
board[ship[z][0]][ship[z][1]]= 1;
}
}
}
}
displayBoard(board);
}
else if (choice == 3)
{
done = true;
System.out.println("Thanks For Playing");
}
}
}
public static void displayBoard(int [][] board)
{
System.out.println(" A B C D E");
for(int r =0; r < 5; r++)
{
System.out.print((r + 1) + "");
for(int c = 0; c < 5; c++)
{
if(board[r][c] == -1)
{
System.out.print(" -");
}
else if(board[r][c] == 0)
{
System.out.print(" X");
}
else if(board[r][c] == 1)
{
System.out.print(" *");
}
}
System.out.println("");
}
}
public static void resetboard(int[][] a)
{
for(int row=0 ; row < 5 ; row++ )
{
for(int column=0 ; column < 5 ; column++ )
{
a[row][column]=-1;
}
}
}
public static void displayMenu()
{
System.out.println("\nMenu:");
System.out.println("1. Fire Shot");
System.out.println("2. Show Solution");
System.out.println("3. Quit");
}
public static int getMenuInput(Scanner input)
{
int in = 0;
if(input.hasNextInt())
{
in = input.nextInt();
if(in>0 && in<4)
{
in = in;
}
else
{
System.out.println("Invalid Entry, Please Try Again.\n");
}
}
else
{
System.out.println("Invalid Entry, Please Try Again.\n");
input.nextInt();
}
return in;
}
public static void getRow(int [] shot)
{
Scanner input = new Scanner(System.in);
System.out.println("Enter a Row Number: ");
shot[0] = shotValid(input);
shot[0]--;
}
public static void getColumn(int [] shot)
{
Scanner input = new Scanner(System.in);
int numb = 0;
System.out.println("Enter a Column Letter: ");
String choice = input.next();
if (choice.equals("A"))
{
numb = 0;
}
else if(choice.equals("B"))
{
numb = 1;
}
else if( choice.equals("C"))
{
numb = 2;
}
else if(choice.equals("D"))
{
numb = 3;
}
else if(choice.equals("E"))
{
numb = 4;
}
else
{
System.out.println("2Invalid Entry, Please Try Again.\n");
input.nextLine();
}
shot[1] = numb;
}
public static boolean fireShot(int [] shot, int [][]ship)
{
boolean result = false;
for(int shipHit=0 ; shipHit<ship.length ; shipHit++)
{
if( shot[0]==ship[shipHit][0] && shot[1]==ship[shipHit][1])
{
result = true;
}else
{
result = false;
}
}
return result;
}
public static int shotValid(Scanner quantity)
{
int shot = 0;
boolean done = false;
while(!done)
{
if(quantity.hasNextInt())
{
shot = quantity.nextInt();
if(shot>0 && shot<6)
{
shot = shot;
done = true;
}
else
{
System.out.println("1Invalid Entry, Please Try Again.\n");
}
}
else
{
System.out.println("2Invalid Entry, Please Try Again.\n");
quantity.next();
}
}
return shot;
}
}
您想在棋盘上放置一艘 2×2 大小的船,然后执行以下操作:
for(int ships=0 ; ships < 4 ; ships++)
{
ship[ships][0]=(int) Math.random() * 5 + 1;
ship[ships][1]=(int) Math.random() * 5 + 1;
}
这里有几个错误:
- 随机变量永远为1,因为
(int)
转换只影响Math.random()
的结果,它是一个0到1之间的伪随机浮点数。转换为 int
会将其截断为 0。使用 (int) (Math.Random() * 5)
,这将产生一个从 0 到 4 的随机数。
- 您不应该加 1。在内部,您的游戏使用 Java 使用的零基索引,这很好。 ()这些在外部被称为第 1 到 5 行和 A 到 E 列,但您在
getRow
和 getColumn
函数中处理了这些。)
- 你最多放置四艘大小为 1×1 的独立飞船。 (这是最多四艘,因为你最终可能会在一个已经有人居住的地方得到一艘船。)
要放置单个2×2船,只需随机确定左上角并使其他船坐标依赖于此:
int x = (Math.random() * 4);
int y = (Math.random() * 4);
ship[0][0] = x;
ship[0][1] = y;
ship[1][0] = x + 1;
ship[1][1] = y;
ship[2][0] = x;
ship[2][1] = y + 1;
ship[3][0] = x + 1;
ship[3][1] = y + 1;
您现在有两个独立的数据结构:棋盘(最初全是负数)和船舶列表。您的显示例程表明您需要为板上的一个单元格提供三个不同的值:-1 是水;-1 是水; 1 是船上没有武装的部分,0 是开过枪的地方。
但您从未设置这些值。你在显示之前设置了船的位置,但你应该直接设置它们。你还应该设置射击的位置,这样你就不会在同一个单元格上开火。
您需要两种显示棋盘的模式:游戏中模式,未受伤的船只显示为水,解决方案模式,显示一切。您可以通过将标志传递给例程来做到这一点。
现在如果你仔细想想,你并不真的需要 ship
数组。只需使用板中的信息:
int x = (Math.random() * 4);
int y = (Math.random() * 4);
board[x][y] = 1;
board[x + 1][y] = 1;
board[x][y + 1] = 1;
board[x + 1][y + 1] = 1;
记录船只的数量,最初是 4。当你在水中开火时,将单元格标记为 0。当你向船只开火时,将单元格标记为 0 并减少船只的数量。如果船只数量为零,则玩家获胜。否则重新显示boatrd再拍
我在随机化和将 2x2 飞船添加到游戏板时遇到问题。我需要它看起来像下面这样:
目前我似乎只能得到一艘 1x1 的船并且不太理解添加 2x2 并随机化它们以便它们全部连接的逻辑。
另外,当用户在主菜单中输入“2”时,我需要显示解决方案,即船只所在的位置。我也可以使用一些帮助。
尚未完成,但请在判断我的代码时提出批评意见,一切都会有所帮助!
提前致谢。
import java.util.Scanner;
public class Battleship
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int [][] board = new int [5][5];
int [][] ship = new int [4][2];
int [] shot = new int[2];
boolean done = false;
resetboard(board);
while(!done)
{
displayBoard(board);
displayMenu();
for(int ships=0 ; ships < 4 ; ships++)
{
ship[ships][0]=(int) Math.random() * 5 + 1;
ship[ships][1]=(int) Math.random() * 5 + 1;
}
int choice = getMenuInput(input);
if(choice == 1)
{
getRow(shot);
getColumn(shot);
if(fireShot(shot,ship) == true)
{
board[shot[0]][shot[1]]= 1;
}
else
{
board[shot[0]][shot[1]]= 0;
}
}
else if(choice == 2)
{
for (int x = 0; x < 5; x++)
{
for(int y = 0; y < 5; y++)
{
for(int z = 0; z < 3; z++)
{
if(board[x][y] == ship[z][0] && board[x][y] == ship[z][1] )
{
board[ship[z][0]][ship[z][1]]= 1;
}
}
}
}
displayBoard(board);
}
else if (choice == 3)
{
done = true;
System.out.println("Thanks For Playing");
}
}
}
public static void displayBoard(int [][] board)
{
System.out.println(" A B C D E");
for(int r =0; r < 5; r++)
{
System.out.print((r + 1) + "");
for(int c = 0; c < 5; c++)
{
if(board[r][c] == -1)
{
System.out.print(" -");
}
else if(board[r][c] == 0)
{
System.out.print(" X");
}
else if(board[r][c] == 1)
{
System.out.print(" *");
}
}
System.out.println("");
}
}
public static void resetboard(int[][] a)
{
for(int row=0 ; row < 5 ; row++ )
{
for(int column=0 ; column < 5 ; column++ )
{
a[row][column]=-1;
}
}
}
public static void displayMenu()
{
System.out.println("\nMenu:");
System.out.println("1. Fire Shot");
System.out.println("2. Show Solution");
System.out.println("3. Quit");
}
public static int getMenuInput(Scanner input)
{
int in = 0;
if(input.hasNextInt())
{
in = input.nextInt();
if(in>0 && in<4)
{
in = in;
}
else
{
System.out.println("Invalid Entry, Please Try Again.\n");
}
}
else
{
System.out.println("Invalid Entry, Please Try Again.\n");
input.nextInt();
}
return in;
}
public static void getRow(int [] shot)
{
Scanner input = new Scanner(System.in);
System.out.println("Enter a Row Number: ");
shot[0] = shotValid(input);
shot[0]--;
}
public static void getColumn(int [] shot)
{
Scanner input = new Scanner(System.in);
int numb = 0;
System.out.println("Enter a Column Letter: ");
String choice = input.next();
if (choice.equals("A"))
{
numb = 0;
}
else if(choice.equals("B"))
{
numb = 1;
}
else if( choice.equals("C"))
{
numb = 2;
}
else if(choice.equals("D"))
{
numb = 3;
}
else if(choice.equals("E"))
{
numb = 4;
}
else
{
System.out.println("2Invalid Entry, Please Try Again.\n");
input.nextLine();
}
shot[1] = numb;
}
public static boolean fireShot(int [] shot, int [][]ship)
{
boolean result = false;
for(int shipHit=0 ; shipHit<ship.length ; shipHit++)
{
if( shot[0]==ship[shipHit][0] && shot[1]==ship[shipHit][1])
{
result = true;
}else
{
result = false;
}
}
return result;
}
public static int shotValid(Scanner quantity)
{
int shot = 0;
boolean done = false;
while(!done)
{
if(quantity.hasNextInt())
{
shot = quantity.nextInt();
if(shot>0 && shot<6)
{
shot = shot;
done = true;
}
else
{
System.out.println("1Invalid Entry, Please Try Again.\n");
}
}
else
{
System.out.println("2Invalid Entry, Please Try Again.\n");
quantity.next();
}
}
return shot;
}
}
您想在棋盘上放置一艘 2×2 大小的船,然后执行以下操作:
for(int ships=0 ; ships < 4 ; ships++)
{
ship[ships][0]=(int) Math.random() * 5 + 1;
ship[ships][1]=(int) Math.random() * 5 + 1;
}
这里有几个错误:
- 随机变量永远为1,因为
(int)
转换只影响Math.random()
的结果,它是一个0到1之间的伪随机浮点数。转换为int
会将其截断为 0。使用(int) (Math.Random() * 5)
,这将产生一个从 0 到 4 的随机数。 - 您不应该加 1。在内部,您的游戏使用 Java 使用的零基索引,这很好。 ()这些在外部被称为第 1 到 5 行和 A 到 E 列,但您在
getRow
和getColumn
函数中处理了这些。) - 你最多放置四艘大小为 1×1 的独立飞船。 (这是最多四艘,因为你最终可能会在一个已经有人居住的地方得到一艘船。)
要放置单个2×2船,只需随机确定左上角并使其他船坐标依赖于此:
int x = (Math.random() * 4);
int y = (Math.random() * 4);
ship[0][0] = x;
ship[0][1] = y;
ship[1][0] = x + 1;
ship[1][1] = y;
ship[2][0] = x;
ship[2][1] = y + 1;
ship[3][0] = x + 1;
ship[3][1] = y + 1;
您现在有两个独立的数据结构:棋盘(最初全是负数)和船舶列表。您的显示例程表明您需要为板上的一个单元格提供三个不同的值:-1 是水;-1 是水; 1 是船上没有武装的部分,0 是开过枪的地方。
但您从未设置这些值。你在显示之前设置了船的位置,但你应该直接设置它们。你还应该设置射击的位置,这样你就不会在同一个单元格上开火。
您需要两种显示棋盘的模式:游戏中模式,未受伤的船只显示为水,解决方案模式,显示一切。您可以通过将标志传递给例程来做到这一点。
现在如果你仔细想想,你并不真的需要 ship
数组。只需使用板中的信息:
int x = (Math.random() * 4);
int y = (Math.random() * 4);
board[x][y] = 1;
board[x + 1][y] = 1;
board[x][y + 1] = 1;
board[x + 1][y + 1] = 1;
记录船只的数量,最初是 4。当你在水中开火时,将单元格标记为 0。当你向船只开火时,将单元格标记为 0 并减少船只的数量。如果船只数量为零,则玩家获胜。否则重新显示boatrd再拍