There's a game file that runs my class and then calculates my average. It calculates the gameboard and gives me an array with the gameboard changes. It starts as a 10x10 of "." which get replaced by X if I hit or O if I miss. If I sink a ship it replaces all the X's(hits) with a number so if it was a destroyer with XXXXX it would become 55555.
When I run the game file and it gives me my average there is a ton of lines before the average saying out of guesses(max 100). I can't find out what is causing it to stop giving answers or bug up. Only thing I've noticed is if there's a hit on A1 and a miss on A2 leaving the only option as B2 it will sometimes give me A1. Any help is greatly appreciated!
public class stug_Bot
{
public static String makeGuess(char[][] guesses)
{
int row = 0;
int col = 0;
int squareValue = squareType(guesses);
int atkRow = -1;
int atkCol = -1;
int direction = 0;
if (guessNumber(guesses) == 0)
{
row = ( 4 + (int)(Math.random() * 2));
col = (4 + (int)(Math.random() * 2));
}
else if (hits(guesses))
{
for ( int i = 0; i < guesses.length; i++)
{
for ( int j = 0; j < guesses[i].length; j++)
if (guesses[i][j] == 'X')
{
atkRow = i;
atkCol = j;
break;
}
if (atkRow != -1)
break;
}
while(true)
{
direction = (int)(Math.random() * 4);
if (direction == 0 && atkRow != 0)
{
if (targetUp(atkRow, atkCol, guesses) == -1)
break;
col = atkCol;
row = targetUp(atkRow, atkCol, guesses);
break;
}
else if (direction == 1 && atkCol < 9)
{
if (targetRight(atkRow, atkCol, guesses) == -1)
break;
row = atkRow;
col = targetRight(atkRow, atkCol, guesses);
break;
}
else if (direction == 2 && atkRow < 9)
{
if (targetDown(atkRow, atkCol, guesses) == -1)
break;
col = atkCol;
row = targetDown(atkRow, atkCol, guesses);
break;
}
else if (direction == 3 && atkCol != 0)
{
if (targetLeft(atkRow, atkCol, guesses) == -1)
break;
row = atkRow;
col = targetLeft(atkRow, atkCol, guesses);
break;
}
}
}
else if (guessNumber(guesses) == 1)
{
do
{
row = ( 4 + (int)(Math.random() * 2));
col = (4 + (int)(Math.random() * 2));
} while (!isCorrectSquare(row, col, squareValue) || guesses[row][col] == 'X' || guesses[row][col] == 'O' || guesses[row][col] == '1' || guesses[row][col] == '2' || guesses[row][col] == '3' || guesses[row][col] == '4' || guesses[row][col] == '5');
}
else if (guessNumber(guesses) == 2)
{
do
{
row = (3 + (int)(Math.random() * 4));
col = (3 + (int)(Math.random() * 4));
} while (!isCorrectSquare(row, col, squareValue) || guesses[row][col] == 'X' || guesses[row][col] == 'O' || guesses[row][col] == '1' || guesses[row][col] == '2' || guesses[row][col] == '3' || guesses[row][col] == '4' || guesses[row][col] == '5');
}
else if (guessNumber(guesses) == 3)
{
do
{
row = (3 + (int)(Math.random() * 4));
col = (3 + (int)(Math.random() * 4));
} while (!isCorrectSquare(row, col, squareValue) || guesses[row][col] == 'X' || guesses[row][col] == 'O' || guesses[row][col] == '1' || guesses[row][col] == '2' || guesses[row][col] == '3' || guesses[row][col] == '4' || guesses[row][col] == '5');
}
else if (guessNumber(guesses) == 4)
{
do
{
row = (1 + (int)(Math.random() * 8));
col = (1 + (int)(Math.random() * 8));
} while (!isCorrectSquare(row, col, squareValue) || guesses[row][col] == 'X' || guesses[row][col] == 'O' || guesses[row][col] == '1' || guesses[row][col] == '2' || guesses[row][col] == '3' || guesses[row][col] == '4' || guesses[row][col] == '5');
}
else
{
do
{
row = ((int)(Math.random() * 10));
col = ((int)(Math.random() * 10));
} while (!isCorrectSquare(row, col, squareValue) || guesses[row][col] == 'X' || guesses[row][col] == 'O' || guesses[row][col] == '1' || guesses[row][col] == '2' || guesses[row][col] == '3' || guesses[row][col] == '4' || guesses[row][col] == '5');
}
char a = (char)((int)'A' + row);
String guess = a + Integer.toString(col+1);
return guess;
}
public static int guessNumber(char[][] arr)
{
int count = 0;
for ( int i = 0; i < arr.length; i++)
{
for ( int j = 0; j < arr[i].length; j++)
{
if (arr[i][j] != '.')
count++;
}
}
return count;
}
public static int squareType(char[][] arr)
{
int square = 0;
if (arr[4][4] != '.')
{
square = 0;
}
else if (arr[5][4] != '.')
{
square = 1;
}
else if (arr[4][5] != '.')
{
square = 1;
}
else if (arr[5][5] != '.')
{
square = 0;
}
else
{
square = 0;
}
return square;
}
public static boolean isCorrectSquare(int x, int y, int z)
{
if (( z == 0 ) && ((x + y) % 2 != 0) || (( z == 1 ) && ((x + y) % 2 == 0)))
{
return false;
}
else
{
return true;
}
}
public static boolean hits(char[][] arr)
{
for ( int i = 0; i < arr.length; i++)
{
for ( int j = 0; j < arr[i].length; j++)
{
if (arr[i][j] == 'X')
return true;
}
}
return false;
}
public static int targetUp(int row, int col, char[][] map)
{
int target = 0;
int count = 1;
while(true)
{
if (row != 0 && map[row - count][col] == '.')
{
target = row - count;
return target;
}
else if ( row!= 0 && map[row - count][col] == 'X')
{
count++;
}
else
{
return -1;
}
}
}
public static int targetRight(int row, int col, char[][] map)
{
int target = 0;
int count = 1;
while(true)
{
if (col+count < 10 && map[row][col + count] == '.')
{
target = col + count;
return target;
}
else if ( col+count < 10 && map[row][col + count] == 'X')
{
count++;
}
else
{
return -1;
}
}
}
public static int targetDown(int row, int col, char[][] map)
{
int target = 0;
int count = 1;
while(true)
{
if (row + count < 10 && map[row + count][col] == '.')
{
target = row + count;
return target;
}
else if ( row + count < 10 && map[row + count][col] == 'X')
{
count++;
}
else
return -1;
}
}
public static int targetLeft(int row, int col, char[][] map)
{
int target = 0;
int count = 1;
while(true)
{
if (col != 0 && map[row][col - count] == '.')
{
target = col - count;
return target;
}
else if ( col != 0 && map[row][col - count] == 'X')
{
count++;
}
else
return -1;
}
}
}
It turned out it was the break statements I was using in the else if (hits) section. If it picked a direction that had something blocking the way like a previous miss it would break the loop and return no value which led to the out of moves in a lot of the games. Replacing them with continue fixed it.
I'm learning java looping, and managed to print a number one pattern using the for loop.
I tried printing the number one pattern using the while and do while loop, but had difficulty. This is my code:
for (int i = 0; i <= 7; i++) {
for (int j = 0; j <= 4; j++) {
if ((i == 0 && j > 1) || (i == 1 && j > 0) || (i == 2 && j >= 0) || (i == 3 && j > 1) || (i > 3 && j > 1))
System.out.print("1");
else
System.out.print(" ");
}
System.out.println();
}
This is my while loop code:
int i = 0, j = 0;
while (i <= 7) {
while (j <= 4) {
if((i == 0 && j > 1) || (i == 1 && j > 0) || (i == 2 && j >= 0) || (i == 3 && j > 1) || (i > 3 && j > 1))
System.out.print("1");
else
System.out.print(" ");
j++;
}
System.out.println();
i++;
}
Need to reset j counter after first j_while end
int i = 0, j = 0;
while (i <= 7)
{
//could also reset here
j=0;
while (j <= 4)
{
if((i == 0 && j > 1) || (i == 1 && j > 0) || (i == 2 && j >= 0) || (i == 3 && j > 1) || (i > 3 && j > 1))
System.out.print("1");
else
System.out.print(" ");
j++;
}
System.out.println();
i++;
}
Yes, any for loop can be converted into a while or do-while.
For example:
for(initialize; condition_check, statement1) {
......
}
Here statement1 => generally this is an increment or decrement of a variable used in the condition_check
Similarly the equivalent while loop would be:
initialize;
while (condition_check) {
.......;
statement1;
}
So it seems that you have forgotten to initialize one of the variables. The other answer has already given you that.
This answer would help in mapping the for loop to the while loop and vice-versa.
Hope it helps.
EDIT: I don't know why somebody links me a TicTacToe as duplicate for my question, there isn't even a MinMax-Algorithm in it.
Currently i'm working on a Connect4 game against the computer which should use the MinMax-Algorithm.
Before that, we wrote a TicTacToe which also uses the MinMax, but i'm not sure how to change my old algorithm to match the Connect4-Game :/.
In TicTacToe i evaluated each possible move with the win-conditions i wrote, it worked fine, but now it won't work with my new conditions.
My makeAMove etc. works fine!
These are my old conditions and the MinMax for TicTacToe:
//Player 1 wins
static boolean has1Won(int[][] array) {
gameBoard = array;
//Diagonal
if ((gameBoard[0][0] == gameBoard[1][1] && gameBoard[0][0] == gameBoard[2][2] && gameBoard[0][0] == 1)
|| (gameBoard[0][2] == gameBoard[1][1] && gameBoard[0][2] == gameBoard[2][0] && gameBoard[0][2] == 1)) {
return true;
}
//Spalten/Zeilen
for (int i = 0; i < 3; ++i) {
if (((gameBoard[i][0] == gameBoard[i][1] && gameBoard[i][0] == gameBoard[i][2] && gameBoard[i][0] == 1)
|| (gameBoard[0][i] == gameBoard[1][i] && gameBoard[0][i] == gameBoard[2][i] && gameBoard[0][i] == 1))) {
return true;
}
}
return false;
}
// Player 2 wins
static boolean has2Won(int[][] array) {
gameBoard = array;
//Diagonal
if ((gameBoard[0][0] == gameBoard[1][1] && gameBoard[0][0] == gameBoard[2][2] && gameBoard[0][0] == 2)
|| (gameBoard[0][2] == gameBoard[1][1] && gameBoard[0][2] == gameBoard[2][0] && gameBoard[0][2] == 2)) {
return true;
}
//Spalten/Zeilen
for (int i = 0; i < 3; ++i) {
if (((gameBoard[i][0] == gameBoard[i][1] && gameBoard[i][0] == gameBoard[i][2] && gameBoard[i][0] == 2)
|| (gameBoard[0][i] == gameBoard[1][i] && gameBoard[0][i] == gameBoard[2][i] && gameBoard[0][i] == 2))) {
return true;
}
}
return false;
}
As I said, i used these conditions for my MinMax like this:
public static int minimax(int depth, int turn) {
if (Board.has1Won(Board.gameBoard)){
return +1; // Der Computer gewinnt
}
if (Board.has2Won(Board.gameBoard)){
return -1; // Der Spieler gewinnt
}
List<GameMove> gameMovesAvailable = GameMove.getAvailableGameMoves();
if (gameMovesAvailable.isEmpty()){
return 0; // Das Spiel endet unentschieden
}
...
I'm not sure how i can get this to work with my new conditions:
I think i have to write an evaluating function which checks this for example (this is my wincondition for Rows):
boolean getWinnerInRow (Playboard brd){
int count = 0;
for (int i = 0; i < 6; i++){
for (int j = 0; j < 7; j++){
if (brd.gameBoard[i][j] != 0 && brd.gameBoard[i][j] == brd.gameBoard[i][j+1]){
count++;
} else {
count = 1;
}
if (count >= 4){
return true;
}
}
}
return false;
I know it's a lot of text, but maybe somebody can give me some useful tips :)
Thanks!
Max
I'm not sure that your test to find the winner is correct. Try this (you'll need to change it a little bit, but at least I'm sure that it's correct):
public static boolean testWinner(int[][] game, int lastColumn, Integ e) {
int lastRow = 0;
while (lastRow < 6 && game[lastRow][lastColumn] == 0) {
lastRow++;
}
lastRow = lastRow;
int i = 0;
int j = 0;
int currentPlayer = game[lastRow][lastColumn];
e.setI(currentPlayer);
int sequence = 0;
i = lastRow;
boolean b = i < 3
&& game[i][lastColumn] == currentPlayer
&& game[i+1][lastColumn] == currentPlayer
&& game[i+2][lastColumn] == currentPlayer
&& game[i+3][lastColumn] == currentPlayer;
if(b) {
return true;
}
sequence = 0;
j = lastColumn;
do {
j--;
} while(0 < j && game[lastRow][j] == currentPlayer);
if(j < 0 || game[lastRow][j] != currentPlayer) {
j++;
}
while(j <= 6 && game[lastRow][j] == currentPlayer) {
j++;
sequence++;
}
if (sequence >= 4) {
return true;
}
sequence = 0;
i = lastRow;
j = lastColumn;
do {
i--;
j--;
} while(0 < i && 0 < j && game[i][j] == currentPlayer);
if(i < 0 || j < 0 || game[i][j] != currentPlayer) {
i++;
j++;
}
while(i <= 5 && j <= 6 && game[i][j] == currentPlayer) {
i++;
j++;
sequence++;
}
if (sequence >= 4) {
return true;
}
sequence = 0;
i = lastRow;
j = lastColumn;
do {
i++;
j--;
} while(i < 5 && 0 < j && game[i][j] == currentPlayer);
if (5 < i || j < 0 || game[i][j] != currentPlayer) {
i--;
j++;
}
while(0 <= i && j <= 6 && game[i][j] == currentPlayer) {
i--;
j++;
sequence++;
}
if (sequence >= 4) {
return true;
}
return false;
}
Integ is just a class with an integer. I've created it because the wrapper is not really an object (can't pass by reference).
private static class Integ {
private int i;
public Integ() {
this.i = 0;
}
public void increment() {
this.i = this.i + 1;
}
public int getI() {
return this.i;
}
public void setI(int i) {
this.i = i;
}
}
I am creating a very rudimentary battle ship program for fun and I
have come across a problem with changing values in my rectangular two dimensional array. Essentially, there are five "ships" placed in this two dimensional array. A user then inputs an integer to see if they hit or miss. I wanted the output to display the array with the guessed number represented with an X for a miss and a 0 for a hit. I am having trouble with changing the value at area[i][j] when it equals the value of t to the 0 or X. I am new to java so I am trying to learn. Any help would be appreciated. Thank you in advance.
import java.util.*;
public class battleship {
//Rudimentary Battleship game
public static void main(String[] args) {
System.out.println(" Hello and welcome to a basic version of Battleship.");
System.out.println(" The objective of this game is to sink all five ships located on the grid listed below.");
System.out.println(" Follow the prompt located underneath the grid ");
final int ROWS = 10;
final int COLS = 10;
int sum = 0;
int [][] area = { {1,2,3,4,5,6,7,8,9,10},
{11,12,13,14,15,16,17,18,19,20},
{21,22,23,24,25,26,27,28,29,30},
{31,32,33,34,35,36,37,38,39,40},
{41,42,43,44,45,46,47,48,49,50},
{51,52,53,54,55,56,57,58,59,60},
{61,62,63,64,65,66,67,68,69,70},
{71,72,73,74,75,76,77,78,79,80},
{81,82,83,84,85,86,87,88,89,90},
{91,92,93,94,95,96,97,98,99,100} };
for(int i=0; i < area.length; i++) {
for (int j=0; j < area[i].length; j++) {
if(area[i][j] < 10)
System.out.print(" "+(area[i][j])+" ");
else if(area[i][j] < 100)
System.out.print(" "+(area[i][j])+" ");
else
System.out.print(" "+(area[i][j])+" ");
}
System.out.println("");
}
Scanner input = new Scanner(System.in);{
System.out.println("Enter attack integer:");
int t;
while(true){
t = input.nextInt();
if ((t == 41) || (t == 42) || (t == 43)){
System.out.println("Hit - Destroyer");}
if ((t == 80) || (t == 90) || (t == 100)){
System.out.println("Hit - Submarine");}
if((t == 52) || (t == 62) || (t== 72) || (t == 82) || (t == 92)){
System.out.println ("Hit - Aircraft Carrier");}
if((t == 15) || (t == 16) || (t == 17) || (t == 18)){
System.out.println ("Hit - Battleship");}
if((t == 1) || (t == 2)){
System.out.println ("Hit - PT Boat");}
else{
System.out.println ("Miss");
}
System.out.println("You have fired at:" + t);
int w = 0;
for(int i=0; i < area.length; i++) {
for (int j=0; j < area[i].length; j++) {
if (area[i][j] == t)
if(area[i][j] < 10)
System.out.print(" "+(area[i][j])+" ");
else if(area[i][j] < 100)
System.out.print(" "+(area[i][j])+" ");
else
System.out.print(" "+(area[i][j])+" ");
}
System.out.println("");
}
}
}
}
}
You would be much better off using object orientation. Here's a skeleton to get you started:
public class Cell {
private boolean ship = false;
private boolean hit = false;
public boolean getHit() {
return hit;
}
public void setHit(boolean hit) {
this.hit = hit;
}
}
Then
public class Board() {
public static final int SIZE = 10;
private Cell[][] board;
public Board() {
board = new Cell[SIZE][SIZE];
for(int i = 0; i < 10; i++)
for(int j = 0; j < 10; j++)
board[i][j] = new Cell();
public boolean getHit(int x, int y) {
if(x < 0 || x >= SIZE || y < 0 || y >= SIZE) throw new BattleshipException("You queried a cell that doesn't exist!");
return board[x][y].getHit();
}
// etc etc.
}
Flesh out all the methods you need, add fields when you need them, this will work much better!
This is simple, modifying your code:
if ((t == 41) || (t == 42) || (t == 43)){
System.out.println("Hit - Destroyer");
area[i][j] = "X";
}
if ((t == 80) || (t == 90) || (t == 100)){
System.out.println("Hit - Submarine");
area[i][j] = "X";
}
if((t == 52) || (t == 62) || (t== 72) || (t == 82) || (t == 92)){
System.out.println ("Hit - Aircraft Carrier");
area[i][j] = "X";
}
if((t == 15) || (t == 16) || (t == 17) || (t == 18)){
System.out.println ("Hit - Battleship");
area[i][j] = "X";
}
if((t == 1) || (t == 2)){
System.out.println ("Hit - PT Boat");
area[i][j] = "X";
}
else{
System.out.println ("Miss");
area[i][j] = "O";
}
A note: be careful, arrays are 0 indexed, so your ship positions don't exactly correspond to the way you set up the grid. i.e. area[4][1] is not "41". You seemed to do this correctly (in the case of the destroyer) for the columns but not the rows. The if statements should check for 31, 32, 33 if the ship is at area[4][0], area[4][1], area [4][2]. In fact, you might be better off labeling the positions from 00, 01, 02, ... , 97, 98, 99 so that the indices correspond to the numbers.
When I compiled I got here error java.lang.ArrayIndexOutOfBoundsException: -1. I checked code 3 times and no error found there, also I am not writing after end of array.
Random nahoda = new Random(); int[][] minPol = new int[5][5];
int[][] cisPol = new int[5][5];
for(int i = 0;i<5;i++)
{
for(int j=0;j<5;j++)
{
minPol[i][j] = nahoda.nextInt(2);
cisPol[i][j] = 0;
}
}
for(int i = 0;i<5;i++)
{
for(int j=0;j<5;j++)
{
if(minPol[i][j]!=0)
{
if(i != 0 || j != 0 || i != 4 || j != 4)
{
cisPol[i+1][j+1]++;
cisPol[i+1][j-1]++;
cisPol[i-1][j+1]++;
cisPol[i-1][j-1]++;
cisPol[i+1][j]++;
cisPol[i-1][j]++;
cisPol[i][j+1]++;
cisPol[i][j-1]++;
}
else
{
if(i == 0)
{
if(j == 0)
{
cisPol[i+1][j+1]++;
cisPol[i][j+1]++;
cisPol[i+1][j]++;
}
else if(j == 4)
{
cisPol[i+1][j]++;
cisPol[i+1][j-1]++;
cisPol[i][j-1]++;
}
else
{
cisPol[i+1][j+1]++;
cisPol[i][j+1]++;
cisPol[i+1][j]++;
cisPol[i+1][j-1]++;
cisPol[i][j-1]++;
}
}
else if(i == 4)
{
if(j == 0)
{
cisPol[i-1][j+1]++;
cisPol[i-1][j]++;
cisPol[i][j+1]++;
}
else if(j == 4)
{
cisPol[i-1][j-1]++;
cisPol[i-1][j]++;
cisPol[i][j-1]++;
}
else
{
cisPol[i][j-1]++;
cisPol[i][j+1]++;
cisPol[i-1][j+1]++;
cisPol[i-1][j]++;
cisPol[i-1][j-1]++;
}
}
}
}
}
}
I am beginner in Java and thanks for tips
Look at this condition:
if(i != 0 || j != 0 || i != 4 || j != 4)
That doesn't do what you want it to. It will always be true, because i can't be simultaneously equal to 0 and 4.
Therefore you'll end up going into here when j is 0:
cisPol[i+1][j-1]++;
Bang.
Try this;
Replace this line;
if(i != 0 || j != 0 || i != 4 || j != 4)
with
if( i>=1 && j>=1 && j<4 && i<4)
That will make sure you don't reference from your array with a negative index or a value greater than 4.