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.
Related
This question already has answers here:
Ludo game board in java [closed]
(2 answers)
Closed 2 years ago.
How do I write code to this board without using an array? I tried, but I did not get the right result. It should be with functions, loops and conditional structures. Row=11, column=11.
public static void board(int size) {
for (int i=1; i<=size;i++){
for (int j=1; j<=size; j++){
if (i==6 && j==6){
System.out.print(" ");
}
else if ( i==5 || i==7 || j==5 || j==7 || i==6 && j==1 || i==6 && j==11 ||
i==1 && j==6 || i==11 && j==6){
if (i==6 && j==7 || i==5 && j==6 || i==6 && j==5 || i==7 && j==6 ){
break;
}else{
System.out.print("o");
}
}
else if (i==6 || j==6 ) {
System.out.print(".");
}
else{
System.out.print(" ");
}
}
System.out.println();
}
}
public static void main(String[] args) {
board(11);
}
Do it as follows:
public class Main {
public static void main(String[] args) {
board(11);
}
public static void board(int size) {
for (int i = 1; i <= size; i++) {
for (int j = 1; j <= size; j++) {
if ((i == 6 && j == 6)) {
System.out.print(" ");
} else if (i == 5 || i == 7 || j == 5 || j == 7 || i == 6 && j == 1 || i == 6 && j == 11
|| i == 1 && j == 6 || i == 11 && j == 6) {
if (i == 6 && j == 5 || i == 6 && j == 7 || i == 5 && j == 6 || i == 7 && j == 6) {
System.out.print(".");
} else {
System.out.print("o");
}
} else if (i == 6 || j == 6) {
System.out.print(".");
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
}
Output:
ooo
o.o
o.o
o.o
ooooo.ooooo
o.... ....o
ooooo.ooooo
o.o
o.o
o.o
ooo
You can write a general routine for any board size by detecting if the cell lies in one of the 4 corner blocks, in which case you print a space, on a center row or column, in which case you print a "." or a space if you're at the board center, otherwise you print a wall (O).
public static void board(int size)
{
if(size % 2 == 0 || size <= 3)
throw new IllegalArgumentException("Board size must be odd and bigger than 3: " + size);
int center = (size+1)/2;
int corner = (size-1)/2;
for (int i = 1; i <= size; i++)
{
for (int j = 1; j <= size; j++)
{
if(Math.max(i, j) < corner ||
Math.max(Math.min(i, 1+size-i), j) < corner ||
Math.max(i, Math.min(j, 1+size-j)) < corner ||
Math.max(Math.min(i, 1+size-i), Math.min(j, 1+size-j)) < corner)
{
System.out.print(" ");
}
else if((i > 1 && i < size && j == center) || (j > 1 && j < size && i == center))
{
if(i == center && j == center)
System.out.print(" ");
else
System.out.print(".");
}
else
{
System.out.print("O");
}
}
System.out.println();
}
}
board(7);
OOO
O.O
OOO.OOO
O.. ..O
OOO.OOO
O.O
OOO
board(11);
OOO
O.O
O.O
O.O
OOOOO.OOOOO
O.... ....O
OOOOO.OOOOO
O.O
O.O
O.O
OOO
The riddle I'm hoping to solve can be found in this video.
In case you're unable to watch the whole video, here is an outline of the riddle:
In short, I need to find the smallest number of points where there is guaranteed to be at least one single-color triangle from any arrangement of red and blue lines connecting every single pair of points.
Below is a Java program I wrote to solve it.
public class RedBlueTimeTravelProblem {
public static void main(String[] args) {
int max = 3;
boolean alltri = false;
long start, end;
double time;
while (!alltri) {
start = System.nanoTime();
int edgecount = max * (max - 1) / 2;
int combos = (int) Math.pow(2, edgecount);
alltri = false;
for (int i=1; i<=combos; i++) {
int a = i-1;
int[][] edge = new int[edgecount][3];
for (int j=0; j<edgecount; j++) {
edge[j][2] = a % 2;
a = (a - a % 2) / 2;
}
int c2 = 0;
for (int j=1; j<=max; j++) {
for (int k=j+1; k<=max; k++) {
edge[c2][0] = j;
edge[c2][1] = k;
c2++;
}
}
boolean tri = false;
for (int j=0; j<edgecount-2; j++) {
for (int k=j+1; k<edgecount-1; k++) {
for (int m=k+1; m<edgecount; m++) {
if ((edge[j][0] == edge[k][0] && ((edge[j][1] == edge[m][0] && edge[k][1] == edge[m][1]) || (edge[j][1] == edge[m][1] && edge[k][1] == edge[m][0]))) ||
(edge[j][0] == edge[k][1] && ((edge[j][1] == edge[m][0] && edge[k][0] == edge[m][1]) || (edge[j][1] == edge[m][1] && edge[k][0] == edge[m][0]))) ||
(edge[j][0] == edge[m][0] && ((edge[j][1] == edge[k][0] && edge[k][1] == edge[m][1]) || (edge[j][1] == edge[k][1] && edge[k][0] == edge[m][1]))) ||
(edge[j][0] == edge[m][1] && ((edge[j][1] == edge[k][0] && edge[k][1] == edge[m][0]) || (edge[j][1] == edge[k][1] && edge[k][0] == edge[m][0])))) {
tri = tri || (edge[j][2] == edge[k][2] && edge[k][2] == edge[m][2]);
}
}
}
}
alltri = alltri && tri;
}
end = System.nanoTime();
time = (end - start) / 1000000000.0;
System.out.println(max + ": " + time + " seconds");
max++;
}
System.out.println("DONE");
}
}
It seems to work so far in checking whether 3, then 4, 5, etc. points will guarantee a single color triangle, but its time complexity is ridiculous. For example, here are the times for 3-8 points:
3: 1.8475E-5 seconds
4: 2.59876E-4 seconds
5: 0.009313668 seconds
6: 0.192455789 seconds
7: 19.226652708 seconds
Based on the trend, 8 points will take 30 min to 1 hr, 9 points will take roughly a few days, 10 will take over 6 months, and well... nobody wants to wait that long.
Any suggestions on how to make my program more time efficient?
Edit: Apparently the answer was 6. Not only was my code inefficient, it was just plain wrong. Also thanks for the suggestions everyone.
How do I prevent the same tic tac toe coordinate from being inputted by the user?
The user input is taken at the main method in the Game Class.
The tic tac toe cells with [x, y] coordinates ranging from (0-2) can be either:
0(_), 1 (X) or 2 (O)
Grid Class with alpha beta search tree pruning algorithm
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class Grid {
List<Cell> availableCells;
int[][] board = new int[3][3];
Scanner scan = new Scanner(System.in);
// Set limit to search tree depth
int treeDepth = 9;
List<CellsAndScores> rootsChildrenScore = new ArrayList<>();
public int score() {
int score = 0;
// Check all columns
for (int j = 0; j < 3; ++j) {
int X = 0;
int O = 0;
for (int i = 0; i < 3; ++i) {
if (board[i][j] == 0) {
} else if (board[i][j] == 1) {
X++;
} else {
O++;
}
}
score += changeInScore(X, O);
}
// Check all rows
for (int i = 0; i < 3; ++i) {
int X = 0;
int O = 0;
for (int j = 0; j < 3; ++j) {
if (board[i][j] == 0) {
} else if (board[i][j] == 1) {
X++;
} else {
O++;
}
}
score += changeInScore(X, O);
}
int X = 0;
int O = 0;
// Check diagonal (first)
for (int i = 0, j = 0; i < 3; ++i, ++j) {
if (board[i][j] == 1) {
X++;
} else if (board[i][j] == 2) {
O++;
} else {
}
}
score += changeInScore(X, O);
X = 0;
O = 0;
// Check Diagonal (Second)
for (int i = 2, j = 0; i > -1; --i, ++j) {
if (board[i][j] == 1) {
X++;
} else if (board[i][j] == 2) {
O++;
} else {
}
}
score += changeInScore(X, O);
return score;
}
private int changeInScore(int X, int O) {
int change;
if (X == 3) {
change = 100;
} else if (X == 2 && O == 0) {
change = 10;
} else if (X == 1 && O == 0) {
change = 1;
} else if (O == 3) {
change = -100;
} else if (O == 2 && X == 0) {
change = -10;
} else if (O == 1 && X == 0) {
change = -1;
} else {
change = 0;
}
return change;
}
public int alphaBetaMinimax(int alpha, int beta, int depth, int turn) {
if (beta <= alpha) {
System.out.println("Pruning at tree depth = " + depth + " alpha: " + alpha + " beta: " + beta);
if (turn == 1)
return Integer.MAX_VALUE;
else
return Integer.MIN_VALUE;
}
if (depth == treeDepth || gameOver()) {
return score();
}
List<Cell> cellsAvailable = getAvailableStates();
if (cellsAvailable.isEmpty()) {
return 0;
}
if (depth == 0) {
rootsChildrenScore.clear();
}
int maxValue = Integer.MIN_VALUE, minValue = Integer.MAX_VALUE;
for (int i = 0; i < cellsAvailable.size(); ++i) {
Cell cell = cellsAvailable.get(i);
int currentScore = 0;
if (turn == 1) {
placeAMove(cell, 1);
currentScore = alphaBetaMinimax(alpha, beta, depth + 1, 2);
maxValue = Math.max(maxValue, currentScore);
// Set alpha
alpha = Math.max(currentScore, alpha);
if (depth == 0) {
rootsChildrenScore.add(new CellsAndScores(currentScore, cell));
}
} else if (turn == 2) {
placeAMove(cell, 2);
currentScore = alphaBetaMinimax(alpha, beta, depth + 1, 1);
minValue = Math.min(minValue, currentScore);
// Set beta
beta = Math.min(currentScore, beta);
}
// reset board
board[cell.x][cell.y] = 0;
// Do not evaluate the rest of the branches after search tree is pruned
if (currentScore == Integer.MAX_VALUE || currentScore == Integer.MIN_VALUE)
break;
}
return turn == 1 ? maxValue : minValue;
}
public boolean gameOver() {
// Game is over is someone has won, or board is full (draw)
return (hasXWon() || hasOWon() || getAvailableStates().isEmpty());
}
public boolean hasXWon() {
if ((board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] == 1)
|| (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] == 1)) {
// System.out.println("X Diagonal Win");
return true;
}
for (int i = 0; i < 3; ++i) {
if (((board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] == 1)
|| (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] == 1))) {
// System.out.println("X Row or Column win");
return true;
}
}
return false;
}
public boolean hasOWon() {
if ((board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] == 2)
|| (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] == 2)) {
// System.out.println("O Diagonal Win");
return true;
}
for (int i = 0; i < 3; ++i) {
if ((board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] == 2)
|| (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] == 2)) {
// System.out.println("O Row or Column win");
return true;
}
}
return false;
}
public List<Cell> getAvailableStates() {
availableCells = new ArrayList<>();
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (board[i][j] == 0) {
availableCells.add(new Cell(i, j));
}
}
}
return availableCells;
}
public void placeAMove(Cell Cell, int player) {
board[Cell.x][Cell.y] = player; // player = 1 for X, 2 for O
}
public Cell returnBestMove() {
int MAX = -100000;
int best = -1;
for (int i = 0; i < rootsChildrenScore.size(); ++i) {
if (MAX < rootsChildrenScore.get(i).score) {
MAX = rootsChildrenScore.get(i).score;
best = i;
}
}
return rootsChildrenScore.get(best).cell;
}
public void displayBoard() {
System.out.println();
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (board[i][j] == 0)
System.out.print("_" + " ");
if (board[i][j] == 1)
System.out.print("X" + " ");
if (board[i][j] == 2)
System.out.print("O" + " ");
}
System.out.println("");
}
System.out.println();
}
public void resetGrid() {
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
board[i][j] = 0;
}
}
}
}
Cell class
class Cell {
int x, y;
public Cell(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return "[" + x + ", " + y + "]";
}
}
class CellsAndScores {
int score;
Cell cell;
CellsAndScores(int score, Cell cell) {
this.score = score;
this.cell = cell;
}
}
Game Class with main method - takes user input
import java.util.Random;
public class Game {
public static void main(String[] args) {
Grid grid = new Grid();
Random random = new Random();
grid.displayBoard();
System.out.print("Who moves first? [1]Computer(X) [2]User(O): ");
int turn = grid.scan.nextInt();
if (turn == 1) {
Cell p = new Cell(random.nextInt(3), random.nextInt(3));
grid.placeAMove(p, 1);
grid.displayBoard();
}
while (!grid.gameOver()) {
int x = 0, y = 0;
System.out.print("Please enter an x coordinate [0-2]: ");
x = grid.scan.nextInt();
System.out.print("Please enter an y coordinate [0-2]: ");
y = grid.scan.nextInt();
Cell userMove = new Cell(y, x);
grid.placeAMove(userMove, 2); // 2 for O and O is the user
grid.displayBoard();
if (grid.gameOver())
break;
grid.alphaBetaMinimax(Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 1);
for (CellsAndScores pas : grid.rootsChildrenScore)
System.out.println("Cell: " + pas.cell + " Score: " + pas.score);
grid.placeAMove(grid.returnBestMove(), 1);
grid.displayBoard();
}
if (grid.hasXWon()) {
System.out.println("Unfortunately, you lost!");
grid.resetGrid();
} else if (grid.hasOWon()) {
System.out.println("You win!");
grid.resetGrid();
} else {
System.out.println("It's a draw!");
grid.resetGrid();
}
}
}
My answer would be to add a boolean check method into your Grid.java class and then in your main method - call this boolean check method before the placeAMove() method.
For example, in your Grid.java class, adding the following method:
/*
* Return true if space is ok to use.
*/
public boolean isMoveOK(Cell cell) {
return board[cell.x][cell.y] == 0;
}
This way, using your pre-existing 0/1/2 values that keep track of empty/X/O space values, you may provide a check to see if the space value is zero or not.
This would be one way to use it in your main method, to answer your question of, 'How do I prevent the same tic tac toe coordinate from being inputted by the user?'
Cell userMove = new Cell(y, x);
if (grid.isMoveOK(userMove)) {
grid.placeAMove(userMove, 2); // 2 for O and O is the user
} else {
System.out.println("Please try a different space/cell");
continue;
}
grid.displayBoard();
if (grid.gameOver())
break;
In this way, I am skipping the remaining loop code in your main method loop, until there's a valid open space. (When there is, then the program should proceed to check for winning values or whether to proceed playing)
Hope this answers your question! :)
Cheers
The purpose of the program is to generate a two-dimensional grid array made of periods ( . ). The user designates a starting point for the 'walker' which is marked by 'A', and then the walker will generate numbers from 0-3 to represent the four cardinal directions. It will move in these random directions while incrementing the alphabet with each mark it leaves until it either runs in to the wall and is "arrested" or reaches 'Z' at which it "made it home". If it runs in to a space it has already been to, it has to jump ahead in the same direction until it reaches an empty space or hits the wall.
My problem now is that I have it on a counter to make sure it doesn't run past 'Z', and will "make it home" if it reaches that point. But even the movements that it is taking to avoid overwriting where it has already been are registering on the counter (which they shouldn't be), so its returning true even though it hasn't hit Z yet, and its also still calling my random number generator so its not keeping to the same direction when it tries to correct itself. It also seems to be occasionally even jumping over empty spaces.
The problem is in processing()
package walktester;
import java.lang.Math;
import java.util.Random;
import java.util.Scanner;
class DrunkWalker {
private char[][] walkgrid = new char[10][10];
private static int randNSEW;
private int randomnum;
private int startrow;
private int startcol;
private char alpha = 'A';
private int nextrow;
private int nextcol;
public DrunkWalker(int r, int c) {
startrow = r;
startcol = c;
nextrow = startrow;
nextcol = startcol;
for (int i = 0; i < 10; i ++) {
for (int j = 0; j < 10; j++)
walkgrid[i][j] = '.';
}
walkgrid[r][c] = alpha++;
}
public static void getRand(){
int x100 = 0;
double randomNum = 0.0;
randomNum = Math.random();
x100 = (int) (randomNum * 100);
randNSEW = x100 % 4;
}
public int getNextRow(){
return nextrow;
}
public int getNextCol(){
return nextcol;
}
public boolean processing(){
for(int i = 1; i < 26; i ++){
getRand();
if(randNSEW == 0){
nextcol--;
}
if(randNSEW == 1){
nextrow++;
}
if(randNSEW == 2){
nextcol++;
}
if(randNSEW == 3){
nextrow--;
}
if(nextrow < 0 || nextrow >= 10 || nextcol < 0 || nextcol >= 10) {
return false;
}
if(randNSEW == 0 && walkgrid[nextrow][nextcol] != '.'){
nextcol--;
continue;
}
if(randNSEW == 1 && walkgrid[nextrow][nextcol] != '.'){
nextrow++;
continue;
}
if(randNSEW == 2 && walkgrid[nextrow][nextcol] != '.'){
nextcol++;
continue;
}
if(randNSEW == 3 && walkgrid[nextrow][nextcol] != '.'){
nextrow--;
continue;
}
walkgrid[nextrow][nextcol] = alpha++;
}
return true;
}
public char[][] DisplayGrid() {
for(int y = 0; y < 10; y++) {
for(int x = 0; x < 10; x++) {
System.out.print(walkgrid[x][y] + " ");
}
System.out.println();
}
return walkgrid;
}
}
public class WalkTester {
public static void main(String[] args) {
Scanner inpr = new Scanner(System.in);
Scanner inpc = new Scanner(System.in);
Scanner inpchoice = new Scanner(System.in);
int r = 0;
int c = 0;
char choice = 'y';
while(choice == 'y' || choice == 'Y') {
System.out.println("Please enter x coordinate between 1 and 10.");
r = inpr.nextInt();
r = r - 1;
System.out.println("Please enter y coordinate between 1 and 10");
c = inpr.nextInt();
c = c - 1;
if(r < 0 || r > 9 || c < 0 || c > 9){
System.out.println("Invalid Entry. Restart? y/n");
choice = inpchoice.next().charAt(0);
if(choice == 'y' || choice == 'Y'){
continue;
}
else if(choice == 'n' || choice == 'N'){
return;
}
else{
System.out.println("Invalid Entry. Restart? y/n");
choice = inpchoice.next().charAt(0);
}
}
DrunkWalker drunkwalker = new DrunkWalker(r, c);
boolean walkerSucceeded = drunkwalker.processing();
drunkwalker.DisplayGrid();
if(walkerSucceeded) {
System.out.println("You made it home");
} else {
System.out.println("You were arrested");
}
System.out.println("Restart? y/n");
choice = inpchoice.next().charAt(0);
if(choice == 'y' || choice == 'Y'){
continue;
}
else if(choice == 'n' || choice == 'N'){
return;
}
else{
System.out.println("Invalid Entry. Restart? y/n");
choice = inpchoice.next().charAt(0);
}
}
}
}
The following code fixes your problems. You basically did not have 'state' distinguishing a valid move, vs. moving to 'jump' over past visit points. I tried to keep the code as close as possible to your existing code.
class DrunkWalker {
private char[][] walkgrid = new char[10][10];
private static int randNSEW;
private int randomnum;
private int startrow;
private int startcol;
private char alpha = 'A';
private int nextrow;
private int nextcol;
public DrunkWalker(int r, int c) {
startrow = r;
startcol = c;
nextrow = startrow;
nextcol = startcol;
for (int i = 0; i < 10; i ++) {
for (int j = 0; j < 10; j++)
walkgrid[i][j] = '.';
}
walkgrid[r][c] = alpha++;
}
public static void getRand(){
int x100 = 0;
double randomNum = 0.0;
randomNum = Math.random();
x100 = (int) (randomNum * 100);
randNSEW = x100 % 4;
}
public int getNextRow(){
return nextrow;
}
public int getNextCol(){
return nextcol;
}
enum Mode {WALKING, CORRECTING};
Mode mode = Mode.WALKING;
public boolean processing(){
for(int i = 1; i < 26; i ++){
if (mode == Mode.WALKING) {
getRand();
if(randNSEW == 0){
nextcol--;
}
if(randNSEW == 1){
nextrow++;
}
if(randNSEW == 2){
nextcol++;
}
if(randNSEW == 3){
nextrow--;
}
}
if(nextrow < 0 || nextrow >= 10 || nextcol < 0 || nextcol >= 10) {
return false;
}
if(randNSEW == 0 && walkgrid[nextrow][nextcol] != '.'){
i--;
nextcol--;
mode = Mode.CORRECTING;
continue;
}
if(randNSEW == 1 && walkgrid[nextrow][nextcol] != '.'){
i--;
nextrow++;
mode = Mode.CORRECTING;
continue;
}
if(randNSEW == 2 && walkgrid[nextrow][nextcol] != '.'){
i--;
nextcol++;
mode = Mode.CORRECTING;
continue;
}
if(randNSEW == 3 && walkgrid[nextrow][nextcol] != '.'){
i--;
nextrow--;
mode = Mode.CORRECTING;
continue;
}
mode = Mode.WALKING;
walkgrid[nextrow][nextcol] = alpha++;
}
return true;
}
The purpose of this program is to build a 10x10 array grid made out of periods (.), allow the user to designate a starting point, and then the program will randomly choose numbers which are assigned to directions for the 'walker' to go. Each time it moves it marks its spot with the next letter in the alphabet (the starting point is marked by A). If the walker crosses out of the bounds of the array (AKA > 10 or < 0) it will say "you were arrested" and if the variable alpha == 'Z' it way say "You made it home".
The only thing I have left to do is make it so that if the walker tries to go back to a spot it has already been to, it will skip to the next space until it reaches a space it hasn't been.
package walktester;
import java.lang.Math;
import java.util.Random;
import java.util.Scanner;
class DrunkWalker {
private char[][] walkgrid = new char[10][10];
private static int randNSEW;
private int randomnum;
private int startrow;
private int startcol;
private char alpha = 'A';
private int nextrow;
private int nextcol;
public DrunkWalker(int r, int c) {
startrow = r;
startcol = c;
nextrow = startrow;
nextcol = startcol;
for (int i = 0; i < 10; i ++) {
for (int j = 0; j < 10; j++)
walkgrid[i][j] = '.';
}
walkgrid[r][c] = alpha++;
}
public static void getRand(){
int x100 = 0;
double randomNum = 0.0;
randomNum = Math.random();
x100 = (int) (randomNum * 100);
randNSEW = x100 % 4;
}
public int getNextRow(){
return nextrow;
}
public int getNextCol(){
return nextcol;
}
public boolean processing(){
for(int i = 0; i < 25; i ++){
getRand();
if(randNSEW == 0){
nextcol--;
}
if(randNSEW == 1){
nextrow++;
}
if(randNSEW == 2){
nextcol++;
}
if(randNSEW == 3){
nextrow--;
}
if(nextrow < 0 || nextrow >= 10 || nextcol < 0 || nextcol >= 10) {
return false;
}
walkgrid[nextrow][nextcol] = alpha++;
}
return true;
}
public char[][] DisplayGrid() {
for(int y = 0; y < 10; y++) {
for(int x = 0; x < 10; x++) {
System.out.print(walkgrid[x][y] + " ");
}
System.out.println();
}
return walkgrid;
}
}
public class WalkTester {
public static void main(String[] args) {
Scanner inpr = new Scanner(System.in);
Scanner inpc = new Scanner(System.in);
Scanner inpchoice = new Scanner(System.in);
int r = 0;
int c = 0;
char choice = 'y';
while(choice == 'y' || choice == 'Y') {
System.out.println("Please enter x coordinate between 1 and 10.");
r = inpr.nextInt();
r = r - 1;
System.out.println("Please enter y coordinate between 1 and 10");
c = inpr.nextInt();
c = c - 1;
if(r < 0 || r > 9 || c < 0 || c > 9){
System.out.println("Invalid Entry. Restart? y/n");
choice = inpchoice.next().charAt(0);
if(choice == 'y' || choice == 'Y'){
continue;
}
else if(choice == 'n' || choice == 'N'){
return;
}
else{
System.out.println("Invalid Entry. Restart? y/n");
choice = inpchoice.next().charAt(0);
}
}
DrunkWalker drunkwalker = new DrunkWalker(r, c);
boolean walkerSucceeded = drunkwalker.processing();
drunkwalker.DisplayGrid();
if(walkerSucceeded) {
System.out.println("You made it home");
} else {
System.out.println("You were arrested");
}
System.out.println("Restart? y/n");
choice = inpchoice.next().charAt(0);
if(choice == 'y' || choice == 'Y'){
continue;
}
else if(choice == 'n' || choice == 'N'){
return;
}
else{
System.out.println("Invalid Entry. Restart? y/n");
choice = inpchoice.next().charAt(0);
}
}
}
}
By "skip to the next space until it reaches a space" I assume you mean they continue on in the same direction.
So, just before you do:
walkgrid[nextrow][nextcol] = alpha++;
you need to check:
if (walkgrid[nextrow][nextcol] == '.')
so something along these lines:
...
do {
if (randNSEW == 0) nextcol--;
if (randNSEW == 1) nextrow++;
if (randNSEW == 2) nextcol++;
if (randNSEW == 3) nextrow--;
if ((nextrow < 0) || (nextrow >= 10) || (nextcol < 0) || (nextcol >= 10)) {
return false;
}
if (walkgrid[nextrow][nextcol] == '.') continue; /* try next */
walkgrid[nextrow][nextcol] = alpha++;
} while (false);
Or we could rewrite those last three lines as:
} while (walkgrid[nextrow][nextcol] == '.');
walkgrid[nextrow][nextcol] = alpha++;