Place a word in a 2d array - java

is there a way to place a word in a 2d array in a specific position? For example,i want to give the word, choose vertical or horizontal and the position ((3,3) or (3,4) or (5,6) etc) and the word will be placed in that position.This is my code for the array...
char [][] Board = new char [16][16];
for (int i = 1; i<Board.length; i++) {
if (i != 1) {
System.out.println("\t");
System.out.print(i-1);
}
for (int j = 1; j <Board.length; j++) {
if ((j == 8 && i == 8) ||(j ==9 && i == 9) ||(j == 10 && i == 10) ||(j == 2 && i == 2) )
{
Board[i][j] = '*';
System.out.print(Board[i][j]);
}
else {
if (i == 1) {
System.out.print("\t");
System.out.print(j-1);
}
else {
Board[i][j] = '_';
System.out.print("\t");
System.out.print(""+Board[i][j]);
}
}
(the * means that the word cant be placed there)

Is there a way to place a word in a 2d array in a specific position?
Yes you can implement that. The pseudo-code is something like this:
public void placeWordHorizontally(char[][] board, String word, int x, int y) {
for (int i = 0; i < word.length(); i++) {
if (y + i >= board[x].length) {
// fail ... edge of board
} else if (board[x][y + i]) == '*') {
// fail ... blocked.
} else {
board[x][y + i] = word.charAt(i);
}
}
}
and to do the vertical case you add i etcetera to the x position.
I won't give you the exact code because you'll learn more if you fill in the details yourself.

Related

Problem with ship overlapping in 2D-arrays for Battleships game, Java

I am creating a simple console-based Battleships in Java, for people who is unfamiliar with the game, it's played on a 2D-grid where you can put down different sized ships either horizontally or vertically. In my example it is a 10x10 grid created by using a 2D char-array. The ships are NOT allowed to overlap each other, they can't share the same 1x1 grid.
I have managed to fix so they can't overlap each other, but the problem I have is if a ship share the same column or row (depending on if the ship is placed vertically or horizontally) at the STARTING POSITION, I can't place it down.
See example picture below for better understanding.
'0' is "empty" slots, 'S' is current placed ships(3-sized). I can place (in this example) 4-sized ships at blue markers, but I can't place them like the red markers
public void placeShip(ShipType shipType, int posX, int posY, int shipSize, Placement placement) {
boolean success = true;
char tempChar = 'x';
if(shipType == ShipType.BATTLESHIP)
tempChar = 'B';
else if(shipType == ShipType.CARRIER)
tempChar = 'C';
else if(shipType == ShipType.DESTROYER)
tempChar = 'D';
else if(shipType == ShipType.SUBMARINE)
tempChar = 'S';
if(placement == Placement.HORIZONTAL) {
for(int i = 0; i < posX+shipSize; i++) {
for(int j = 0; j < posX+shipSize; j++) {
if(board[i][posX-1] != '0' || board[posY-1][i] != '0') {
System.out.println("Can't place down the ship ");
success = false;
break;
}
}
}
if(success) {
System.out.println("Got space");
for(int i = 0; i < shipSize; i++) {
board[posY-1][posX-1+i] = tempChar;
success = false;
}
}
}
if(placement == Placement.VERTICAL) {
for(int i = 0; i < posY+shipSize; i++) {
for(int j = 0; j < posX+shipSize; j++) {
if(board[posY-1][i] != '0' || board[i][posX-1] != '0') {
System.out.println("Can't place down the ship ");
success = false;
break;
}
}
}
if(success) {
System.out.println("Got space");
for(int i = 0; i < shipSize; i++) {
board[posY-1+i][posX-1] = tempChar;
success = false;
}
}
}
}
Above is the code I use to place ships, where I send in Position X and Y and the size of the ship, and the direction of the ship.
You need to re-think your loops for checking if a ship can be placed down. Let's break down one of them into plain English:
if(placement == Placement.HORIZONTAL) {
for(int i = 0; i < posX+shipSize; i++) {
for(int j = 0; j < posX+shipSize; j++) {
if(board[i][posX-1] != '0' || board[posY-1][i] != '0') {
System.out.println("Can't place down the ship ");
success = false;
break;
}
}
}
First issue:
for(int i = 0; i < posX+shipSize; i++)
Why are we iterating from 0 to posX+shipSize? we only need to check shipSize spaces. So you should be looping from posX to posX+shipSize, or from 0 to shipSize, not a combination.
Second issue:
Despite your position being horizontal or vertical, you are nesting your for loops. Which means you're doing your loop shipSize times for no reason. You only need to do it once.
Third issue:
if(board[i][posX-1] != '0' || board[posY-1][i] != '0')
The position board[i][posX-1] has no meaning in this context, and is not related to the position of your ship, because you always start at i = 0. So no matter where you're trying to place your ship, if you have one in the same row or col, we have a problem. This is what's causing the issue in your question. Instead, it should be something like: if(board[posY-1][posX-1] != '0').
Lastly, why not just set the position of posX and posY properly? So you don't have to subtract 1 and confuse yourself.
Ultimately, your new block should look something like this (but I can't be sure since you didn't post a minimum reproducible example):
if(placement == Placement.HORIZONTAL) {
for(int i = 0; i < shipSize; i++) {
if(board[posY-1][posX-1+i] != '0') {
System.out.println("Can't place down the ship ");
success = false;
break;
}
}
// your code

Printing only NON-BOUNDARY and CORNER elements of an (n*n) array

I am to write a program that prints ONLY the NON-BOUNDARY AND CORNER elements of an (n*n) array, for my assignment, and this is the main part of the code:
The output I am getting is this:
As you can see, the non-boundary elements (6,7,10,11) are not in their correct positions, which I believe, is because of incorrect printing of tab spaces within the loop. (My code is totally a mess) I would like some help or suggestions to fix this. Thanks!
I generally find that flattening things (the if-conditions in particular), and putting conditions into boolean-returning methods helps. Try something like
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++ {
if (isCorner(i,j,n) || !isEdge(i,j,n)) {
//...
} else {
//...
}
}
System.out.println();
}
where isCorner(i,j,n) and isEdge(i,j,n) are defined something like
public boolean isCorner(int row, int column, int gridSize) {
//...
}
A you got a solution, just missing spaces, I'll add some smart things:
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
boolean visible = (i % (n - 1) == 0) == (j % (n - 1) == 0);
if (visible) {
System.out.printf(" %4d", a[i][j]);
} else {
System.out.print(" ");
}
}
System.out.println();
}
No longer any problems with tabs "\t", though I used spaces here.
Keep it simple, too many cases just cause problems - as you experienced.
The trick here is to consider whether to print or not. Hence I started with
a variable visible.
The border condition
i == 0 || i == n - 1
could also be written with modulo as
i % (n - 1) == 0
If this is "too smart", hard to grasp reading:
boolean iOnBorder = i % (n - 1) == 0;
boolean jOnBorder = j % (n - 1) == 0;
boolean visible = iOnBorder == jOnBorder;
The "X" pattern checks the _equivalence of i-on-border and j-on-border.
For the rest: formatted printf allows padding of a number.
Try this i have optimized your if condition
No need to again check for i == 0 or i == n-1
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i==0 || i==n-1){
if(j==0 || j==n-1){
System.out.print(a[i][j]);
}
}else{
if(j != 0 && j!= n-1){
System.out.print(a[i][j]);
}
}
System.out.print("\t");
}
System.out.println();
}
Just gave a try in case you might find it helpful.
public static void main(String[] args) throws ParseException {
int[][] ar = new int[4][4];
int[] input = new int[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
int pointer=0;
int imin=0,jmin=0,imax=3,jmax=3;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
ar[i][j]=input[pointer];
pointer++;
}
}
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(!((i==imax && j==jmin)||(i==imin && j==jmax)||i==j) && //For skipping the corners
(i == imin || j == jmin || i == imax || j == jmax)){// Not to print the borders
continue;
}
else {
System.out.println(ar[i][j]);
}
}
}
}

ArrayIndexOutOfBoundsException error on two-dimensional array [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 5 years ago.
I want to check the 8th positions adjacent to each of the positions of my two-dimensional array but the firsts ones give me error because there aren't positions there.
How can I avoid that error? The same happened to me in the past and I couldn't solve it neither.
Example image of what I want to do:
Code of my method:
private static void evoluciona(char[][] tauler2, char[][] tauler22) {
for(int i = 0; i < files; i++) {
for(int j = 0; j < columnes; j++) {
tauler2[i][j] = tauler[i][j];
}
}
for(int i = 0; i < files; i++) {
for(int j = 0; j < columnes; j++) {
if(tauler2[i][j] == 'x') {
int cont = 0;
if(tauler2[i-1][j] == '*') {
cont++;
}
if(tauler2[i-1][j-1] == '*') {
cont++;
}
if(tauler2[i-1][j+1] == '*') {
cont++;
}
if(tauler2[i][j-1] == '*') {
cont++;
}
if(tauler2[i+1][j-1] == '*') {
cont++;
}
if(tauler2[i+1][j] == '*') {
cont++;
}
if(tauler2[i+1][j+1] == '*') {
cont++;
}
if(tauler2[i][j+1] == '*') {
cont++;
}
if(cont == 2 || cont == 3) {
tauler2[i][j] = '*';
}
}
else if(tauler2[i][j] == '*') {
int cont = 0;
if(tauler2[i-1][j] == '*') {
cont++;
}
if(tauler2[i-1][j-1] == '*') {
cont++;
}
if(tauler2[i-1][j+1] == '*') {
cont++;
}
if(tauler2[i][j-1] == '*') {
cont++;
}
if(tauler2[i+1][j-1] == '*') {
cont++;
}
if(tauler2[i+1][j] == '*') {
cont++;
}
if(tauler2[i+1][j+1] == '*') {
cont++;
}
if(tauler2[i][j+1] == '*') {
cont++;
}
if(cont == 2 || cont == 3) {
tauler2[i][j] = '*';
}
else {
tauler2[i][j] = 'x';
}
}
}
}
}
I had a similar problem when programming my own little Minesweeper clone around christmas.
I ended up with a field class that knows its neighbors.
class Field {
char value;
Field[] neighbors;
}
Whenever initializing a new board those 'connections' were sort of precompiled.
class FieldManager {
void initializeFields(int firstDimension, int secondDimension) {
fields = new Field[firstDimension][secondDimension];
for(int i = 0; i < fields.length; i++) {
for(int j = 0; j < fields[i].length; j++) {
fields[i][j] = new Field();
fields[i][j].neighbors = neighborsFor(i, j);
}
}
}
private Field[] neighborsFor(int iIn, int jIn) {
List<Field> result = new ArrayList<>();
for(int i = iIn - 1; i <= iIn + 1; i++) {
for(int j = jIn - 1; j < jIn + 1; j++)
// do some range checks and fill result
}
}
return result.toArray(new Field[result.size()]);
}
Field[][] fields;
}
Instead of array you can as well use Collections, such as ArrayList. Especially the newer java versions have a lot of useful utility built around those interfaces.
I'd recommend explicitly checking against boundaries!
Modify your if statements, so that whenever you have i+1, j+1 you check it's not too large ( i < files and j < columnes), and i-1, j-1 that they are not 0 ( i > 0 and j > 0).
As you are counting neighboring stars, this method will not add extra stars if you are on the border.
Alternatively, the "lazy way", you can try{} catch(ArrayOutOfBoundsException e) { continue; } inside the inner loops!
In all the places that you have an index of i-1 or j-1, on the first iteration of either cycle (i or j) you can have an index of -1 as per your exception in the stack trace, which causes the ArrayIndexOutOfBoundsException.
Instead of catching it and ignoring it, place an if around the areas that can cause this exception before doing anything.
// your code
...
if (i - 1 >= 0) {
if(tauler2[i-1][j] == '*') {
cont++;
}
}
...
and likewise in the case of tauler2[i][j-1], a condition check on j - 1 >= 0.
you are accessing such an index that is not in array. As you are starting forloops i-e i=0 and j=0, and in if conditions u r using indexes that are [i-1] and [j-1]. here u r getting exception of index out of bounds. eliminate or change these conditions.

Square pattern java

Create void method that will put on screen square with patern like that :
xoxo
xoxo
xoxo
xoxo
First argument of the method will define amount of characters used to create a square side, second which character is first.
This is my solution but im wondering if i can do it with less code.
static void square(char a, int b) {
if (a == 'x') {
for (int i = 0; i < b; i++) {
int sum = 0;
do {
System.out.print("x");
sum++;
if (sum == b)
break;
System.out.print("o");
sum++;
}
while (sum != b);
System.out.println();
}
} else {
for (int i = 0; i < b; i++) {
int sum = 0;
do {
System.out.print("o");
sum++;
if (sum == b)
break;
System.out.print("x");
sum++;
}
while (sum != b);
System.out.println();
}
}
}
How to make pattern to look like
xoxox
oxoxo
xoxox
oxoxo
xoxox
And how to make this using only for loops or arrays.
O(n^2) loop and constant O(k) space. Start from 0 and just keep alternating the characters till you reach the end (b^2).
char oth = (a == 'x') ? 'o' : 'x';
for (int i = 0; i < (b * b); i++) {
System.out.print(i % 2 == 0 ? a : oth);
if ((i + 1) % b == 0) {
System.out.println();
}
}
O(n) loop and O(n) space. Construct the two pattern rows to print and alternate them.
char oth = (a == 'x') ? 'o' : 'x';
String x = (a == 'x') ? "xo" : "ox";
// Construct the two repeating patterns which will alternate
String first = String.join("", Collections.nCopies(b / 2, x));
String second = first;
if (b % 2 == 1) {
second = new StringBuilder(first).reverse().toString();
first += a;
second += oth;
}
for (int i = 0; i < b; i++) {
System.out.println(i % 2 == 0 ? first : second);
}
See output here: https://ideone.com/E3bVFK
Have fun
public static void square(int side, char order){
char x = (order=='x')?'x':'o';
char o = (order=='x')?'o':'x';
for ( int i = 0; i < side; i++ ) {
for ( int j = 0; j < side; j++ )
System.out.print((j%2==0)?x:o);
System.out.println();
}
}
Output would be exactly what you were asking for.

How can I turn the null character into a blank character in my Java TicTacToe program?

At the moment, I have working code for a simple Tic Tac Toe program written in java. The only problem, as you'll see below, is that the null character (\u0000) is being printed instead of an open space when my board is displayed.
My professor told us to write this program in such a way that null spaces are detected and to fill them with either X or O, which I did.
Now, I would like to be able to change the null character from appearing as 00 to just a blank space since the format is incorrect otherwise.
I already tried simply erasing the '\u0000' character and replacing it with a ' ' character but then my board doesn't show up at all. Any help is appreciated!
import java.util.Scanner;
public class TicTacToe
{
public static void main(String[] args)
{
char[][] board = new char[3][3];
while (true) {
makeCompMove(board, 'X');
displayBoard(board);
if(isWon('X', board)) {
System.out.println("\n\nComputer won!");
System.exit(1);
}
else if (isDraw(board)) {
System.out.println("\n\nDraw Game! No winner");
System.exit(2);
}
makeAMove(board, 'O');
displayBoard(board);
if (isWon('O', board)) {
System.out.println("\n\nPlayer won!");
System.exit(3);
}
else if (isDraw(board)) {
System.out.println("\n\nDraw Game! No winner");
System.exit(4);
}
}
}
public static void displayBoard(char[][] board)
{
for(int k = 0; k < 3; k++)
{
for(int i = 0; i < 28; i++)
{
System.out.print("-");
}
System.out.println();
for(int j = 0; j < 3; j++)
{
System.out.print("|" + " " + board[k][j] + " ");
}
System.out.println("|");
}
for(int i = 0; i < 28; i++)
{
System.out.print("-");
}
}
public static void makeAMove(char[][] board, char o)
{
Scanner input = new Scanner(System.in);
while(true)
{
System.out.print("\n\nYour turn. Enter a row and col(0,1 or 2): ");
int row = input.nextInt();
int col = input.nextInt();
if(row > 2 || row < 0 || col > 2 || col < 0)
{
System.out.println("Incorrect Input. Try Again!");
continue;
}
if(board[row][col] == '\u0000')
{
System.out.print("\n You (O) have made your move...\n\n");
board[row][col] = 'O';
break;
}
else
System.out.println("Incorrect Input. Try Again!");
}
}
public static void makeCompMove(char[][] board, char x)
{
System.out.println();
System.out.println();
System.out.print("Computer (X) has made his move...\n");
while(true)
{
int row = (int)(Math.random()*3);
int col = (int)(Math.random()*3);
if(board[row][col] == '\u0000')
{
board[row][col] = x;
break;
}
}
System.out.println();
}
public static boolean isDraw(char[][] board)
{
for(int row = 0; row < 3; row++)
{
for(int col = 0; col < 3; col++)
{
if(board[row][col] == '\u0000')
{
return false;
}
}
}
return true;
}
public static boolean isWon(char x, char[][] board)
{
// Check Rows
for (int i = 0; i < 3; i++)
if (x == board[i][0] && x == board[i][1] && x == board[i][2])
return true;
// Check Columns
for (int j = 0; j < 3; j++)
if (x == board[0][j] && x == board[1][j] && x == board[2][j])
return true;
// Check first diagonal
if (x == board[0][0] && x == board[1][1] && x == board[2][2])
return true;
// Check second diagonal
if (x == board[0][2] && x == board[1][1] && x == board[2][0])
return true;
return false;
}
}
No need to change any of code You Just Check before display
in displayBoard use like this
for(int j = 0; j < 3; j++)
{
if(board[k][j]=='\u0000')
System.out.print("|" + " ");
else
System.out.print("|" + " " + board[k][j] + " ");
}
The elements in the two-dimensional array are set to the null character when the array is initialized. If you want to convert them all to a space, then iterate over them all and replace the character with a space.
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
board[i][j] = ' ';
}
}
If the place is never used, then it will have a space instead of the null character in it. Do this before you use the array.

Categories

Resources