I'm trying to write a simple game in Java that creates a grid of dots using a 2d array for the user to move on. I've done that and I've gotten to the point where I'm asking the user for their movement selection, however, after that happens I want to reprint the grid with their old space empty, and with the 'o' in the space they moved to. I'm unsure how to go about reprinting the grid though, as when I first printed it I used an if statement to tell the loop where to not put dots. I'll post the code below, tips are greatly appreciated!
import java.util.Scanner;
import java.util.Random;
public class main {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
char[][] gridArray = new char[10][10];
int randomRow;
int randomCol;
int randomRow2;
int randomCol2;
String moveSelect;
boolean validInput = true;
int min = 0;
int max = 9;
Random tRNG = new Random();
randomRow = tRNG.nextInt(max - min + 1) + min;
randomCol = tRNG.nextInt(max - min + 1) + min;
randomRow2 = tRNG.nextInt(max - min + 1) + min;
randomCol2 = tRNG.nextInt(max - min + 1) + min;
gridArray[randomRow][randomCol] = 'o';
gridArray[randomRow2][randomCol2] = 'X';
for (int i = 0; i < gridArray.length; i++)
{
for (int j = 0; j < gridArray.length; j++)
{
if (gridArray[i][j] != gridArray[randomRow][randomCol] && gridArray[i][j] != gridArray[randomRow2][randomCol2])
{
gridArray[i][j] = '.';
}
System.out.print(gridArray[i][j]);
}
System.out.println("");
}
System.out.println("Enter a movement choice W A S or D");
do{
Scanner keyboard = new Scanner(System.in);
moveSelect = keyboard.nextLine();
if ( moveSelect.equals("w"))
{
gridArray[randomRow][randomCol] = gridArray[randomRow+1][randomCol];
gridArray[randomRow][randomCol] = ' ';
validInput = true;
}
else if ( moveSelect.equals("a"))
{
gridArray[randomRow][randomCol] = gridArray[randomRow][randomCol-1];
gridArray[randomRow][randomCol] = ' ';
validInput = true;
}
else if ( moveSelect.equals("s"))
{
gridArray[randomRow][randomCol] = gridArray[randomRow-1][randomCol];
gridArray[randomRow][randomCol] = ' ';
validInput = true;
}
else if (moveSelect.equals("d"))
{
gridArray[randomRow][randomCol] = gridArray[randomRow][randomCol+1];
gridArray[randomRow][randomCol] = ' ';
validInput = true;
}
else
{
System.out.println("Invalid Entry. Try again.");
validInput = false;
}
} while (validInput == false);
}
}
I think most of the problems come from general confusion about arrays. E.g. the line from the code block run when you press w:
gridArray[randomRow][randomCol] = gridArray[randomRow+1][randomCol];
sets the char value of the array at randomRow, randomCol (in this case an 'x') to the char value of the of the array space one row below it at randomRow+1, randomCol. And then the line of code after that:
gridArray[randomRow][randomCol] = ' ';
assigns a new value to that same space making the code above worthless! And in the end, randomRow and randomCol are never modified. (also you had some confusion about which way the x would move with a higher row value)
all you actually need to do in this code block is:
randomRow -= 1;
after this, you can simply reprint the whole grid with the printing code from before. Although there are other issues with this code that make it far from optimal. Also there are a similar problem in that if statement in the for loop that worked but led to problems later down the road. Simply rewriting it to fix all the things wrong, you get this:
char[][] gridArray = new char[10][10];
int randomRow;
int randomCol;
int randomRow2;
int randomCol2;
String moveSelect;
boolean validInput = true;
int min = 0;
int max = 9;
Random tRNG = new Random();
randomRow = tRNG.nextInt(max - min + 1) + min;
randomCol = tRNG.nextInt(max - min + 1) + min;
randomRow2 = tRNG.nextInt(max - min + 1) + min;
randomCol2 = tRNG.nextInt(max - min + 1) + min;
gridArray[randomRow][randomCol] = 'o';
gridArray[randomRow2][randomCol2] = 'X';
for (int i = 0; i < gridArray.length; i++)
{
for (int j = 0; j < gridArray.length; j++)
{
if (!((i == randomRow && j == randomCol) || (i == randomRow2 && j == randomCol2)))
{
gridArray[i][j] = '.';
}
System.out.print(gridArray[i][j]);
}
System.out.println("");
}
System.out.println("Enter a movement choice W A S or D");
do{
Scanner keyboard = new Scanner(System.in);
moveSelect = keyboard.nextLine();
if ( moveSelect.equals("w"))
{
randomRow -= 1;
validInput = true;
}
else if ( moveSelect.equals("a"))
{
randomCol -= 1;
validInput = true;
}
else if ( moveSelect.equals("s"))
{
randomRow += 1;
validInput = true;
}
else if (moveSelect.equals("d"))
{
randomCol -= 1;
validInput = true;
}
else
{
System.out.println("Invalid Entry. Try again.");
validInput = false;
}
} while (validInput == false);
gridArray[randomRow][randomCol] = 'o';
gridArray[randomRow2][randomCol2] = 'X';
for (int i = 0; i < gridArray.length; i++)
{
for (int j = 0; j < gridArray.length; j++)
{
if (!((i == randomRow && j == randomCol) || (i == randomRow2 && j == randomCol2)))
{
gridArray[i][j] = '.';
}
System.out.print(gridArray[i][j]);
}
System.out.println("");
}
Make a method to print the grid if validInput==true
public static void printGrid(char[][]gridArray){
for (int i = 0; i < gridArray.length; i++)
{
for (int j = 0; j < gridArray.length; j++)
{
System.out.print(gridArray[i][j]);
}
System.out.println("");
}
}
I modified your gridArray[randomRow][randomCol] from =' ' to ='.' because you want it to be a dot right? (If you actually want it to be a space, just leave it like it already is)
For validation, change each of the directions to things like:
if ( moveSelect.equals("w")&&randomRow!=0)
{
gridArray[randomRow][randomCol] = gridArray[randomRow-1][randomCol];
gridArray[randomRow][randomCol] = '.';
validInput = true;
}
At the end of the do,
if(validInput) printGrid(gridArray);
Related
I am solving this problem on code forces.
https://codeforces.com/contest/1675/problem/B
The break statement I have doesn't break out of the while loop.
When I use this input:
It outputs -1 one twice in the same case, which shows that the break statement isn't taking me outside the loop?
Why is this happening?
public class vanita {
public static void main (String[]args) {
Scanner in = new Scanner(System.in);
int cases = in.nextInt();
for (int i = 0; i < cases; i++) {
boolean test = true;
int arrLength = in.nextInt();
int arr[] = new int[arrLength];
for (int j = 0; j < arrLength; j++) {
arr[j] = in.nextInt();
}
int operations = 0;
int after;
for (int j = arrLength-1; j >= 1 ; j--){
after = arr[j-1];
while (arr[j] <= after) {
arr[j-1] = (int)Math.floor(arr[j-1]/2);
after = arr[j-1];
operations++;
if (arr[j] == 0 && arr[j-1] == 0) {
//System.out.println("current: " + arr[j]);
//System.out.println("after: " + arr[j-1]);
//System.out.println("Case " + i);
System.out.println("-1");
test = false;
break;
}
}
}
for (int s = 0; s < arrLength; s++) {
//System.out.print(arr[s] + " ");
}
//System.out.println(" ");
if (test == true) {
System.out.println(operations);
}
}
}
}
i think it breaks out of the inner while loop, but not the outer for loop. So the inner while loop runs multiple times.
Problems
Normally a break; will always break out of the most recent loop. If you can't break out of your loop, the problem is your algorithm or your condition.
Solutions
First, always debug to see if you enter your if statement.
Second, use something else as condition of your while loop. You could use a boolean and change its value to break the while condition. Ex:
boolean hasFoundDuplicate = false;
while(!hasFoundDuplicate){
arr[j-1] = (int)Math.floor(arr[j-1]/2);
after = arr[j-1];
operations++;
if(arr[j] == 0 && arr[j-1] == 0){
hasFoundDuplicate = true;
}
}
I am working on solution for the CCC 2018 Robo Thieves Problem, it a simplified version of the original problem. My problem is that it will give me this "Index 5 out of bounds for length 5" when I executed my code and I'm not sure why it is happening. Half of my program executes and then this error occurs.
import java.util.*;
public class RoboThieves {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
ArrayList<Integer> rowPos = new ArrayList<Integer>();
ArrayList<Integer> colPos = new ArrayList<Integer>();
int sRow = -1; // robot pos
int sCol = -1;
int dotCounter = 0;
int stepCounter = 0;
int rowSize = sc.nextInt();
int colSize = sc.nextInt();
char[][] factoryGrid = new char[rowSize][colSize];
for (int i = 0; i < rowSize; i++) {
String rowChars = sc.next().toUpperCase();
for (int j = 0; j < colSize; j++) {
factoryGrid[i][j] = rowChars.charAt(j);
}
}
// check to see if the grid was inputted properly (with square brackets)
/*
* for (char [] row: factoryGrid) { System.out.println(Arrays.toString(row)); }
*/
// check to see if the grid was inputted properly (as inputted)
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
System.out.print(factoryGrid[i][j]);
}
System.out.println();
}
// locate dots and store their row and col in arraylists
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
if (factoryGrid[i][j] == '.') {
rowPos.add(i);
colPos.add(j);
dotCounter++;
}
}
}
// print dot location to check
for (int i = 0; i < rowPos.size(); i++) {
System.out.println("Dot Position = " + "(" + rowPos.get(i) + "," + colPos.get(i) + ")");
}
// locate robot position
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
if (factoryGrid[i][j] == 'S')
sRow = i;
sCol = j;
}
}
// print camera location to check
System.out.println("Camera Position = " + "(" + sRow + "," + sCol + ")");
//System.out.println(dotCounter); // test to see if counter works
char above = getAbove(factoryGrid, sRow, sCol);
char right = getRight(factoryGrid, sRow, sCol);
char below = getBelow(factoryGrid, sRow, sCol);
char left = getLeft(factoryGrid, sRow, sCol);
if (above == '.') {
boolean canMove = check360(factoryGrid, sRow, sCol);
// check if camera is around dot
if (canMove == true) {
// set robot position to dot position and old position to W
sRow = sRow - 1;
// sCol = sCol;
factoryGrid[sRow][sCol] = 'W';
dotCounter--;
stepCounter++;
} else {
// this is if there is a camera in the 360 radius of the open space
System.out.println("You cannot move to the space beside because there is a camera in your sightline!");
}
} else if (right == '.') {
boolean canMove = check360(factoryGrid, sRow, sCol);
// check if camera is around dot
if (canMove == true) {
// set robot position to dot position and old position to W
// sRow = sRow;
sCol = sCol + 1;
factoryGrid[sRow][sCol] = 'W';
dotCounter--;
stepCounter++;
} else {
// this is if there is a camera in the 360 radius of the open space
System.out.println("You cannot move to the space beside because there is a camera in your sightline!");
}
} else if (below == '.') {
boolean canMove = check360(factoryGrid, sRow, sCol);
// check if camera is around dot
if (canMove == true) {
// set robot position to dot position and old position to W
sRow = sRow + 1;
// sCol = sCol;
factoryGrid[sRow][sCol] = 'W';
dotCounter--;
stepCounter++;
} else {
// this is if there is a camera in the 360 radius of the open space
System.out.println("You cannot move to the space beside because there is a camera in your sightline!");
}
} else if (left == '.') {
boolean canMove = check360(factoryGrid, sRow, sCol);
// check if camera is around dot
if (canMove == true) {
// set robot position to dot position and old position to W
// sRow = sRow;
sCol = sCol - 1;
factoryGrid[sRow][sCol] = 'W';
dotCounter--;
stepCounter++;
} else {
// this is if there is a camera in the 360 radius of the open space
System.out.println("You cannot move to the space beside because there is a camera in your sightline!");
}
} else {
System.out.println(
"The robot cannot move to any spaces try inputting a factory layout that can produce an answer.");
} // end if above dot (yes)
System.out.println(stepCounter);
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
System.out.print(factoryGrid[i][j]);
}
System.out.println();
}
} // end main method
public static char getLeft(char[][] factGrid, int cRow, int cCol) {
return factGrid[cRow][(cCol - 1)];
}
public static char getAbove(char[][] factGrid, int cRow, int cCol) {
return factGrid[(cRow - 1)][(cCol)];
}
public static char getBelow(char[][] factGrid, int cRow, int cCol) {
return factGrid[cRow + 1][cCol];
}
public static char getRight(char[][] factGrid, int cRow, int cCol) {
return factGrid[cRow][(cCol + 1)];
}
public static boolean check360(char[][] factGrid, int cRow, int cCol) {
boolean canMove = true;
char left = getLeft(factGrid, cRow, cCol);
char above = getAbove(factGrid, cRow, cCol);
char right = getRight(factGrid, cRow, cCol);
char below = getBelow(factGrid, cRow, cCol);
if (left == 'C' || above == 'C' || right == 'C' || below == 'C') {
canMove = false;
}
return canMove;
}
} // end main program
Upon first look, I expect that the issue may lie in your getLeft(), getAbove(), getRight(), and getBelow() methods.
In these methods, you give it a value for cRow and cCol and add or subtract 1. However, you need to make sure that the index you are querying does not exceed the size of the double array factGrid, or go below 0.
For example, in your getRight() method, you might try:
public static char getRight(char[][] factGrid, int cRow, int cCol) {
if(factGrid[0].length > (cCol + 1)) {
return factGrid[cRow][(cCol + 1)];
} else {
return '';
}
}
import java.util.*;
public class TicTacToe {
public static char X = 'X';
public static char O = 'O';
public static char S = ' ';
public static char[][] board = new char[3][3];
public static boolean isFull = false, win = false;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int c,r;
for(r=0;r<board.length;r++){
for(c=0;c<board[r].length;c++)
board[r][c] = ' ';
}
System.out.println("Player 1: X");
System.out.println("Player 2: O");
printBoard(board);
for(int i = 0; i <9 && win==false;i++){
if(i%2==0){
do {
System.out.print("Player 1: Enter your next move:(r,c) ");
r = in.nextInt();
c = in.nextInt();
if(r>board.length || c>board.length || r<0 || c<0)
System.out.println("Error, try again ");
if(board[r][c]==X || board[r][c]==O){
isFull=true;
System.out.println("This square is already taken, Player 1, try again");
}
if(board[r][c]==S){
isFull=false;
board[r][c] = X;
checkWin(board);
printBoard(board);
}
}while(isFull);
}
else{
do{
System.out.print("Enter your next move:(r,c) ");
r = in.nextInt();
c = in.nextInt();
if(r>board.length || c>board.length || r<0 || c<0)
System.out.println("Error, try again ");
if(board[r][c]==X || board[r][c]==O){
isFull=true;
System.out.println("This square is already taken, Player 2, try again");
}
if(board[r][c]==S){
isFull=false;
board[r][c] = O;
checkWin(board);
printBoard(board);
}
}while(isFull);
}
if(win)
System.out.print("We have a winner");
}
}
public static boolean checkWin(char[][] b){
int r = 0,c = 0,countX = 0,countO = 0;
for(char i = board[r][c];r<3 && c<3;r++)
System.out.println(r);
if(board[r][c]==X)
countX++;
if(board[r][c]==O)
countO++;
if(countX==3 || countO==3)
return win = true;
if(countX<3 && countO<3 && r<3){
countX = 0;
countO = 0;
r = 0;
c++;
}
return win = false;
}
public static void printBoard(char[][] b){
int r = 0,c = 0;
System.out.println();
for(r=0;r<b.length;r++){
for(c=0;c<b[r].length-1;c++)
System.out.print(" " + b[r][c] + " |");
System.out.println(" "+b[r][c]);
if(r<b.length-1){
for(c=0;c < b[r].length-1;c++)
System.out.print("---+");
System.out.println("---");
}
}
}
}
When I try to check to see if there are three in a row, it throws an ArrayOutOfBoundsException on these lines.
if(board[r][c]==X)
countX++;
if(board[r][c]==O)
countO++;
I don't know why it would throw an Exception there, considering that i am just adding to three there.
The problem is in this for loop:
for(char i = board[r][c] ; r<3 && c<3 ; r++)
When you get to r = 3, r<3 && c<3 is still false and you try to access br[r][c], which is why you get an out of bounds exception.
I suggest that you use nested loops instead of having if statement to reset. But if you really want to go that route, this is a possible construct:
for(char i = board[r][c] ; c<3 ; r++) {
...
if(r == 2) {
r=0;
c++;
}
}
int r = 0, c = 0, countX = 0, countO = 0;
for (char i = board[r][c]; r < 3 && c < 3; r++)
System.out.println(r);
if (board[r][c] == X)
countX++;
In method, checkWin. There is a for loop. In which you are iterating rows from 0 to 3.
When loops get completed rows value goes to 3.
r++ works 3 times so value is 2 and 4th time value goes 3 and condition fails.
In next statement you are checking if as
if (board[r][c] == X)
In this you are using same r value which is currently 3, so there is no element at the position of 3,0. Therefore it gives ArrayIndexOutOfBoundException.
I'm working on this program where I need to verify if every odd index in a String has the letter "X". For example if my String is: AXFXTX then I should get a message: "GOOD", if not I should get a message: "BAD". Can anyone tell me what I'm missing please. Thank you in advanced.
Here's my code
import java.util.Random;
import java.util.Scanner;
public class Program {
public static void main(String[] args) {
Random rand = new Random();
Scanner scan = new Scanner(System.in);
int min = 1;
int max = 10;
int randomNum = rand.nextInt((max - min) + 1) + min;
System.out.println("Random number = " + randomNum);
System.out.print("Enter a word of " + randomNum + " characters:");
String myString = scan.nextLine();
while(myString.length() != randomNum){
System.out.print("Enter a word of " + randomNum + " characters:");
myString = scan.nextLine();
}
char[] c = myString.toCharArray();
for(int i = 0 ; i < c.length ; i++){
if(c[i] == 'X'){
System.out.println("GOOD!");
}
else{
System.out.println("BAD");
}
}
}
}
If I understand your question, then it's important to note that the first odd index is 1. So you can start at 3 and check if that, and every subsequent odd number (index += 2), is the same as the first. Something like,
boolean sameLetter = true;
for (int index = 3; index < c.length && sameLetter; index += 2) {
sameLetter = (c[1] == c[index]);
}
System.out.println(sameLetter ? "GOOD!" : "BAD");
Simply evaluate odd indices only:
char[] c = myString.toCharArray();
boolean good = true;
for(int i = 3 ; i < c.length ; i+=2){
if(c[i] != c[i-2]){
good = false;
break;
}
}
if(good) System.out.println("GOOD");
else System.out.println("BAD");
I would simply use a regular expression here
str.matches(".(\\w)(.\\1)+") //true is GOOD
Try
booelan allGood = true;
for(int i = 2 ; i < c.length ; i = i + 2){
if(c[i] != c[0]){
allGood = false;
break;
}
}
To start with, you need a boolean variable here to track if it's consistent across all characters. Second, you need to improve your loop
boolean testSucceed = true;
for(int i = 1 ; i < c.length ; i += 2){
if (c[i] != 'X') testSucceed = false;
break;
}
if(testSucceed){
System.out.println("GOOD!");
} else{
System.out.println("BAD");
}
Change the for loop to :
for(int i = 0 ; i < c.length ; i+=2)
so that it goes over alternate characters.
//If NOT divisible by 2- Check only ODD number
Edited: You are suppossed to use modulus % and not division %. My bad
for(int i = 0 ; i < c.length ; i++){
if(c[i]%2 != 0){
if(c[i] == 'X'){
System.out.println("GOOD!");
}
else{
System.out.println("BAD");
}
}
}
public class Palindrome
{
public static boolean isDoublePalindrome (char[] digits)
{
char[] firstHalf = new char[digits.length/2];
char[] secondHalf = new char[digits.length/2];
for(int a = 0; a < digits.length / 2; a++)
{
firstHalf[a] = digits[a];
System.out.print(firstHalf[a]);
}
for(int b = digits.length / 2; b < digits.length; b++)
{
secondHalf[b] = digits[b];
}
if(digits.length % 2 == 0)
{
for(int i = 0; i < digits.length / 2 - 1; i++)
{
if(digits[i] != digits[digits.length - i - 1])
{
return false;
}
else
{
return true;
}
}
for(int j = 0; j < firstHalf.length / 2 - 1; j++)
{
if(firstHalf[j] != firstHalf[digits.length - j - 1])
{
return false;
}
else
{
return true;
}
}
}
else if(digits.length % 2 != 0)
{
return false;
}
return false;
}
}
Here I take digits[] as parameter and whatever the character array in there I want to divide them into half and store first half into firstHalf and second half into secondHalf array. But when I debug, secondHalf doesn't have any values. Please help!!
method to do so
public int reverse(int num) {
int revNum = 0;
while (num > 0) {
int rem = num % 10;
revNum = (revNum * 10) + rem;
num = num / 10;
}
return revNum;
}
implementation
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter a number: ");
int num = scanner.nextInt();
System.out.println("Please enter a string: ");
String str = scanner.next();
Palindrome palin = new Palindrome();
int revNum = palin.reverse(num);
if (num == revNum) {
System.out.printf("\n The number %d is a Palindrome ", num);
} else {
System.out.printf("\n The number %d is not a Palindrome ", num);
}
here palindrome is class name of main method hope my works helps you in this regard.
First off, be careful dividing your array length by 2, you may have an odd length (making one half 1 longer than the other).
What happens if "digits" is an odd number length? It can still be a palindrome.
To answer your question, in the second loop your assigning values to secondHalf[b], which is past it's length: "digits.length / 2". You should be assigning values into secondHalf[] starting at zero.
If you're lazy, this could be your way:
public static boolean isPalindrome(String s){
String reverse = new StringBuffer(s).reverse().toString();
if(s.equalsIgnoreCase(reverse))
return true;
else
return false;
}
And if you are not allowed to cheat, this could help you:
public static boolean isPalindrome(String s){
char[] chars = s.toCharArray();
for(int i = 0; i < chars.length / 2; i++){
if(Character.toLowerCase(chars[i]) != Character.toLowerCase(chars[chars.length - 1 - i]))
return false;
}
return true;
}
EDIT: With the second version you also don't encounter the problem of overlooking a character, because if it is a odd number, it would be the middle character that both sides of the string share.