My code has some logic issues with the problem mentioned above. What I'm trying to do is to print a 2D array in the console, and then, after asking for the user's input, the array will change and will replace the old one for this new one in the console.
Here is an example of what I'm trying to do. Don't pay attention to the numbers on the array, what I am asking only has to do with the elements that are printed in the console.
The console will look like this
What column do you want to shoot (A, B, C, D, E, F)
The number that is going to be shoot is ---1---
After the user gives the column, the console will look like this.
What column do you want to shoot (A, B, C, D, E, F)
The number that is going to be shoot is ---1---
A
3 3 2 1 1 3
2 2 3 1 1 3
2 3 3 1 3 3
2 2 3 3 1 3
1 3 1 2 2 3
2 2 1 1 3 2
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
What column do you want to shoot (A, B, C, D, E, F)
The number that is going to be shoot is ---2---
The code that I attached at the end does all of this, but the problem starts after the user gives the second input. After the user gives his second input (his second column) the console will look like this:
What column do you want to shoot (A, B, C, D, E, F)
The number that is going to be shoot is ---1---
A
3 3 2 1 1 3
2 2 3 1 1 3
2 3 3 1 3 3
2 2 3 3 1 3
1 3 1 2 2 3
2 2 1 1 3 2
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
What column do you want to shoot (A, B, C, D, E, F)
The number that is going to be shoot is ---2---
B
2 2 2 3 3 1
3 3 2 1 1 3
2 2 3 1 1 3
2 3 3 1 3 3
2 2 3 3 1 3
1 3 1 2 2 3
0 0 1 1 3 2
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
What column do you want to shoot (A, B, C, D, E, F)
The number that is going to be shoot is ---3---
What it's doing is that it keeps printing and printing new boards instead of "updating" the same board.
What I am trying to achieve is the following: (What I am showing is what I want the console to look like)
(User gives the first input) Console:
The number that is going to be shoot is ---2---
A
3 3 2 1 1 3
2 2 3 1 1 3
2 3 3 1 3 3
2 2 3 3 1 3
1 3 1 2 2 3
2 2 1 1 3 2
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
(User gives second input) Console:
What column do you want to shoot (A, B, C, D, E, F)
The number that is going to be shoot is ---3---
A
2 2 2 3 3 1
3 3 2 1 1 3
2 2 3 1 1 3
2 3 3 1 3 3
2 2 3 3 1 3
1 3 1 2 2 3
0 0 1 1 3 2
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
(The only 2 changes here are the number that is going to be shoot and the numbers in the array)
In a few words all I want to do is to "update" the board with the result instead of printing and printing new boards over and over again.
The code below is the code I have so far. I included a pseudo code so that you can see what each method does (The whole game structure is on the game()
method). I would prefer to not change the code for any of the methods rather than the gameOver
method since it is the one that is in "charge" of clearing the consoles and all that stuff. (If you find an answer and involves changing another method that's ok)
Again, the only thing that i'm confused about is on how to replace the existing board instead of printing new boards, not with the content of the arrays.
Here's the code
import java.util.Scanner;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Collections;
public class Project {
public static final int[][] NEIGHBOURS = // adjacent cells
{{0, 1}, // horizontal -
{1, 0}, // vertical |
{1, 1}, // diagonal \
{1, -1}}; // diagonal /
private List<Island> islands = new ArrayList<>(); // collection of Islands
private int[][] grid; // matrix
public Project(int[][] grid) {
this.grid = grid;
}
public static int[][]board = { {0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0} };
public static int[][]numberBoard = createBoard(6, /*Number of colums*/ 5, /*Number of rows*/ 3 /*Bubble types in the board (1, 2 or 3)*/);
//creates random board
public static void main( String[] args) {
game();
}
public static void game() {
String input; //the Input
int randomNumber;
int[] location;
board = combine(board, numberBoard); //Empty Board to Randomized Board
while(gameOver(board).equals("GAME CONTINUES")) {
gameOver(board); //Scans the array to see if the game is still going or not
//The code below up to "shiftRow" shouldn't really matter with the question because all it's doing is to make changes to the array
//but does not print anything to the console so I seperated them.
randomNumber = createRandomNumber(3); //creates a randomNumber
input = shoot(randomNumber); //Input
board = putNumber(board, input, randomNumber); //Places Input
location = numberLocation(board, input, randomNumber); //Gets location of the placed number
board = destroyAdjacentNumbers(board, location[0], location[1], randomNumber); //Deletes any number that is both, a neighbor and
//has the same value as the number placed
Project destroyIslands = new Project(board); //destroys the islands (Chunks of numbers that are completely surrounded by zeros)
destroyIslands.deleteIslandBoard2();
shiftRow(board); //Shifts the row down
destroyIslands.printGrid(); //prints the grid
}
if(gameOver(board).equals("CONGRATULATIONS, YOU WON THE GAME!")) {
clearConsole();
System.out.println("CONGRATULATIONS, YOU WON THE GAME!");
} else if(gameOver(board).equals("YOU LOST THE GAME!")) {
clearConsole();
System.out.println("YOU LOST THE GAME!");
}
}
public static int[][] createBoard(int cols, int rows, int numBubbleTypes) {
int[][] board = new int[rows][cols];
for( int row = 0; row < rows; row++ ) {
for( int col = 0; col < cols; col++ ) {
board[row][col] = (int)(Math.random() * (double)numBubbleTypes) + 1;
}
}
return board;
}
public static int createRandomNumber(int type) {
double randomNumber = Math.random();
randomNumber = randomNumber * type;
int roundedNumber = (int) Math.floor(randomNumber);
int result = roundedNumber + 1;
return result;
}
public static void printGrid(int[][] grid) {
for( int row = 0; row < grid.length; row++ ) {
for( int col = 0; col < grid[row].length; col++ ) {
System.out.print( grid[row][col] + " " );
}
System.out.println("");
}
}
public static int[][] shiftRow( int[][] grid ) {
/*
* Pseudocode:
* Shift down first row to second row, then third row goes up two rows
*
* Shift each row down one (except the last row), then shift bottom row to the top
*
* Store the row after the current row in a temporary box, then overwrite the next row
* with the first, then repeat (excluding the last row).
*/
int[] tempList = new int[ grid[0].length ]; //0, 0, 0
for( int col = 0; col < grid[0].length; col++ ) {
tempList[col] = grid[0][col];
}
for( int row = 0; row < grid.length - 1; row++ ) {
int[] currentList = new int[ grid[row].length ];
for( int col = 0; col < grid[row].length; col++ ) {
currentList[col] = tempList[col];
tempList[col] = grid[row+1][col];
grid[row+1][col] = currentList[col];
}
}
int[][]newRow = createBoard(6, 1, 3);
for( int col = 0; col < grid[0].length; col++ ) {
grid[0][col] = newRow[0][col];
}
return grid;
}
public static void fillBoard(int[]array) {
}
public static String shoot(int number) {
System.out.println("What column do you want to shoot (A, B, C, D, E, F)");
System.out.println("The number that is going to be shoot is ---" + number + "--- ");
Scanner scanShoot = new Scanner(System.in);
String input = scanShoot.nextLine();
return input;
}
private static void clearConsole() {
System.out.print('\u000C'); //Clear terminal
}
public static int[][] combine(int[][]board, int[][] numberBoard) {
for(int i = 0; i < numberBoard.length; i++) {
for(int j = 0; j < numberBoard[i].length; j++) {
board[i][j] = numberBoard[i][j];
}
}
return board;
}
public static int[][] putNumber(int[][] board, String columnInput, int randomNumber) {
if(columnInput.equals("A") ) {
for(int row = 0; row < board.length; row++) {
if(board[row][0] == 0) {
board[row][0] = randomNumber;
break;
}
}
}
if(columnInput.equals("B") ) {
for(int row = 0; row < board.length; row++) {
if(board[row][1] == 0) {
board[row][1] = randomNumber;
break;
}
}
}
if(columnInput.equals("C") ) {
for(int row = 0; row < board.length; row++) {
if(board[row][2] == 0) {
board[row][2] = randomNumber;
break;
}
}
}
if(columnInput.equals("D") ) {
for(int row = 0; row < board.length; row++) {
if(board[row][3] == 0) {
board[row][3] = randomNumber;
break;
}
}
}
if(columnInput.equals("E") ) {
for(int row = 0; row < board.length; row++) {
if(board[row][4] == 0) {
board[row][4] = randomNumber;
break;
}
}
}
if(columnInput.equals("F") ) {
for(int row = 0; row < board.length; row++) {
if(board[row][5] == 0) {
board[row][5] = randomNumber;
break;
}
}
}
return board;
}
public static int [] numberLocation(int [][] board, String column, int randomNumber) {
int columnIndex = column.charAt (0) - 'A';
int saveRow = -1;
for (int row = 0; row < board.length; row++) {
if (columnIndex >= 0 && columnIndex < board[row].length && board [row][columnIndex] == 0) {
board [row][columnIndex] = randomNumber;
saveRow = row;
break;
}
}
return new int [] { saveRow, columnIndex };
}
public static void destroyNumbers(int num, int[][] grid) {
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (grid[i][j] == num) {
grid[i][j] = 0;
}
}
}
}
public static int[][] destroyAdjacentNumbers(int[][] array, int row, int col, int num) {
if (row < 0 || row >= array.length || col < 0 || col >= array[row].length) {
return array;
}
if (array[row][col] == num) {
array[row][col] = 0;
}
if (row > 0 && array[row - 1][col] == num) {
array[row - 1][col] = 0;
destroyAdjacentNumbers(array, row - 1, col, num);
}
if (row < array.length - 1 && array[row + 1][col] == num) {
array[row + 1][col] = 0;
destroyAdjacentNumbers(array, row + 1, col, num);
}
if (col > 0 && array[row][col - 1] == num) {
array[row][col - 1] = 0;
destroyAdjacentNumbers(array, row, col - 1, num);
}
if (col < array[row].length - 1 && array[row][col + 1] == num) {
array[row][col + 1] = 0;
destroyAdjacentNumbers(array, row, col + 1, num);
}
return array;
}
public static void numberShot(int number) {
System.out.println("The number that is going to be shot is " + " --- " + number + " --- " );
}
public static String gameOver(int[][] array) {
boolean hasEmpty = false;
boolean hasNonEmpty = false;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
if (array[i][j] == 0) {
hasEmpty = true;
} else {
hasNonEmpty = true;
}
}
}
if (hasEmpty && hasNonEmpty) {
return "GAME CONTINUES";
} else if (hasEmpty) {
clearConsole();
return "CONGRATULATIONS, YOU WON THE GAME!";
} else {
clearConsole();
return "YOU LOST THE GAME!";
}
}
public static int[][] deleteIslandBoard(int[][] array) {
// Create a boolean array to track which cells have been visited
boolean[][] visited = new boolean[array.length][array[0].length];
// Iterate
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[0].length; j++) {
// If the cell is not visited and is part of an island
if (!visited[i][j] && array[i][j] != 0) {
// Delete the island by setting all cells to 0
deleteIsland(array, i, j, visited);
}
}
}
// Return the modified array
return array;
}
public static void deleteIsland(int[][] array, int i, int j, boolean[][] visited) {
// Check if the current cell is out of board or if it has already been visited
if (i < 0 || i >= array.length || j < 0 || j >= array[0].length || visited[i][j]) {
return;
}
// Mark the current cell as visited
visited[i][j] = true; // If the current cell is part of the island, set it to 0
if (array[i][j] != 0) {
array[i][j] = 0;
// Recursively delete the neighboring cells that are part of the island
deleteIsland(array, i - 1, j, visited);
deleteIsland(array, i + 1, j, visited);
deleteIsland(array, i, j - 1, visited);
deleteIsland(array, i, j + 1, visited);
}
}
public class Island implements Comparable<Island> {
private List<int[]> cells = new ArrayList<>();
public void addCell(int[] cell) {
cells.add(cell);
}
public void destroy() {
cells.forEach(cell -> grid[cell[0]][cell[1]] = 0);
}
@Override
public int compareTo(Island other) {
return Integer.compare(cells.size(), other.cells.size());
}
}
public void deleteIslandBoard2() {
exploreIslands();
deleteSmallerIslands();
}
public void exploreIslands() {
boolean[][] visited = new boolean[grid.length][grid[0].length];
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (!visited[i][j] && grid[i][j] != 0) { // if a New Island was found
exploreIsland(new int[]{i, j}, visited); // explore the Island, i.e. index all its cell and mark them as visited
}
}
}
}
/**
* Depth first search implementation
*/
public void exploreIsland(int[] cell, boolean[][] visited) {
Island island = new Island();
islands.add(island); // updating the list of Islands
Deque<int[]> stack = new ArrayDeque<>();
stack.push(cell);
while (!stack.isEmpty()) {
int[] next = stack.poll();
island.addCell(next);
for (int[] shift : NEIGHBOURS) {
int row = next[0] + shift[0];
int col = next[1] + shift[1];
if (isValid(row, col) && !visited[row][col]) { // if cell exist, non-zero and not visited yet
stack.push(new int[]{row, col});
visited[row][col] = true;
}
}
}
}
public boolean isValid(int row, int col) {
return row >= 0 && row < grid.length
&& col >= 0 && col < grid[0].length
&& grid[row][col] != 0;
}
public void deleteSmallerIslands() {
if (islands.isEmpty()) return; // otherwise Collections.max() would throw NoSuchElementException
Island largest = Collections.max(islands);
for (Island next : islands) {
if (next != largest) next.destroy();
}
}
public void printGrid() {
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
System.out.print(grid[i][j] + " ");
}
System.out.println();
}
}
}
Most of this code shouldn't matter, just the methods that print stuff!!!!!!!!!!!!!!!