I am trying to solve a boggle word checker problem, I am almost there but I need some help with the logic.
Boggle word checker takes a 2d array and a string and I want to determine whether that string is a valid boggle word returning either true or false. So valid guesses are strings which can be formed by connecting adjacent cells (horizontally, vertically, or diagonally) without re-using any previously used cells.
For example EAR is correct but EARS is not.
From what I can tell, it seems to work properly until it gets to the last letter and then I am having issues with it returning correctly T/F. I tried using an if statement so that it would stop the recursive call but it doesn't seem to be working. Any advice on how to figure it out would be amazing!
final private static char[][] board = {
{'E','A','R','A'},
{'N','L','E','C'},
{'I','A','I','S'},
{'B','Y','O','R'}
}
public class Boggle {
char[][] board;
String word;
public Boggle(final char[][] board, final String word) {
this.board = board;
this.word = word;
}
public boolean checkit() {
//make string array
//iterated through board
//if word[0] == board value
//check -> see if value above beloow left right is a match to word[1]
System.out.println("word: "+word);
char[] charArr = word.toCharArray();
int index = 0;
boolean valid = false;
for(int row=0; row< board.length; row++) {
for(int col=0; col<board[0].length; col++) {
if(board[row][col] == charArr[index]) {
return check(board, charArr, row, col, index);
}
}
}
return valid;
}
public boolean check(char[][] board, char[] charArr, int row, int col, int index) {
index++;
//while index< charArr.length, keep searching for matches
System.out.println("index: "+index + " chararr.length: "+charArr.length);
if(index >= charArr.length) return true;
else if(index < charArr.length) {
System.out.println("here");
//check up
if(row-1 >= 0) {
if(board[row-1][col] == charArr[index]) {
check(board, charArr, row-1, col, index);
}
}
//check up/right (diagonal)
else if((row-1 >= 0) && (col+1 < board[0].length)) {
if(board[row-1][col+1] == charArr[index]) {
check(board, charArr, row-1, col+1, index);
}
}
//check right
else if(col+1 < board[0].length) {
if(board[row][col+1] == charArr[index]) {
System.out.println("right");
check(board, charArr, row, col+1, index);
}
}
//check right/down (diagonal)
else if((col+1 < board[0].length) && (row+1 < board.length)) {
if(board[row+1][col+1] == charArr[index]) {
check(board, charArr, row+1, col+1, index);
}
}
//check down
else if(row+1 < board.length) {
if(board[row+1][col] == charArr[index]) {
check(board, charArr, row+1, col, index);
}
}
//check down/left (diagonal)
else if((col-1 >= 0) && (row+1 < board.length)) {
if(board[row+1][col-1] == charArr[index]) {
check(board, charArr, row+1, col-1, index);
}
}
//check left
else if(col-1 >= 0) {
if(board[row][col-1] == charArr[index]) {
check(board, charArr, row, col-1, index);
}
}
//check left/up (diagonal)
else if((col-1 >= 0) && (row-1 >= 0)) {
if(board[row-1][col-1] == charArr[index]) {
check(board, charArr, row-1, col-1, index);
}
}
//no match
System.out.println("false section");
return false;
} //end while
return false;
}
}
Problems I see include:
You don't look at the return result of check().
You allow a word to use the same letter twice.
The following code is redundant.
if(index >= charArr.length) return true;
else if(index < charArr.length) {
If it gets past the first line, we know the condition must pass, so there is no need to check it again.
Related
I am trying to make an algorithm that finds a path for a maze and prints out the failed paths as well. The output should look like this:
Where # is a wall, * is a failed path, and # is a working path to the end of the maze
My pathfinding method is not completely finding all the paths:
public boolean findPath(int row, int col) {
if (maze.get(row)[col] == 'E'){
return true;
}
if (maze.get(row)[col] == '#' || maze.get(row)[col] == '*') {
return false;
}
else {
if (maze.get(row)[col] != 'S'){
maze.get(row)[col] = '*';
}
if (col - 1 >= 0){
if (findPath(row, col - 1)) {
maze.get(row)[col] = '#';
return true;
}
}
if (row - 1 >= 0){
if (findPath(row - 1, col)) {
maze.get(row)[col] = '#';
return true;
}
}
if (row + 1 < maze.size()){
if (findPath(row + 1, col)) {
maze.get(row)[col] = '#';
return true;
}
}
if (col + 1 < maze.get(row).length) {
if (findPath(row, col + 1)) {
maze.get(row)[col] = '#';
return true;
}
}
}
return false;
}
Attached is the output, where not all #'s are placed and some are not true. Also, it overrides the start point. Any solutions?
I am trying to build a treasure hunt game using test files I have been given. These texts files are of chars S,W,E,N and T which all correspond to directions except for T, which is the treasure. Everything works fine until it moves the length of the rows/columns. I suspect it has something to do with the for loops but I'm not certain. Is there a way to do this without for loops or does anyone have any advice to get this back on track?
Here is my Updated code so far:
import java.util.*;
public class NewGridGame {
public static final int FALL_OFF = -1;
public static final int GOING_IN_CIRCLES = -2;
private int row;
private int col;
private char[][] gameBoard;
NewGridGame(int conRow, int conCol, char[][] conGameBoard) {
row = conRow;
col = conCol;
gameBoard = new char[row][col];
for (int i = 0; i < gameBoard.length; i++) {
for (int j = 0; j < gameBoard[i].length; j++) {
gameBoard[i][j] = conGameBoard[i][j];
}
}
System.out.println(Arrays.deepToString(gameBoard));
}
public int playGame() {
boolean[][] beenHereBefore = new boolean[row][col];
int turns = 0;
int i = 0;
int j = 0;
while (true) {
if (beenHereBefore[i][j] == true) {
return GOING_IN_CIRCLES;
} else {
beenHereBefore[i][j] = true;
}
if (gameBoard[i][j] == 'N') {
if (i - 1 >= 0) {
i--;
turns++;
System.out.println(turns);
System.out.println(gameBoard[i][j]);
} else {
return FALL_OFF;
}
} else if (gameBoard[i][j] == 'S') {
if (i + 1 < row) {
i++;
turns++;
System.out.println(turns);
System.out.println(gameBoard[i][j]);
} else {
return FALL_OFF;
}
} else if (gameBoard[i][j] == 'E') {
if (j + 1 < col) {
j++;
turns++;
System.out.println(turns);
System.out.println(gameBoard[i][j]);
} else {
return FALL_OFF;
}
} else if (gameBoard[i][j] == 'W') {
if (j - 1 >= 0) {
j--;
turns++;
System.out.println(turns);
System.out.println(gameBoard[i][j]);
} else {
return FALL_OFF;
}
} else if (gameBoard[i][j] == 'T') {
return turns;
}
}
}
}
Here is an example of a test file as well.
ES
TW
this one should return 3, which is the number of moves (turns, in my code) but instead it gets to W (which takes 2 moves) and returns -2, which is only for when it's gone to a position more than once. Additionally, not all of the Arrays are squares, some are 1x200 or 4x5 for examples.
If you know that the board is such that, starting at (0, 0), you won't get stuck in a loop or move off the board you can just used something like this:
public int playGame()
{
int numMoves = 0;
int currentRow = 0;
int currentCol = 0;
while(gameBoard[currentRow][currentCol] != 'T')
{
switch (gameBoard[currentRow][currentCol])
{
case 'E': currentCol++; break;
case 'W': currentCol--; break;
case 'S': currentRow--; break;
case 'N': currentRow++; break;
default:
throw new IllegalStateException("Unrecognized Move");
}
numMoves++;
}
return numMoves;
}
You may want to use if-then-else instead of a switch.
If you need to check for loops or off-board moves you should be able to add these checks in.
I am stuck on my tictactoe problem. Define a calss called TicTacToe. An object of type TicTacToe is a single game of TicTacToe. Store the game board as a single 2d array of base type char that has three rows and three columns. Include methods to add a move, display the board, to tell whose turn it is, to tell whether there is a winnner, to say who the winner is, and to restart the game to the beginning. Write a main method for the class that will allow two players to enter their moves in turn at the same keyboard.
I have some of my methods written and have been testing as I go. When I test my code I either get it to place a mark but also print out invalid entry or it will continuously loop through asking for a move and then saying the space is occupied. I can't figure out how to fix that. I'm sure it has something to do with my do while loop and the boolean methods for isEmpty and notValid. Also I'm stuck on how to implement a counter for each player's win.
Here is my code:
public void addMove()
{
checkTurn();
int row, col;
do
{
System.out.println("Enter a row (1-3): ");
row = in.nextInt() - 1; //Array index starts at 0.
System.out.println("Enter a column (1-3): ");
col = in.nextInt() - 1;
if (row>=0 && row<ROWS)
if(col>=0 && col<COLUMNS)
if (playerX)
{
gameBoard[row][col] = player1Move;
}
else
{
gameBoard[row][col] = player2Move;
}
checkForWin();
changePlayer();
}while (notValid(row,col));
System.out.println("Invaild Entry.");
//System.exit(0);
//checkForWin();
//changePlayer();
}
public boolean notValid(int row, int col)
{
if (row < 0 || row > ROWS )
return true;
if (col < 0 || col > COLUMNS)
return true;
if (!isEmpty(row,col))
return true;
return false;
}
public boolean isEmpty(int row, int col)
{
if(gameBoard[row][col]==' ')
return true;
else
{
System.out.println("Space is already occupied.");
return false;
}
}
}
Here is my testing class:
public class TicTacToe
{
public static void main(String[] args)
{
TicTacToeClass game = new TicTacToeClass();
game.addMove();
game.printBoard();
}
}
I will let you handle the multiple game part. This plays one game and exits.
import java.util.Scanner;
public class TicTacToe
{
private final static int ROWS = 3;
private final static int COLUMNS = 3;
private char[][] gameBoard;
private int player1WinCount = 0;
private int player2WinCount = 0;
private char player1Move = 'X', player2Move = 'O';
private boolean playerX = true;
Scanner in = new Scanner(System.in);
public TicTacToe()
{
gameBoard = new char [ROWS][COLUMNS];
playerX = true;
startGame();
}
//Initiate the game board with all empty spaces.
public void startGame()
{
for (int row = 0; row < ROWS; row++) //Loop through rows.
for(int col = 0; col < COLUMNS; col++) //Loop through columns.
gameBoard[row][col]= ' ';
}
public boolean checkTurn()
{
if (playerX)
{
System.out.println("Player X's turn.");
}
else
{
System.out.println("Player O's turn.");
}
return playerX;
}
public void addMove()
{
int row, col;
do
{
checkTurn();
System.out.println("Enter a row (1-3): ");
row = in.nextInt() - 1; //Array index starts at 0.
System.out.println("Enter a column (1-3): ");
col = in.nextInt() - 1;
if(notValid(row,col)){
// do not proceed
System.out.println("Invalid Entry.");
continue;
}
if (row>=0 && row<ROWS)
if(col>=0 && col<COLUMNS)
if (playerX)
{
gameBoard[row][col] = player1Move;
}
else
{
gameBoard[row][col] = player2Move;
}
boolean hasWon = checkForWin();
if(hasWon)
{
System.out.println("You won");
if(playerX)
{
player1WinCount++;
}
else
{
player2WinCount++;
}
break;
}
changePlayer();
}while (true);
}
public boolean notValid(int row, int col)
{
if (row < 0 || row > (ROWS - 1))
return true;
if (col < 0 || col > (COLUMNS - 1))
return true;
if (!isEmpty(row,col))
return true;
return false;
}
public boolean isEmpty(int row, int col)
{
if(gameBoard[row][col]==' ')
return true;
else
{
System.out.println("Space is already occupied.");
return false;
}
}
public void changePlayer()
{
if (playerX)
{
playerX = false;
}
else
{
playerX = true;
}
}
public void printBoard()
{
for (int row = 0; row < ROWS; row++){
for (int col = 0; col < COLUMNS; col++)
{
System.out.print("" + gameBoard[row][col]);
if(col == 0 || col == 1)
System.out.print("|");
}
if (row ==0 || row ==1)
System.out.print("\n-----\n");
}
}
/**
* This method checks to see if a winner.
* return true is there is a winner.
*/
public boolean checkForWin()
{
//checks rows for win
for(int row = 0; row < ROWS; row ++)
{
if (gameBoard[row][0] == gameBoard[row][1] && gameBoard[row][1]==gameBoard[row][2] && gameBoard[row][0]!= ' ')
return true;
}
//checks columns for wins.
for (int col = 0; col < COLUMNS; col++)
{
if (gameBoard[0][col] == gameBoard[1][col]&& gameBoard[1][col]==gameBoard[2][col] && gameBoard[0][col]!= ' ')
return true;
}
//check the diagonals for wins.
if (gameBoard[0][0] == gameBoard[1][1] && gameBoard[1][1] == gameBoard[2][2] && gameBoard[0][0]!= ' ')
return true;
if (gameBoard[2][0] == gameBoard[1][1] && gameBoard[1][1] == gameBoard[0][2] && gameBoard[0][2]!= ' ')
return true;
return false;
}
public static void main(String args[])
{
TicTacToe game = new TicTacToe();
game.addMove();
game.printBoard();
}
}
So I have this recursive method that searches a 4x4 "board" for a word (think boggle except it only looks above, below, left, and right of the current letter). It gets passed an index (the current letter it is searching for from a given word), and the row and column to search around. The first if statement takes care of the first letter, and always works. The next else if statement doesn't work, and I'm not sure why. Any help is appreciated as to why. secondArray is used in another part of the program when it is displayed.
private boolean verifyWord(int index, int row, int column) {
System.out.println(index + " " + row + " " +column);
if (index == 0) {
for (int i = 0; i < letterArray.length; i++) {
for (int i2 = 0; i2 < letterArray[0].length; i2++) {
if (letterArray[i][i2] == wordToFind.charAt(index)) {
secondArray[i][i2] = true;
verifyWord(index+1, i, i2);
}
}
}
} else if (index > 0 && index < wordToFind.length()) {
// check above row
if (row+1 < row) {
if (letterArray[row+1][column] == wordToFind.charAt(index)) {
secondArray[row+1][column] = true;
verifyWord(index+1, row+1, column);
}
}
//check below row
if (row-1 >= 0) {
if (letterArray[row-1][column] == wordToFind.charAt(index)) {
secondArray[row-1][column] = true;
verifyWord(index+1, row-1, column);
}
}
//check left column
if (column-1 >= 0) {
if (letterArray[row][column-1] == wordToFind.charAt(index)) {
secondArray[row][column-1] = true;
verifyWord(index+1, row, column-1);
}
}
//check right column
if (column+1 < letterArray[0].length) {
if (letterArray[row][column+1] == wordToFind.charAt(index)) {
secondArray[row][column+1] = true;
verifyWord(index+1, row, column+1);
}
}
} else {
boolCheck = true;
}
return boolCheck;
}
The first condition if(row+1 < row) in your else if(index > 0 && index < wordToFind.length()) would never be evaluated to true (x+1 is always bigger than x).
You probably want it to be if(row+1 < letterArray.length)
so I've been asked to solve a maze in a recursive java function, but I stumble into an issue that the recursive function doesnt seem to switch the correct path into '*'.
Any help would be appreciated.
public class Maze
{
/**
* This is only an example,
* you can change this to test other cases but don't forget to submit the work with this main.
* #param args
*/
public static void main(String[] args)
{
int M = 4;
int N = 4;
char[][] maze = {{'1','0','0','0'},{'1','1','0','0'},{'0','1','1','1'},{'0','0','0','1'}};
if (findPath(maze, 0,0))
printMaze(maze);
else
System.out.println("No solution");
}
private static void printMaze(char[][] maze)
{
for (int i = 0; i < maze.length; i++)
{
for (int j = 0; j < maze[0].length; j++)
{
System.out.print(maze[i][j] +" ");
}
System.out.println();
}
}
// you should implement this function
private static boolean findPath(char[][] maze, int i, int j)
{
if ((i+1 > maze.length) || (j+1 > maze[i].length))
return false;
else
{
if (maze[i][j] == 1)
{
maze[i][j] = '*';
if (maze[i+1][j] == 1)
{
return findPath(maze, i+1, j);
}
if (maze[i][j+1] == 1)
{
return findPath(maze, i, j+1);
}
}
}
return true;
}
}
You're missing quotes around the 1 at
if (maze[i][j] == 1)
should be
if (maze[i][j] == '1')
The number 1 and the character representing the number 1 are two different things in Java (and in any other statically typed language), so you can't check if they're equal like that.
I doubt that the code will find all paths then though, since you don't seem to be searching left and up at all.
Use this code:
private static boolean findPath(char[][] maze, int i, int j)
{
if (maze[i][j] == 1)
{
maze[i][j] = '*';
if ((i+1 > maze.length && maze[i+1][j] == '1' && findPath(maze, i+1, j))
{
return true;
}
if ((j+1 > maze[i].length) && maze[i][j+1] == '1' && findPath(maze, i, j+1))
{
return true;
}
if (i>=1 && maze[i-1][j] == '1' && findPath(maze, i-1,j)){
return true;
}
if(j>=1 && maze[i][j-1] == '1' && findPath(maze, i,j-1)){
return true;
}
}
return false;
}