I am trying to create a method/ while loop which checks to see which player moves. For now I check to see which play moves in a for loop. I am trying to make my code a bit more clear and concise. Here is the main method:
public static void main(String[] args) {
try (Scanner input = new Scanner(System.in)) {
int height = 6, width = 8, moves = height * width;
ConnectFour board = new ConnectFour(width, height);
System.out.println("Use 0-" + (width - 1) + " to choose a column.");
System.out.println(board);
for (int player = 0; moves-- > 0; player = 1 - player) { // Here is where i check to see who plays
char symbol = players[player];
board.chooseAndDrop(symbol, input);
System.out.println(board);
if (board.isWinningPlay()) {
System.out.println("Player " + symbol + " wins!");
return;
}
}
System.out.println("Game over, no winner.");
}
}
I was thinking more along the lines of:
int playerNb = 0;
while (thegamestarted)
{
if (playerNb == 0)
// Get user input
else
// Get second player input
// Process the input
// Change playerNb to 1 or 0
}
Below is the full code:
import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class ConnectFour {
private static final char[] players = new char[] { 'X', 'O' };
private final int width, height;
private final char[][] grid;
private int lastCol = -1, lastTop = -1;
public ConnectFour(int width, int height) {
this.width = width;
this.height = height;
this.grid = new char[height][];
for (int h = 0; h < height; h++) {
Arrays.fill(this.grid[h] = new char[width], '.');
}
}
public String toString() {
return IntStream.range(0, this.width)
.mapToObj(Integer::toString)
.collect(Collectors.joining()) + "\n" +
Arrays.stream(this.grid)
.map(String::new)
.collect(Collectors.joining("\n"));
}
/**
* Prompts the user for a column, repeating until a valid
* choice is made.
*/
public void chooseAndDrop(char symbol, Scanner input) {
do {
System.out.print("\nPlayer " + symbol + " turn: ");
int col = input.nextInt();
if (! (0 <= col && col < this.width)) {
System.out.println("Column must be between 0 and " +
(this.width - 1));
continue;
}
for (int h = this.height - 1; h >= 0; h--) {
if (this.grid[h][col] == '.') {
this.grid[this.lastTop=h][this.lastCol=col] = symbol;
return;
}
}
System.out.println("Column " + col + " is full.");
} while (true);
}
/**
* Detects whether the last chip played was a winning move.
*/
public boolean isWinningPlay() {
if (this.lastCol == -1) {
throw new IllegalStateException("No move has been made yet");
}
char sym = this.grid[this.lastTop][this.lastCol];
String streak = String.format("%c%c%c%c", sym, sym, sym, sym);
return contains(this.horizontal(), streak) ||
contains(this.vertical(), streak) ||
contains(this.slashDiagonal(), streak) ||
contains(this.backslashDiagonal(), streak);
}
/**
* The contents of the row containing the last played chip.
*/
private String horizontal() {
return new String(this.grid[this.lastTop]);
}
/**
* The contents of the column containing the last played chip.
*/
private String vertical() {
StringBuilder sb = new StringBuilder(this.height);
for (int h = 0; h < this.height; h++) {
sb.append(this.grid[h][this.lastCol]);
}
return sb.toString();
}
/**
* The contents of the "/" diagonal containing the last played chip
* (coordinates have a constant sum).
*/
private String slashDiagonal() {
StringBuilder sb = new StringBuilder(this.height);
for (int h = 0; h < this.height; h++) {
int w = this.lastCol + this.lastTop - h;
if (0 <= w && w < this.width) {
sb.append(this.grid[h][w]);
}
}
return sb.toString();
}
/**
* The contents of the "\" diagonal containing the last played chip
* (coordinates have a constant difference).
*/
private String backslashDiagonal() {
StringBuilder sb = new StringBuilder(this.height);
for (int h = 0; h < this.height; h++) {
int w = this.lastCol - this.lastTop + h;
if (0 <= w && w < this.width) {
sb.append(this.grid[h][w]);
}
}
return sb.toString();
}
private static boolean contains(String haystack, String needle) {
return haystack.indexOf(needle) >= 0;
}
public static void main(String[] args) {
try (Scanner input = new Scanner(System.in)) {
int height = 6, width = 8, moves = height * width;
ConnectFour board = new ConnectFour(width, height);
System.out.println("Use 0-" + (width - 1) + " to choose a column.");
System.out.println(board);
for (int player = 0; moves-- > 0; player = 1 - player) {
char symbol = players[player];
board.chooseAndDrop(symbol, input);
System.out.println(board);
if (board.isWinningPlay()) {
System.out.println("Player " + symbol + " wins!");
return;
}
}
System.out.println("Game over, no winner.");
}
}
}
Its a bit difficult to tell what you want from your code, but the absolute simplest way to keep track of what player it is, is to keep track of the turn number, and check if it is even or odd with the modulus function
This is just a brief bit of psuedocode to show you how you can tell what the turn is with simple math. You will have to adapt it to your own needs. You can see that it will only be "Player 2"'s turn on an even turn number where the turn number divided by 2 has no remainder. Just remember to increment the turn after every move.
There's no "good" answer. You're the one writing the code, you can decide whose turn it is, you just have to keep track of it.
int turn = 1;
for ( ) {
if (turn % 2 == 0) {
System.out.println("Player 2");
} else {
System.out.println("Player 1");
}
turn++;
}
Related
I am coding a simple tic-tac-toe for a high-school mini project, but I need it to be within a strict data volume (not more than 112 lines). I thought checking for each row, column and cross would be long, so is there any alternative to do so (You should see a [[[HERE]]] comment)? (Btw, I already know it looks awful) Thanks in advance!
public class TTTGame {
//OPTIONS v
public static final String draw = "DRAW"; // <- Definitions for different states
public static final String circles = "CIRCLES"; // BOT
public static final String crosses = "CROSSES"; // PLAYER
public static final String getCrosses = "X"; //<- Symbols to display
public static final String getCircles = "O";
//OPTIONS ^
//DO NOT MODIFY UNDER THIS LINE (Just kidding, do whatever u want) v
public static int[][] board = {
{0,0,0},
{0,0,0},
{0,0,0},
};
public static final int empty = 0; // Definition of the values
public static final int cross = 1;
public static final int circle = 2;
public static int turns = 0; //Just here to count turns, nothing special
public static void main(String[]args) { //Main process
board[1][1] = circle;
display();
while (true) {
PlayerTurn();
if (checkStop()||checkWinner()!=null) {display();GStop();break;}
BotTurn();
if (checkStop()||checkWinner()!=null) {display();GStop();break;}
display();
turns += 1;
}
}
private static void GStop() { //Force stop the match function
System.out.println("Winner : " + checkWinner());
System.exit(1);
}
private static boolean checkStop() { //Check if match is already full / completed (Draw)
for (int x = 0; x < 3; x++)
for (int y = 0; y < 3; y++)
if (board[x][y]==empty) return false;
return true;
}
#Nullable
private static String checkWinner() { //Check Winner
// [[[ HERE ]]] ---------------
return null;
}
private static void PlayerTurn() { //Player turn
int x; Scanner c = new Scanner(System.in);
while (true) {
x = c.nextInt();
x = x-1;
if ((x>=0)&&(x < 9)) {
if (board[x / 3][x % 3] == empty) {
board[x / 3][x % 3] = cross;
break;
} else System.out.println("Already chosen");
} else System.out.println("Invalid");
}
}
private static void BotTurn() { //Bot turn -> (Modify these to change the AI behaviour, here's a very simple one);
boolean choose = true;
for (int y = 0; y < 3 ; y++)
for (int x = 0; x < 3; x++)
if (board[y][x] == empty&&choose) {
board[y][x] = circle;
choose = false;
}
}
private static void display() { //Display the board
int nn = 1;
String a = "z";
for (int y = 0; y < 3 ; y++) {
for (int x = 0; x < 3; x++) {
if (board[y][x] == 0) a = "*";
if (board[y][x] == 1) a = getCrosses;
if (board[y][x] == 2) a = getCircles;
System.out.print(a + " ");
}
System.out.print(" "); //Indications
for (int xn = 0; xn < 3; xn++) {
System.out.print(nn);
nn+=1;
System.out.print(" ");
}
System.out.println(" ");
}
}
}
How about this idea: (neither the only nor the best nor the most performant solution... just an idea)
You can use the sum of each row, diagonal and column to determine if the either player one (all 1s) or player two (all 2s) wins. Therefore you only need to set the empty field to be higher than 6.
For example let's say your board looks like this:
7 1 1 -> 7+1+1 = 9 // no one wins
2 2 2 -> 2+2+2 = 6 // player two wins, he has 3 * 2 in a row
1 7 2 -> 1+7+2 =10 // no win here
if all three numbers where 1s (sum == 3) your player one wins.
It is "cumbersome" to implement, but as I said it is just an idea:
// first we check every column
for( int x=0; x<board[y].length; x++){
int sum = 0;
for( int y=0; y<board.length; y++){
sum += board[y][x];
}
if(sum == 3 || sum == 6){
return true;
}
}
// then every row
for( int y=0; y<board.length; y++){
int sum = 0;
for( int x=0; x<board[y].length; x++){
sum += board[y][x];
}
if(sum == 3 || sum == 6){
return true;
}
}
// and finally the diagonals (if we ever reach that part)
int sum= board[0][0] + board[1][1] + board[2][2];
if(sum == 3 || sum == 6){
return true;
}
sum= board[0][2] + board[1][1] + board[2][0];
if(sum == 3 || sum == 6){
return true;
}
you could also return 1 when the sum == 3 and the first player wins or 2 when player two wins.
I have a two-dimensional array filled with random letters. I have words to find in that array.
I have written a toString method that uses:
startX : The start X position of the String to be found
startY : The start Y position of the String to be found
endX : The end X position of the String to be found
endY : The end Y position of the String to be found
The code that I provide works horizontally and vertically but does not work for diagonals. How can I print words which are placed in the array diagonally?
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
if (startX == endX) {
if (startY < endY) {
for (int i = startY; i <= endY; i++)
sb.append(i).append("x").append(startY).append(" ");
} else {
for (int i = endY; i <= startY; i++)
sb.append(i).append("x").append(startY).append(" ");
}
}
if (startY == endY) {
if (startX < endX) {
for (int i = startX; i <= endX; i++)
sb.append(i).append("x").append(startY).append(" ");
} else
for (int i = endX; i <= startX; i++)
sb.append(i).append("x").append(startY).append(" ");
}
if (startX > endX && startY > endY) {
int i = startX;
int j = startY;
while (i >= endX)
sb.append(i--).append("x").append(j--).append(" ");
} else if (startX > endX && startY < endY) {
int i = startX;
int j = startY;
while (i >= endX)
sb.append(i--).append("x").append(j++).append(" ");
} else if (startX < endX && startY > endY) {
int i = startX;
int j = startY;
while (i >= endX)
sb.append(i++).append("x").append(j--).append(" ");
} else if (startX < endX && startY < endY) {
int i = startX;
int j = startY;
while (i >= endX)
sb.append(i++).append("x").append(j++).append(" ");
}
return sb.toString();
}
I assume that what you are looking for is a way to find a word in a letter puzzle.
In such a case, I suggest you to store the puzzle on a 2D array and the word to find in a String. Then you need to check all the positions of the array that have the same character than the begining character of the String you are looking for (in the code I provide: findWord). Once you find a match, you need to check the rest of the characters of the string (in the code I provide: checkDirections). If the rest of the characters match then you have found the string, otherwise you need to check for the other directions or for the next appearance of the first letter of the string.
Next I provide the code:
package letterPuzzle;
import java.util.Random;
public class LetterPuzzle {
private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
private static final int[] DIRECTIONS_X = new int[] { 0, 0, 1, -1, 1, 1, -1, -1 };
private static final int[] DIRECTIONS_Y = new int[] { 1, -1, 0, 0, 1, -1, 1, -1 };
private static int N;
private static char[][] puzzle;
private static void initializePuzzle() {
Random r = new Random();
puzzle = new char[N][N];
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
puzzle[i][j] = ALPHABET.charAt(r.nextInt(ALPHABET.length()));
}
}
// Add the JAVA word in a location
if (N < 6) {
System.out.println("[ERRRO] Example needs N >= 6");
System.exit(1);
}
puzzle[2][3] = 'j';
puzzle[3][3] = 'a';
puzzle[4][3] = 'v';
puzzle[5][3] = 'a';
}
private static void printPuzzle() {
System.out.println("[DEBUG] Puzzle");
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
System.out.print(puzzle[i][j] + " ");
}
System.out.println("");
}
System.out.println("[DEBUG] End Puzzle");
}
private static boolean findWord(String word) {
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
// We check all the matrix but only try to match the word if the first letter matches
if (puzzle[i][j] == word.charAt(0)) {
if (checkDirections(i, j, word)) {
return true;
}
}
}
}
return false;
}
private static boolean checkDirections(int initX, int initY, String word) {
System.out.println("Searching " + word + " from (" + initX + ", " + initY + ")");
// Checks the different directions from (initX, initY) position
for (int dirIndex = 0; dirIndex < DIRECTIONS_X.length; ++dirIndex) {
System.out.println(" - Searching direction " + dirIndex);
boolean wordMatches = true;
// Checks all the characters in an specific direction
for (int charIndex = 0; charIndex < word.length() && wordMatches; ++charIndex) {
int x = initX + DIRECTIONS_X[dirIndex] * charIndex;
int y = initY + DIRECTIONS_Y[dirIndex] * charIndex;
System.out.println(" -- Checking position (" + x + ", " + y + ")");
if (x < 0 || y < 0 || x >= N || y >= N || puzzle[x][y] != word.charAt(charIndex)) {
System.out.println(" -- Not match");
wordMatches = false;
} else {
System.out.println(" -- Partial match");
}
}
// If the word matches we stop, otherwise we check other directions
if (wordMatches) {
return true;
}
}
return false;
}
public static void main(String[] args) {
// Check args
if (args.length != 2) {
System.err.println("[ERROR] Invalid usage");
System.err.println("[ERROR] main <puzzleSize> <wordToSearch>");
}
// Get args
N = Integer.valueOf(args[0]);
String word = args[1];
// Initialize puzzle (randomly)
initializePuzzle();
printPuzzle();
// Search word
boolean isPresent = findWord(word);
if (isPresent) {
System.out.println("Word found");
} else {
System.out.println("Word NOT found");
}
}
}
Notice that:
The puzzle matrix is randomly initialized and I hardcoded the word 'java' on the 2,3 -> 5,3 positions (this is just for the example but you should initialize the puzzle from the command line or from a file).
The ALPHABET variable is used only for the random generation.
The directions are stored on two 1D arrays to make the 8 directions programatically but you can unroll for the sake of clarity.
It is probably not best efficient code in terms of performance since you will double check lots of positions if the first character of the string appears several times. However it is still a feasible and easy solution.
If :
each word of yours is in a particular row and doesn't overflows to next row and
all words are consecutive
then you can do something like this:
#Override
public String toString()
{
StringBuilder string = new StringBuilder();
for(int c = startY; c<=endY; c++) {
string.append(startX).append("x").append(c).append(", ");
}
return string.toString();
}
so im having problems polishing up my program. this program is supposed to create a 1D array with a user input. then it creates a box of 'O's like this..
N = 4
OOOO
OOOO
OOOO
OOOO
the user inputs coordinates based on the box and the 'O' is changed to an 'X'.
the program is supposed to repeat itself after the coordinates are selected while remembering the position of X and including it in the next loop.
i tried implementing a while loop but it seems that code just loops over the Array without remembering the last position of X.
how could i change the code so it does what i need it to do?
public static void makeArray(int M) {
String input = "";
boolean repeat = false;
int N = InputNumber(input);
String[] Board = new String[N];
M = (int) Math.sqrt(N);
String A = "O";
String B = "X";
System.out.println("Printing " + (M) + " x " + (M) + " board...");
System.out.println("Done.");
System.out.println();
while (!repeat) {
int X = Xvalue(M);
int Y = Yvalue(M);
int C = convertIndex(X, Y, M);
System.out.println("Marking location " + X + "," + Y + ")");
for (int i = 0; i < (Board.length); i++) {
{
Board[i] = A;
if ((i % M == 0)) {
System.out.println();
}
if (i == C) {
Board[i] = Board[i].replace(A, B);
}
if (i == C && C == -1) {
repeat = true;
}
}
System.out.print(Board[i]);
}
System.out.println();
}
}
public static int convertIndex(int x, int y, int N) {
int valX = (x - 1) * N;
int valY = y;
int targetIndex = valX + valY;
return (targetIndex - 1);
}
public static int Xvalue(int M) {
boolean repeat = false;
int X = 0;
while (!repeat) {
System.out.print("Please enter the X-coordinate: ");
String InputX = new Scanner(System.in).nextLine();
X = Integer.parseInt(InputX);
if (X > M) {
System.out.println();
System.out.println("Error, please enter a valid X Coordinate...");
repeat = false;
} else {
repeat = true;
}
}
return X;
}
public static int Yvalue(int M) {
boolean repeat = false;
int Y = 0;
while (!repeat) {
System.out.println();
System.out.print("Please enter the Y-coordinate: ");
String InputY = new Scanner(System.in).nextLine();
Y = Integer.parseInt(InputY);
if (Y > M) {
System.out.println("Error, please enter a valid Y Coordinate...");
repeat = false;
} else {
repeat = true;
}
}
return Y;
}
The trouble with you loop is that it defines every element in you your array before it prints them:
while (!repeat) {
//...
for (int i = 0; i < (Board.length); i++) {
{
Board[i] = A; //Makes each element "O"
//...
if (i == C) { //Makes only the current cooridinate "X"
Board[i] = Board[i].replace(A, B);
}
//...
}
System.out.print(Board[i]);
}
}
To fix it so that old X's are retained, you need to remove assignment Board[i] = A;. But you'll still need to initialize your board, or else you'll have null strings. So you need to add something before the loop like:
String[] Board = new String[N];
M = (int) Math.sqrt(N);
String A = "O";
String B = "X";
//initialize board
for (int i = 0; i < Board.length; i++)
Board[i] = A;
Try using a char[][] instead of a String[]. Then you can just plugin the coordinates the user inputs (e.g. board[x][y] = B). This better represents what you're showing the user as well.
This saves you from having to loop through your String[] and then finding the right character to change. Remember, Strings are immutable, so you'd have to reassign the entire string after replacing the right character. With the char[][] you simply assign 'X' to the right coordinates.
EDIT:
Since a single array is required, you should be able to do the following (instead of looping):
board[x] = board[x].substring(0, y) + A + board[x].substring(y + 1);
I'm having trouble randomizing and adding a 2x2 ship into the game board. I need it to look like the following:
currently I can only seem to get a 1x1 ship and don't quite understand the logic for adding the 2x2 and randomizing it so that they're all connected.
also when the user inputs a '2' at the main menu I need to show the solution, meaning where the ships are. Which I also could use some help on.
Not nearly finished but please be critical when it comes to judging my code, everything helps!
Thanks in advance.
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;
}
}
You want to place a single ship of size 2×2 on the board and do this:
for(int ships=0 ; ships < 4 ; ships++)
{
ship[ships][0]=(int) Math.random() * 5 + 1;
ship[ships][1]=(int) Math.random() * 5 + 1;
}
There are several errors here:
The random variables will always be 1, because the (int) conversion affects only the result of Math.random(), which is a pseudo-random floating-point number between 0 and 1 exclusively. Conversion to int truncates this to 0. Use (int) (Math.Random() * 5), which will yield a random number from 0 to 4.
You shouldn't add 1. Internally, your game uses the zero-base indices that Java uses, which is good. ()These are known to the outside as rows 1 to 5 ande columns A to E, but you take care of that in your getRow and getColumn functions.)
You place up to four independent ships of size 1×1. (This is up to four, because you might end up wit one ship in an already occupied place.)
To place a single 2×2 ship, just determine the top left corner randomply and make the other ship coordinates dependent on that:
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;
You now have two separate data structures: The board, which is all minus ones initially, and the list of ships. Your display routine suggests that you want three different values for a cell in the board: −1 is water; 1 is an unarmed part of a ship and 0 is where a shot has been fired.
But you never set these values. You set the position of the ship before displaying, but you should probably set them straight away. You should also set the locations of shots, so that you never fire at the same cell.
You need two modes for displaying the board: The in-play mode, where the unharmed ships are displayed as water and the solution mode, which shows everything as it is. You could so this by passing a flag to the routine.
Now if you think about it, you don't really need the ship array. Just use the information in the board:
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;
Keep a count of ships, initially 4. When you fire at water, mark the cell with 0. When you fire at a ship, mark the cell as 0 and decrement the count of ships. If the count of ships is zero, the player has won. Otherwise, redisplay the boatrd and shoot again.
I currently have it so it prints of a 2 by 2 grid and renames my position as P and everything else as - and it hides the chest until i step on it and ask's me if i want to open the chest then ends the game but i want it to rename the randomly generated chest to C so i can see on the grid where it is, Could someone please help me with this issue
/**
* Auto Generated Java Class.
*/
import java.util.*;
public class Adventure {
public static final int rows= 2;
public static String tile = "";
public static final int cols= 2;
public static String input = "";
public static boolean run = true;
public static String[][] map = new String[rows][cols];
public static int xpos = 0;
public static int ypos = 0;
public static Random gen = new Random();
public static final int xx = gen.nextInt(rows);
public static final int yy = gen.nextInt(cols);
public static void main(String[] args) {
for(int x = 0; x < rows; x++) {
for(int y = 0; y < cols; y++) {
map[x][y] = "you see nothing, on the fields of justice";
}
}
map[xx][yy] = "You find a chest: Open?";
while(run) {
displayMap();
System.out.println(map[xpos][ypos]);
input = userinput();
input = input.toLowerCase();
if(input.equals("w")) {
if (ypos < cols - 1) {
ypos++;
}else{
System.out.println("You're at the edge of the map");
}
}else if(input.equals("d")) {
if (xpos < rows - 1) {
xpos++;
}else{
System.out.println("You're at the edge of the map");
}
}else if(input.equals("s")) {
if (ypos > 0) {
ypos--;
}else{
System.out.println("You're at the edge of the map");
}
}else if(input.equals("a")) {
if (xpos > 0) {
xpos--;
}else{
System.out.println("You're at the edge of the map");
}
}else if(input.equals("open")) {
if(map[xpos][ypos].equals("You find a chest: Open?")){
System.out.println("You find a sword");
System.out.println("()==[:::::::::::::>");
run = false;
}else{
System.out.println("There's nothing to open");
}
}else {
System.out.println("Wrong direction, W , A, S , D");
}
}
}
public static String userinput(){
System.out.println("Which direction do you want to move: w , a ,s ,d ? ");
Scanner keyboard = new Scanner(System.in);
return keyboard.nextLine();
}
public static void displayMap() {
for (int y = cols - 1; y >= 0; y--) {
for (int x = 0; x < rows; x++) {
if (y == ypos && x == xpos) {
tile = tile + "P";
}
//Heres where i want to rename the chest to 'C' on the grid
else if (xx && yy) {
tile = tile + "C";
}
else{
tile = tile + "-";
}
}
System.out.println(tile);
tile = "";
}
}
}
Replace else if (xx && yy) with else if (y==yy && x==xx). It's an easy error to make.