英文:
Battleship game board in Java
问题
我编写了战舰游戏的代码。有两名玩家,人类玩家和计算机玩家。他们都有独立的游戏板。一开始,我会自动将战舰随机放置在两个游戏板上,然后我会获取坐标并在彼此的游戏板上放置战舰。如果坐标处击中了对方的战舰,我会在屏幕上显示一条消息。如果击沉了战舰,屏幕上会显示字符"s",如果击中了战舰,只会显示"*",如果不能击中,则显示"x"。在轮到人类玩家时,我如何修改计算机玩家的游戏板?
public static void main(String[] args) {
System.out.println("Welcome to Battleship game");
System.out.println("\nComputer: ");
deployComputerShips();
System.out.println("\n");
System.out.println("\nHuman: ");
deployPlayerShips();
do {
Battle();
}
while(players.playerShips != 0 && players.computerShips != 0);
gameOver();
}
public static void playerTurn(){
Scanner scn = new Scanner(System.in);
System.out.println("\nHuman's turn: ");
int x = -1, y = -1;
do {
Scanner input = new Scanner(System.in);
System.out.print("Enter row number: ");
x = scn.nextInt();
System.out.print("Enter column number: ");
y = scn.nextInt();
if ((x >= 0 && x < numRows) && (y >= 0 && y < numCols)){
if (grid[x][y].equals("o")){
System.out.println("You sunk the ship!");
grid[x][y] = "s";
--players.computerShips;
}
else if (grid[x][y].equals(".")) {
System.out.println("You missed");
grid[x][y] = "x";
}
}
else if ((x < 0 || x >= numRows) || (y < 0 || y >= numCols))
System.out.println("You can't place ships outside the " + numRows + " by " + numCols + " grid");
}
while((x < 0 || x >= numRows) || (y < 0 || y >= numCols));
}
public static void computerTurn(){
System.out.println("\nComputer's turn: ");
int x = -1, y = -1;
do {
x = (int)(Math.random()*10);
y = (int)(Math.random()*10);
System.out.println("Enter row number: "+x);
System.out.println("Enter column number: "+y);
if ((x >= 0 && x < numRows) && (y >= 0 && y < numCols)){
if (grid[x][y].equals("o")){
System.out.println("The Computer sunk one of your ships!");
grid[x][y] = "s";
--players.playerShips;
++players.computerShips;
}
else if (grid[x][y].equals(".")) {
System.out.println("Computer missed");
grid[x][y] = "x";
if(missedGuesses[x][y] != 1)
missedGuesses[x][y] = 1;
}
}
}
while((x < 0 || x >= numRows) || (y < 0 || y >= numCols));
}
以上代码是关于游戏逻辑的关键部分,涵盖了人类玩家和计算机玩家的轮次。在playerTurn
函数中,玩家输入坐标,并根据情况更新游戏板和战舰数量。在computerTurn
函数中,计算机随机生成坐标并进行类似的操作。
英文:
I write the code of the warships game. There are two players, human and computer players. Both of them have separate boards. In the beginning, I automatically place the ships on both boards randomly, then I take the coordinates and put the ships on each other's boards.If the place in the coordinate hits the other player's ship, I will send a message saying this to the screen. The character "s" is shown on the screen if it sinks the ship, only with "*" if it hits and "x" if it cannot hit. How can I make changes to the computer player's board after receiving coordinates when it's time for the human player?
public static int numRows = 10;
public static int numCols = 10;
public static int playerShips;
public static int computerShips;
public static String[][] grid = new String[numRows][numCols];
public static int[][] missedGuesses = new int[numRows][numCols];
public static void main(String[] args) {
System.out.println("Welcome to Amiral Batti game");
System.out.println("\nComputer: ");
deployComputerShips();
System.out.println("\n");
System.out.println("\nHuman: ");
deployPlayerShips();
do {
Battle();
}
while(players.playerShips != 0 && players.computerShips != 0);
gameOver();
}
public static int FIELD_SIZE = 10;
public static void deployPlayerShips() {
Random random = new Random();
int[][] field = new int[FIELD_SIZE][FIELD_SIZE];
for (int i = 5; i > 0; i--) {
int x = random.nextInt(field.length);
int y = random.nextInt(field.length);
boolean vertical = random.nextBoolean();
if (vertical) {
if (y + i > FIELD_SIZE) {
y -= i;
}
} else if (x + i > FIELD_SIZE) {
x -= i;
}
boolean isFree = true;
if (vertical) {
for (int m = y; m < y + i; m++) {
if (field[m][x] != 0) {
isFree = false;
break;
}
}
} else {
for (int n = x; n < x + i; n++) {
if (field[y][n] != 0) {
isFree = false;
break;
}
}
}
if (!isFree) {
i++;
continue;
}
if (vertical) {
for (int m = Math.max(0, x - 1); m < Math.min(FIELD_SIZE, x + 2); m++) {
for (int n = Math.max(0, y - 1); n < Math.min(FIELD_SIZE, y + i + 1); n++) {
field[n][m] = 9;
}
}
} else {
for (int m = Math.max(0, y - 1); m < Math.min(FIELD_SIZE, y + 2); m++) {
for (int n = Math.max(0, x - 1); n < Math.min(FIELD_SIZE, x + i + 1); n++) {
field[m][n] = 9;
}
}
}
for (int j = 0; j < i; j++) {
field[y][x] = i;
if (vertical) {
y++;
} else {
x++;
}
}
}
System.out.print(" ");
System.out.println("0 1 2 3 4 5 6 7 8 9");
char[][] map = new char[FIELD_SIZE][FIELD_SIZE];
for (int i = 0; i < FIELD_SIZE; i++) {
for (int j = 0; j < FIELD_SIZE; j++) {
map[i][j] = field[i][j] == 0 || field[i][j] == 9 ? '.' : 'o';
}
}
Arrays.stream(map)
.forEach(m -> System.out.println(Arrays.toString(m).replace(",", "")));
}
public static void deployComputerShips() {
Random random = new Random();
int[][] field = new int[FIELD_SIZE][FIELD_SIZE];
for (int i = 5; i > 0; i--) {
int x = random.nextInt(field.length);
int y = random.nextInt(field.length);
boolean vertical = random.nextBoolean();
if (vertical) {
if (y + i > FIELD_SIZE) {
y -= i;
}
} else if (x + i > FIELD_SIZE) {
x -= i;
}
boolean isFree = true;
if (vertical) {
for (int m = y; m < y + i; m++) {
if (field[m][x] != 0) {
isFree = false;
break;
}
}
} else {
for (int n = x; n < x + i; n++) {
if (field[y][n] != 0) {
isFree = false;
break;
}
}
}
if (!isFree) {
i++;
continue;
}
if (vertical) {
for (int m = Math.max(0, x - 1); m < Math.min(FIELD_SIZE, x + 2); m++) {
for (int n = Math.max(0, y - 1); n < Math.min(FIELD_SIZE, y + i + 1); n++) {
field[n][m] = 9;
}
}
} else {
for (int m = Math.max(0, y - 1); m < Math.min(FIELD_SIZE, y + 2); m++) {
for (int n = Math.max(0, x - 1); n < Math.min(FIELD_SIZE, x + i + 1); n++) {
field[m][n] = 9;
}
}
}
for (int j = 0; j < i; j++) {
field[y][x] = i;
if (vertical) {
y++;
} else {
x++;
}
}
}
System.out.print(" ");
System.out.println("0 1 2 3 4 5 6 7 8 9");
char[][] map = new char[FIELD_SIZE][FIELD_SIZE];
for (int i = 0; i < FIELD_SIZE; i++) {
for (int j = 0; j < FIELD_SIZE; j++) {
map[i][j] = field[i][j] == 0 || field[i][j] == 9 ? '.' : 'o';
}
}
Arrays.stream(map)
.forEach(m -> System.out.println(Arrays.toString(m).replace(",", "")));
}
public static void Battle(){
playerTurn();
computerTurn();
printBoard();
System.out.println();
System.out.println("Your ships: " + players.playerShips + " | Computer ships: " + players.computerShips);
System.out.println();
}
public static void playerTurn(){
Scanner scn = new Scanner(System.in);
System.out.println("\nHuman's turn: ");
int x = -1, y = -1;
do {
Scanner input = new Scanner(System.in);
System.out.print("Enter row number: ");
x = scn.nextInt();
System.out.print("Enter column number: ");
y = scn.nextInt();
if ((x >= 0 && x < numRows) && (y >= 0 && y < numCols)){
if (grid[x][y].equals("o")){
System.out.println("You sunk the ship!");
grid[x][y] = "s";
--players.computerShips;
}
else if (grid[x][y].equals(".")) {
System.out.println("You missed");
grid[x][y] = "x";
}
}
else if ((x < 0 || x >= numRows) || (y < 0 || y >= numCols))
System.out.println("You can't place ships outside the " + numRows + " by " + numCols + " grid");
}
while((x < 0 || x >= numRows) || (y < 0 || y >= numCols));
}
public static void computerTurn(){
System.out.println("\nComputer's turn: ");
int x = -1, y = -1;
do {
x = (int)(Math.random()*10);
y = (int)(Math.random()*10);
System.out.println("Enter row number: "+x);
System.out.println("Enter column number: "+y);
if ((x >= 0 && x < numRows) && (y >= 0 && y < numCols)){
if (grid[x][y].equals("o")){
System.out.println("The Computer sunk one of your ships!");
grid[x][y] = "s";
--players.playerShips;
++players.computerShips;
}
else if (grid[x][y].equals(".")) {
System.out.println("Computer missed");
grid[x][y] = "x";
if(missedGuesses[x][y] != 1)
missedGuesses[x][y] = 1;
}
}
}
while((x < 0 || x >= numRows) || (y < 0 || y >= numCols));
}
public static void gameOver(){
System.out.println("Your ships: " + players.playerShips + " | Computer ships: " + players.computerShips);
if(players.playerShips > 0 && players.computerShips <= 0)
System.out.println("You won the battle! ");
else
System.out.println("You lost the battle! ");
System.out.println();
}
public static void printBoard(){
System.out.print(" ");
System.out.println("0123456789");
for(int x = 0; x < grid.length; x++) {
System.out.print(x);
for (int y = 0; y < grid[x].length; y++){
System.out.print(grid[x][y]);
}
System.out.println();
}
System.out.println();
}
答案1
得分: 0
以下是翻译好的部分:
package sandbox;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
// 注意:这是基于问题中发布的原始源代码的低质量代码。不是完全功能的,存在许多问题。但它回答了原问题。
public class Warships {
private static final int numRows = 10;
private static final int numCols = 10;
private static final int NB_SHIPS = 5;
private static int playerShips = NB_SHIPS;
private static int computerShips = NB_SHIPS;
private static final int[][] missedGuesses = new int[numRows][numCols];
private static final Random random = new Random(System.currentTimeMillis());
public static final int FIELD_SIZE = 10;
private static final int[][] playerField = new int[FIELD_SIZE][FIELD_SIZE];
private static final int[][] computerField = new int[FIELD_SIZE][FIELD_SIZE];
public static void main(String[] args) {
System.out.println("欢迎来到Amiral Batti游戏");
System.out.println("\n电脑: ");
deployPlayersShips(computerField);
System.out.println("\n");
System.out.println("\n玩家: ");
deployPlayersShips(playerField);
Scanner scn = new Scanner(System.in);
do {
battle(scn);
} while (playerShips != 0 && computerShips != 0);
gameOver();
}
public static void deployPlayersShips(int[][] field) {
for (int i = NB_SHIPS; i > 0; i--) {
int x = random.nextInt(field.length);
int y = random.nextInt(field.length);
boolean vertical = random.nextBoolean();
(...)
}
printBoard2(field);
}
public static void battle(Scanner scn) {
playerTurn(scn);
computerTurn();
System.out.println("\n电脑: ");
printBoard2(computerField);
System.out.println("\n玩家: ");
printBoard2(playerField);
System.out.println();
System.out.println("你的战舰: " + playerShips + " | 电脑的战舰: " + computerShips);
System.out.println();
}
public static void playerTurn(Scanner scn) {
System.out.println("\n玩家的回合: ");
int x = -1, y = -1;
// 主要问题在这里 - 在无效输入上添加正确的循环
do {
System.out.print("输入行号: ");
x = scn.nextInt();
System.out.print("输入列号: ");
y = scn.nextInt();
} while ((x < 0 || x >= numRows) || (y < 0 || y >= numCols));
// 主要问题在这里 - 删除了在更新字段上的无效循环
if (computerField[x][y] != 0 && computerField[x][y] != 9) {
System.out.println("你击沉了敌舰!");
computerField[x][y] = 1;
computerShips--;
} else if (".".equals(computerField[x][y])) {
System.out.println("你没有命中");
computerField[x][y] = 2;
}
}
public static void computerTurn() {
System.out.println("\n电脑的回合:");
int x = random.nextInt(FIELD_SIZE);
int y = random.nextInt(FIELD_SIZE);
System.out.println("输入行号: " + x);
System.out.println("输入列号: " + y);
// 主要问题在这里 - 删除了输入/随机上的无效循环
if ((x >= 0 && x < numRows) && (y >= 0 && y < numCols)) {
if (playerField[x][y] != 0 && playerField[x][y] != 9) {
System.out.println("电脑击沉了你的一艘舰船!");
playerField[x][y] = 1;
playerShips--;
} else if (".".equals(playerField[x][y])) {
System.out.println("电脑没有命中");
playerField[x][y] = 2;
if (missedGuesses[x][y] != 1) {
missedGuesses[x][y] = 1;
}
}
}
}
public static void gameOver() {
System.out.println("你的战舰: " + playerShips + " | 电脑的战舰: " + computerShips);
if (playerShips > 0 && computerShips <= 0) {
System.out.println("你赢得了战斗!");
} else {
System.out.println("你输掉了战斗!");
}
System.out.println();
}
public static void printBoard2(int[][] field) {
System.out.print(" ");
System.out.println("0 1 2 3 4 5 6 7 8 9");
char[][] map = new char[FIELD_SIZE][FIELD_SIZE];
for (int i = 0; i < FIELD_SIZE; i++) {
for (int j = 0; j < FIELD_SIZE; j++) {
switch (field[i][j]) {
case 0:
case 9:
map[i][j] = '.';
break;
case 1:
map[i][j] = 's';
break;
case 2:
map[i][j] = 'x';
break;
default:
map[i][j] = 'o';
break;
}
}
}
Arrays.stream(map)
.forEach(m -> System.out.println(Arrays.toString(m).replace(",", "")));
}
}
希望这有所帮助。如有任何其他问题,请随时提问。
英文:
Okay here is a more correct version. I could do more but ... then half of the code would be rewritten and I don't see the point of doing that (doesn't help you). So I insist that its far from perfect but at least it resolves your issue. I made the following corrections:
- The battle() method has a corrected game logic
- I removed the 'grid' variable. I don't understand why it exists. And instead externalized the 'field' variable -> one for each player.
- I merged your two deployPlayerShips() deployComputerShips() methods into one: deployPlayersShips(...). But I still don't understand most of its logic. And with the given code below there are issues at display and field init. But these errors certainly are already present in your original code.
- I have rewritten printBoard() to make use of 'field' variables. But it will still need fixes.
- I fixed partially the playerTurn() and computerTurn() methods as they had badly constructed loops. Turns could never really "turn". The biggest (blocking) problem was in these methods I think (even though other errors remain).
- I've added a global Random() and made Scanner instantiated only once.
package sandbox;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
// ATTENTION: low-quality code based on original source posted in question. Not fully functional and has many issues. But it answers the original question.
public class Warships {
private static final int numRows = 10;
private static final int numCols = 10;
private static final int NB_SHIPS = 5;
private static int playerShips = NB_SHIPS;
private static int computerShips = NB_SHIPS;
private static final int[][] missedGuesses = new int[numRows][numCols];
private static final Random random = new Random(System.currentTimeMillis());
public static final int FIELD_SIZE = 10;
private static final int[][] playerField = new int[FIELD_SIZE][FIELD_SIZE];
private static final int[][] computerField = new int[FIELD_SIZE][FIELD_SIZE];
public static void main(String[] args) {
System.out.println("Welcome to Amiral Batti game");
System.out.println("\nComputer: ");
deployPlayersShips(computerField);
System.out.println("\n");
System.out.println("\nHuman: ");
deployPlayersShips(playerField);
Scanner scn = new Scanner(System.in);
do {
battle(scn);
} while (playerShips != 0 && computerShips != 0);
gameOver();
}
public static void deployPlayersShips(int[][] field) {
for (int i = NB_SHIPS; i > 0; i--) {
int x = random.nextInt(field.length);
int y = random.nextInt(field.length);
boolean vertical = random.nextBoolean();
(...)
}
printBoard2(field);
}
public static void battle(Scanner scn) {
playerTurn(scn);
computerTurn();
System.out.println("\nComputer: ");
printBoard2(computerField);
System.out.println("\nHuman: ");
printBoard2(playerField);
System.out.println();
System.out.println("Your ships: " + playerShips + " | Computer ships: " + computerShips);
System.out.println();
}
public static void playerTurn(Scanner scn) {
System.out.println("\nHuman's turn: ");
int x = -1, y = -1;
// MAIN ISSUE WAS HERE -- Add correct loop on invalid input
do {
System.out.print("Enter row number: ");
x = scn.nextInt();
System.out.print("Enter column number: ");
y = scn.nextInt();
} while ((x < 0 || x >= numRows) || (y < 0 || y >= numCols));
// MAIN ISSUE WAS HERE -- Removed invalid loop on update field
if (computerField[x][y] != 0 && computerField[x][y] != 9) {
System.out.println("You sunk the ship!");
computerField[x][y] = 1;//"s";
computerShips--;
} else if (".".equals(computerField[x][y])) {
System.out.println("You missed");
computerField[x][y] = 2; //"x";
}
}
public static void computerTurn() {
System.out.println("\nComputer's turn: ");
int x = random.nextInt(FIELD_SIZE);
int y = random.nextInt(FIELD_SIZE);
System.out.println("Enter row number: " + x);
System.out.println("Enter column number: " + y);
// MAIN ISSUE WAS HERE -- Removed invalid loop on input/rand
if ((x >= 0 && x < numRows) && (y >= 0 && y < numCols)) {
if (playerField[x][y] != 0 && playerField[x][y] != 9) {
System.out.println("The Computer sunk one of your ships!");
playerField[x][y] = 1;//"s";
playerShips--;
} else if (".".equals(playerField[x][y])) {
System.out.println("Computer missed");
playerField[x][y] = 2; //"x";
if (missedGuesses[x][y] != 1) {
missedGuesses[x][y] = 1;
}
}
}
}
public static void gameOver() {
System.out.println("Your ships: " + playerShips + " | Computer ships: " + computerShips);
if (playerShips > 0 && computerShips <= 0) {
System.out.println("You won the battle! ");
} else {
System.out.println("You lost the battle! ");
}
System.out.println();
}
public static void printBoard2(int[][] field) {
System.out.print(" ");
System.out.println("0 1 2 3 4 5 6 7 8 9");
char[][] map = new char[FIELD_SIZE][FIELD_SIZE];
for (int i = 0; i < FIELD_SIZE; i++) {
for (int j = 0; j < FIELD_SIZE; j++) {
switch(field[i][j]) {
case 0:
case 9: map[i][j] = '.';
break;
case 1: map[i][j] = 's';
break;
case 2: map[i][j] = 'x';
break;
default: map[i][j] = 'o';
break;
}
}
}
Arrays.stream(map)
.forEach(m -> System.out.println(Arrays.toString(m).replace(",", "")));
}
}
At this point I let you do the rest. Many errors remain. Take the time to truly finish and double-check your code before requesting help again. And keep training there is room for improvements out there in terms of OOP, coding rules and best practices. Good luck.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论