Logic error in NQueens recursion program - java

I'm using java and am trying to make a program that uses recursion to solve the NQueens puzzle. The problem is it is giving me true when it shouldn't be (for example 3 should return false because you can NQueen a 3x3 grid). I have looked through everything multiple times but I cannot find where things go wrong. Anyone have any idea?
package model;
public class NQueensModel
{
private int myNumsQueen;
private boolean[][] myBoard;
private static NQueensModel myModel = new NQueensModel(3);
public static void main (String[] args) {
System.out.println(myModel.solvePuzzle());
}
public NQueensModel(int nQueens)
{
myNumsQueen = nQueens;
myBoard = new boolean[myNumsQueen][myNumsQueen];
}
public boolean solvePuzzle()
{
return this.solvePuzzle(myNumsQueen);
}
private boolean solvePuzzle(int ncolumn)
{
if(ncolumn>myNumsQueen)
{
return true;
}
int i;
for( i =0; i<myBoard.length;i++)
{
if(this.isSafeMove(i, ncolumn)==true)
{
myBoard[i][ncolumn-1]=true;
if(this.solvePuzzle(ncolumn+1)==true)
{
return true;
}
myBoard[i][ncolumn]=false;
}
}
return false;
}
private boolean isSafeMove(int row, int col)
{
for(int i=0; i<myBoard[row].length; i++)
{
if(myBoard[row][i]==true)
{
return false;
}
}
for(int i = 0; i<myBoard.length; i++)
{
if(myBoard[i][col-1]==true)
{
return false;
}
}
if(this.checkLowerDiag(row, col)==true)
{
return false;
}
if(this.checkUpperDiag(row, col)==true)
{
return false;
}
if(this.checkLeft(row,col)==true)
{
return false;
}
else
{
return true;
}
}
private boolean checkUpperDiag(int row, int col)
{
if(row==0)
{
return true;
}
else if(col==myBoard[0].length)
{
if (myBoard[row-1][col-2]==true)
{
return true;
}
else
{
return false;
}
}
else if(myBoard[row-1][col-2]==true || myBoard[row-1][col]==true)
{
return true;
}
else
{
return false;
}
}
private boolean checkLowerDiag(int row, int col)
{
if(col==1 && myBoard[row][col]==true)
{
return true;
}
else if(col == myBoard[0].length)
{
if(myBoard[row+1][col-2]==true)
{
return true;
}
else
{
return false;
}
}
else if(row == myBoard.length)
{
return true;
}
else if(myBoard[row+1][col-2]==true || myBoard[row+1][col]==true)
{
return true;
}
else
{
return false;
}
}
private boolean checkLeft(int row, int col)
{
if(myBoard[row][col-1]==true)
{
return true;
}
else
{
return false;
}
}
private boolean placeQueen(int row, int col)
{
myBoard[row][col] = true;
return true;
}
private boolean removeQueen(int row, int col)
{
myBoard[row][col] = false;
return false;
}
// public String toString()
// {
//
// }
}

Related

how can I sort the class generic type when read from file with

I have this class and I read from file the data and my program is add the word and I count every word for example:
(WData{word=success, count=1} WData{word=automata, count=1} Data{word=theory, count=2}) How can I sort the output and start with character A to Z I mean the word and. this my code
Class Sa
class SA:
public class SA<T> {
int head;
int size;
T[] nodes;
public SA(int maxsize) {
head = 0;
nodes = (T[]) new Object[maxsize];
size = 0;
}
public int size() {
return size;}
public boolean empty() {
return size == 0;
public void insert(T e) {
nodes[size] = e;
size++;
}
public T find(T s) {
if (size != 0) {
for (int i = 0; i < size; i++) {
if (nodes[i].equals(s)) {
return nodes[i];
}
}
}
return null;
}
public void display() {
for (int i = 0; i < size; i++) {
System.out.println(nodes[i].toString());
}}}
and here class TextAnalyzer:
Public class TextAnalyzer<T> {
private static class WData {
#Override
public int hashCode() {
int hash = 7;
hash = 71 * hash + Objects.hashCode(this.word);
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final WData other = (WData) obj;
if (!Objects.equals(this.word, other.word)) {
return false;
}
return true;
}
String word;
int count;
public WData(String w, int f) {
word = w;
count = f;
}
#Override
public String toString() {
return "WData{" + "word=" + word + ", count=" + count + '}';
}
} SA<WData>list;
public TextAnalyzer() {
list=new SA<WData>(11000);
}
public void processText(String filename) {
long count = 0;
try {
Scanner sc = new Scanner(new File(filename));;
while (sc.hasNext()) {
String line = sc.next();
String st = line.replaceAll("[^a-zA-Z ]", "").toLowerCase();
processWord(st);}
list.display();
} catch (FileNotFoundException ex) {
System.out.println("There are error in processText");
}
}
public void processWord(String word) {
WData w = new WData(word, 1);
WData s = list.find(w);
if (s == null) {
list.insert(w);
} else {
s.count = s.count + 1;
}}}

How to create a clone of a 2d array?

I am trying to create a clone of myBoard[][] because right now when I try to return it I get all false values which can't be right.
Where exactly would I clone it, and how, so that I would get a copy of a myBoard[][] with legitimate values instead of all false? I am trying to return it at the bottom with public boolean[][] getBoard()
package model;
public class NQueensModel
{
private int myNumsQueen;
public int myPossibilities=0;
private boolean[][] myBoard;
private boolean[][] myGridBoard;
public static void main (String[] args) {
//...
}
public NQueensModel(int nQueens)
{
myNumsQueen = nQueens;
myPossibilities=0;
myBoard = new boolean[myNumsQueen][myNumsQueen];
}
public boolean solvePuzzle()
{
return solvePuzzle(0);
}
private boolean solvePuzzle(int ncolumn)
{
if(ncolumn>myNumsQueen-1)
{
myPossibilities++;
}
int i;
for( i =0; i<myNumsQueen;i++)
{
if(this.isSafeMove(i, ncolumn)==true)
{
this.placeQueen(i,ncolumn);
if(this.solvePuzzle(ncolumn+1)==true)
{
return true;
}
this.removeQueen(i, ncolumn);
}
}
return false;
}
private boolean doIt(int county)
{
if(county>0)
{
return true;
}
else
{
return false;
}
}
private boolean isSafeMove(int row, int col)
{
if(row <0 || row>=myNumsQueen || col<0 || col>=myNumsQueen)
{
return false;
}
else if(this.checkLowerDiag(row, col)==true ||this.checkUpperDiag(row, col)==true ||this.checkLeft(row,col)==true)
{
return false;
}
else
{
return true;
}
}
private boolean checkUpperDiag(int row, int col)
{
if(row==0)
{
return false;
}
else
{
for(int i=row, j = col; i>=0 && j>=0; i--, j--)
{
if(myBoard[i][j]==true)
{
return true;
}
}
return false;
}
}
private boolean checkLowerDiag(int row, int col)
{
if(col==0 )
{
return false;
}
if(row==myNumsQueen-1){
return false;
}
else
{
for(int i = row, j = col; i<myNumsQueen && j>=0; i++, j--)
{
if(j>=myNumsQueen)
{
return false;
}
else if(myBoard[i][j]==true)
{
return true;
}
}
return false;
}
}
private boolean checkLeft(int row, int col)
{
if(col==0)
{
return false;
}
else
{
for(int i = col; i>=0; i--)
{
if(i>=myNumsQueen)
{
return false;
}
else if(myBoard[row][i]==true)
{
return true;
}
}
return false;
}
}
private boolean placeQueen(int row, int col)
{
if(col>=myNumsQueen)
{
return false;
}
myBoard[row][col] = true;
return true;
}
private boolean removeQueen(int row, int col)
{
myBoard[row][col] = false;
return false;
}
public int getPossibilities(){
return myPossibilities;
}
public boolean[][] getBoard()
{
for(int i = 0; i<5; i++)
{
for(int j = 0; j<5; j++)
{
System.out.println("myBoard : " +myBoard[i][j]);
}
}
return myBoard;
}
}
Well, if you're just looking to create a cloned array, you would have to build it by iterating over the old array and copying the values over:
for (int i = 0; i < oldArray.length; ++i)
for (int j = 0; j < oldArray[0].length; ++j)
newArray[i][j] = oldArray[i][j];
As you are using native types you can use clone().
public static boolean[][] clone2DArray(boolean [][] array){
// this clone is a shallow copy
boolean[][] newArray =(boolean[][]) array.clone();
//now you need to clone each array cause still referring to the same
for(int i=0;i<array.length;i++){
newArray[i]=Arrays.copyOf(array[i],array[i].length);
//newArray[i]=(boolean[])array[i].clone(); this is valid too
}
return newArray;
}
Read more in Arrays#copyOf()

How to count all the possibilities of NQueens?

So the code below is an NQueens program that gives the correct true or false return of whether NQueens is possible with the given variable (ie if it is 3, then is it possible for a 3x3 board). What I'm having trouble with is finding out how many different possibilities there are for it. For example in a 4x4 there are 2 possibilities, so it should return true, (which it already does) and 2. I am not sure where to put this counter method or change the code so that it keeps going after one possibility.
Any advice?
package model;
public class NQueensModel
{
private int myNumsQueen;
private int myPossibilities;
private boolean[][] myBoard;
private static NQueensModel myModel = new NQueensModel(4);
public static void main (String[] args) {
System.out.println(myModel.solvePuzzle());
}
public NQueensModel(int nQueens)
{
myNumsQueen = nQueens;
myPossibilities=0;
myBoard = new boolean[myNumsQueen][myNumsQueen];
}
public boolean solvePuzzle()
{
return this.solvePuzzle(0);
}
private boolean solvePuzzle(int ncolumn)
{
if(ncolumn>myNumsQueen-1)
{
return true;
}
int i;
for( i =0; i<myNumsQueen;i++)
{
if(this.isSafeMove(i, ncolumn)==true)
{
this.placeQueen(i,ncolumn);
System.out.println(i + " " + ncolumn);
if(this.solvePuzzle(ncolumn+1)==true)
{
return true;
}
this.removeQueen(i, ncolumn);
}
}
return false;
}
private boolean isSafeMove(int row, int col)
{
if(this.checkLowerDiag(row, col)==true ||this.checkUpperDiag(row, col)==true ||this.checkLeft(row,col)==true)
{
return false;
}
else
{
return true;
}
}
private boolean checkUpperDiag(int row, int col)
{
if(row==0)
{
return false;
}
else
{
for(int i=row, j = col; i>=0 && j>=0; i--, j--)
{
if(myBoard[i][j]==true)
{
return true;
}
}
return false;
}
}
private boolean checkLowerDiag(int row, int col)
{
if(col==0 )
{
return false;
}
else
{
for(int i = row, j = col; i<myNumsQueen && j>=0; i++, j--)
{
if(myBoard[i][j]==true)
{
return true;
}
}
return false;
}
}
private boolean checkLeft(int row, int col)
{
if(col==0)
{
return false;
}
else
{
for(int i = col; i>=0; i--)
{
if(myBoard[row][i]==true)
{
return true;
}
}
return false;
}
}
private boolean placeQueen(int row, int col)
{
myBoard[row][col] = true;
return true;
}
private boolean removeQueen(int row, int col)
{
myBoard[row][col] = false;
return false;
}
// public String toString()
// {
//
// }
}
Below is some sudo code of one possible solution. It keeps a running count of all the valid solutions you have discovered thus far. When a new solution is discovered you add it to the count and return. This will complete until all possible solutions are discovered.
public int solvePuzzle(int solutionCount, int col){
if(isValidSolution())
return solutionCount + 1;
else if(solutionFails())
return solutionCount;
else {
for(/*Every position you want to check in this col*/){
solutionCount = solvePuzzle(solutionCount, col + 1);
}
return solutionCount;
}
}

Backtracking maze algorithm

I'm having some issues implementing backtracking for solving a maze, the issue I'm having is that if the player gets to a dead end, it doesn't go back to where it have another solution. In the case i developed just by coincidence at first it worked because of the order of the methods, but if i put that the player moves first east, it reaches a dead end and doesn't backtrack. Here is the code:
import java.util.ArrayList;
public class Laberinto {
int posicionX = 0;
int posicionY = 0;
int largo = 6;
int ancho = 6;
int solX = 5;
int solY = 4;
boolean[][] cordenadas = new boolean[largo][ancho];
int[] bloqueadasX = {1,2,3,4,5,5,0,2,3,4,5,0,2,3,4,5,3,0,1,5};
int[] bloqueadasY = {0,0,0,0,0,1,2,2,2,2,2,3,3,3,3,3,4,5,5,5};
public ArrayList<Coordenada> recorridas = new ArrayList<Coordenada>();
public Laberinto(int xo,int yo) {
posicionX = xo;
posicionY = yo;
recorridas.add(new Coordenada(posicionX,posicionY));
}
public void recorrer() {
if(posicionX==solX && posicionY == solY) {
System.out.println("Solucion encontrada");
}
else {
if(este(posicionX,posicionY)) recorrer();
if(norte(posicionX,posicionY)) recorrer();
if(sur(posicionX,posicionY)) recorrer();
if(oeste(posicionX,posicionY)) recorrer();
volver(new Coordenada(posicionX,posicionY));
}
}
public void armarLaberinto() {
for(int i=0;i<ancho;i++) {
for(int j=0;j<largo;j++) {
cordenadas[j][i] = estaBloqueada(j,i);
}
}
}
public boolean estaBloqueada(int x,int y) {
for(int i=0;i<bloqueadasX.length;i++) {
if(x==bloqueadasX[i] && y==bloqueadasY[i]) {
return true;
}
}
return false;
}
public boolean norte(int x,int y) {
if(dentroTablero(x,y-1)) {
if(!yaRecorrido(new Coordenada(x,y-1))) {
if(estaBloqueada(x,y-1)) {
return false;
}
posicionY = posicionY-1;
recorridas.add(new Coordenada(x,y));
return true;
}
return false;
}
return false;
}
public boolean sur(int x,int y) {
if(dentroTablero(x,y+1)) {
if(!yaRecorrido(new Coordenada(x,y+1))) {
if(estaBloqueada(x,y+1)) {
return false;
}
posicionY = posicionY+1;
recorridas.add(new Coordenada(x,y));
return true;
}
return false;
}
return false;
}
public boolean este(int x,int y) {
if(dentroTablero(x+1,y)) {
if(!yaRecorrido(new Coordenada(x+1,y))) {
if(estaBloqueada(x+1,y)) {
return false;
}
posicionX = posicionX+1;
recorridas.add(new Coordenada(x,y));
return true;
}
return false;
}
return false;
}
public boolean oeste(int x,int y) {
if(dentroTablero(x-1,y)) {
if(!yaRecorrido(new Coordenada(x-1,y))) {
if(estaBloqueada(x-1,y)) {
return false;
}
posicionX = posicionX-1;
recorridas.add(new Coordenada(x,y));
return true;
}
return false;
}
return false;
}
public boolean dentroTablero(int x, int y) {
if((x >=0 && x<=ancho) && (y>=0 && y<=largo) ) {
return true;
}
return false;
}
public boolean yaRecorrido(Coordenada a) {
for(int i=0;i<recorridas.size();i++) {
if(recorridas.get(i).getX() == a.getX() && recorridas.get(i).getY() == a.getY()) {
return true;
}
}
return false;
}
public void volver(Coordenada a) {
recorridas.remove(a);
}
public void bloqueadas() {
armarLaberinto();
for(int i=0;i<ancho;i++) {
for(int j=0;j<largo;j++) {
if(!cordenadas[j][i]) {
if(j==solX && i==solY) {
System.out.print("M");
}
else {
System.out.print(" ");
}
}
else {
System.out.print("◘");
}
}
System.out.println();
}
}
public void mostrarRecorrido() {
armarLaberinto();
for(int i=0;i<ancho;i++) {
for(int j=0;j<largo;j++) {
if(!cordenadas[j][i]) {
if(j==solX && i==solY) {
System.out.print("M");
}
else {
if(yaRecorrido(new Coordenada(j,i))) {
System.out.print("•");
}
else {
System.out.print(" ");
}
}
}
else {
System.out.print("◘");
}
}
System.out.println();
}
}
public static void main(String[] args) {
Laberinto laberinto = new Laberinto(0,0);
laberinto.armarLaberinto();
laberinto.bloqueadas();
laberinto.recorrer();
laberinto.mostrarRecorrido();
System.out.println(laberinto.posicionX);
System.out.println(laberinto.posicionY);
}
}
One possible bug is you have a global for your position. This would confuse your search a lot, once the first call fails to find the solution. Try to keep posicionX,posicionY as local to that function if possible.

"A Java Exception has occurred"

So I'm trying to run my pacman project as a jar(also tried runnable) and I just get the error message you see in the title. It runs perfectly fine in eclipse/netbeans, but whilst cleaning/building i see the warnings:
Note: C:\Users\Lucas\Documents\Eclipse\PackMan\src\game\packman\GameData.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
The main class is correct and assigned. Does anybody know what I'm doing wrong?
Here is my GameData class
public class GameData {
int mazeNo;
CopyOnWriteArrayList<Position> pills;
CopyOnWriteArrayList<Position> powerPills;
public MoverInfo packman;
public GhostInfo[] ghostInfos = new GhostInfo[4];
public int score;
Maze[] mazes;
boolean dead = false;
boolean win = false;
public GameData() {
mazes = new Maze[4];
// load mazes information
for (int m=0; m<4; m++) {
mazes[m] = new Maze(m);
}
setMaze(mazeNo);
}
private void setMaze(int m) {
packman = new MoverInfo(mazes[m].packmanPos);
for (int g=0; g<4; g++) {
ghostInfos[g] = new GhostInfo(mazes[m].ghostPos);
}
pills = new CopyOnWriteArrayList((List<Position>)(mazes[m].pills.clone()));
powerPills = new CopyOnWriteArrayList((List<Position>)(mazes[m].powerPills.clone()));
}
public void movePackMan(int reqDir) {
if (move(reqDir, packman)) {
packman.curDir = reqDir;
} else {
move(packman.curDir, packman);
}
}
private int wrap(int value, int incre, int max) {
return (value+max+incre)%max;
}
private boolean move(int reqDir, MoverInfo info) {
// current position of packman is (row, column)
int row = info.pos.row;
int column = info.pos.column;
int rows = mazes[mazeNo].rows;
int columns = mazes[mazeNo].columns;
int nrow = wrap(row, MoverInfo.DROW[reqDir], rows);
int ncol = wrap(column, MoverInfo.DCOL[reqDir], columns);
if (mazes[mazeNo].charAt(nrow, ncol) != '0') {
info.pos.row = nrow;
info.pos.column = ncol;
return true;
}
return false;
}
public void update() {
if (pills.contains(packman.pos)) {
pills.remove(packman.pos);
score += 5;
} else if (powerPills.contains(packman.pos)) {
powerPills.remove(packman.pos);
score += 50;
for (GhostInfo g:ghostInfos) {
g.edibleCountDown = 500;
}
}
for (GhostInfo g:ghostInfos) {
if (g.edibleCountDown > 0) {
if (touching(g.pos, packman.pos)) {
// eat the ghost and reset
score += 100;
g.curDir = g.reqDir = MoverInfo.LEFT;
g.pos.row = mazes[mazeNo].ghostPos.row;
g.pos.column = mazes[mazeNo].ghostPos.column;
g.edibleCountDown = 0;
}
g.edibleCountDown--;
} else {
if (touching(g.pos, packman.pos)) {
dead = true;
}
}
}
// level is cleared
if (pills.isEmpty() && powerPills.isEmpty()) {
mazeNo++;
if (mazeNo < 4) {
setMaze(mazeNo);
} else if (mazeNo == 5) {
win = true;
} else {
// game over
dead = true;
}
}
}
private boolean touching(Position a, Position b) {
return Math.abs(a.row-b.row) + Math.abs(a.column-b.column) < 3;
}
public void moveGhosts(int[] reqDirs) {
for (int i=0; i<4; i++) {
GhostInfo info = ghostInfos[i];
info.reqDir = reqDirs[i];
if (move(info.reqDir, info)) {
info.curDir = info.reqDir;
} else {
move(info.curDir, info);
}
}
}
public int getWidth() {
return mazes[mazeNo].width;
}
public int getHeight() {
return mazes[mazeNo].height;
}
public List<Integer> getPossibleDirs(Position pos) {
List<Integer> list = new ArrayList<>();
for (int d=0; d<4;d++) {
Position npos = getNextPositionInDir(pos, d);
if (mazes[mazeNo].charAt(npos.row, npos.column) != '0') {
list.add(d);
}
}
return list;
}
private Position getNextPositionInDir(Position pos, int d) {
int nrow = wrap(pos.row, MoverInfo.DROW[d], mazes[mazeNo].rows);
int ncol = wrap(pos.column, MoverInfo.DCOL[d], mazes[mazeNo].columns);
return new Position(nrow, ncol);
}
}

Categories

Resources