Peg Solitaire can't find a solution with backtracking - java

I'm working on a solution for the game Peg Solitaire in Java. It appears however, that my solution is unable to solve the game.
I'm working with the 'standard' version, so the board looks like :
{2, 2, 1, 1, 1, 2, 2}
{2, 2, 1, 1, 1, 2, 2}
{1, 1, 1, 1, 1, 1, 1}
{1, 1, 1, 0, 1, 1, 1}
{1, 1, 1, 1, 1, 1, 1}
{2, 2, 1, 1, 1, 2, 2}
{2, 2, 1, 1, 1, 2, 2}
0 is empty, 1 is a peg, 2 is nothing
The desired state of the board is
{2, 2, 0, 0, 0, 2, 2}
{2, 2, 0, 0, 0, 2, 2}
{0, 0, 0, 0, 0, 0, 0}
{0, 0, 0, 1, 0, 0, 0}
{0, 0, 0, 0, 0, 0, 0}
{2, 2, 0, 0, 0, 2, 2}
{2, 2, 0, 0, 0, 2, 2}
My solve() method works like this:
move peg on location x,y in a direction (up, down, left or right)
check if the board is in the desired state, if so, print board and moves taken and exit the program
Check if there is a still a peg that can be moved, if there isn't one exit the function
Find the first possible peg that can move in 1 or more directions; call solve() for that peg and it's direction.
(if we get here step 4 produced a undesired board state) undo the move made in step 4 and recall step 4 with the next possible move that peg could make, if any.
return to step 4 for the next possible peg that comes after the peg found in step 4.
I've implemented the above instructions like this:
private void play(int xx, int yy, Direction direction) {
board.move(xx, yy, direction);
if (board.finished()) {
board.printBoard();
System.out.println(moves);
System.exit(0);
}
if (board.noMoreMoves()) {
return;
}
for (int y = 0; y < board.board.length; y++) {
for (int x = 0; x < board.board[y].length; x++) {
if (board.containsPeg(x, y)) {
Direction[] moves = board.getMovesFor(x, y);
for (Direction move : moves) {
if (move != null) {
this.moves++;
play(x, y, move);
if (move.equals(Direction.UP)) {
board.undoMove(x, y-2, move);
} else if (move.equals(Direction.DOWN)) {
board.undoMove(x, y+2, move);
} else if (move.equals(Direction.LEFT)) {
board.undoMove(x-2, y, move);
} else if (move.equals(Direction.RIGHT)) {
board.undoMove(x+2, y, move);
}
}
}
}
}
}
return;
}
However, the above solution does not produce the desired board state. I have this version running in eclipse for over an hour now, without any results.
I've tested the methods board.move(x, y, direction), board.finished(), board.noMoreMoves(), board.containsPeg(x, y), board.getMovesFor(x, y) and board.undoMove(x, y, direction) in isolation and they all appear to function as desired.
Is there something I'm missing here, either in my implementation or in recursion / backtracking in general? I'm pretty sure the solution doesn't require over 200 million moves to be made.

What you need is a debugging strategy.
Use a method that will output the state of your board. Also write one that will save a representation of your board, and one that will compare two states to see if they're the same.
Output after the first method has failed, then at different points after backtracking to ensure that the backtrack has backtracked back to the right track.
Also make sure that you aren't tracking the same move more than once.
As for the possible number of moves, don't be too sure. One wouldn't think, a priori, that there were billions of possible moves in the first 10-20 moves of chess, but there are.

Related

Boolean 2d array of size m by n, another integer 2d array also with size m by n, and another integer 2d array of size r by c, replace values

I am trying to code a reverse tetris game for fun, but I am stumped on a part of my implementation :(
So I have a boolean 2D array of size m by n, another integer 2D array representing the field also of size m by n, and another integer 2D array of size r by c (the tetris piece).
Example:
Game field:
int[][] field = {{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{1, 1, 0, 1, 0},{1, 0, 1, 0, 1}};
Tetris piece:
int[][] figure = {{1, 1, 1}, {1, 0, 1}, {1, 0, 1}};
Boolean 2d Array: (Wrote code for this)
boolean[][] fieldbool = [[true, true, true, true, true], [true, true, true, true, true], [true, true, true, true, true], [false, false, true, true, true], [false, false, false, true, false]]
Expected output:
final field matrix
int[][] field = {{1, 1, 1, 0, 0},{1, 0, 1, 0, 0},{1, 0, 1, 0, 0},{1, 1, 0, 1, 0},{1, 0, 1, 0, 1}};
I want to fit the tetris piece in the smallest row and column index possible. I am super confused on how to do this. Worked on it for four hours and still stumped :(
So far, I tried maintaining two integer variables that store count for the number of times there is true for row and for col. If the count is equal to the height/width of the tetris piece, I have a for loop that goes back from the index currently in minus that count and fill the values in the field. It's not working as I my output is the same as the given field.

creating non symmetrical patterns of asterisks [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I'm new to Java and programming in general and embarking on an interesting problem. its a question has ive been tasked with to make my initials with asterisks. as mine is "CH" I've decided to start by trying to simplify by thinking of it as three columns and three rows.
so far I've created a two-dimensional array; to use as a blank grid. it's 5 by 10 (arbitrarily).
Breaking the task down I think there are three columns top to bottom, occupying the 0, 6, and 9th indexes of the y array. Also three rows: top and bottom first thirds; and the central last third. further to this I've decided on two spaces between the characters.
So my next thought has been it's probably best to consider the spaces? I believe I can probably effectively do this by slicing the arrays rather than doing iterating through or similar. to keep the code as tight as possible. i'm thinking I want to split x index and tell it to place a space in the mid-value..at some point (x/2) is it possible to give this index a name to do this and how do I do this in java?
What i'm trying to achieve is:
XXXX x x
x x x
x xxxx
x x x
xxxx x x
// so far i have just the base:
public class MyClass {
public static void main (string args[]){
int[x][y] myArray = new int[5][10];
brief summary of what i'd like to achieve so far:
*'s on Y "columns" 0,6,9
*'s on X 0-4 y 0;
6-9 y 2;
0-4 y 4
apologies if this seems stupidly simple but I'm unsure how to do this programmatically, and I'm on my own!
apologies for any errors any suggestions or pointers appreciated!
I would make each letter as array of bytes like:
byte[][] c = {{1, 1, 1, 1}, {1, 0, 0, 0}, {1, 0, 0, 0}, {1, 0, 0, 0}, {1, 1, 1, 1}};
byte[][] h = {{1, 0, 0, 1}, {1, 0, 0, 1}, {1, 1, 1, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}};
so, 1 marks the X, and 0 marks the zero, ie. a "raster alphabet".
Then you can do a row by row iteration of the arrays and print it out?
public class Test
{
public static void main(String[] args)
{
byte[][] c = {{1, 1, 1, 1}, {1, 0, 0, 0}, {1, 0, 0, 0}, {1, 0, 0, 0}, {1, 1, 1, 1}};
byte[][] h = {{1, 0, 0, 1}, {1, 0, 0, 1}, {1, 1, 1, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}};
for (int i = 0; i < 5; i++)
{
for (int j=0; j < 4; j++)
{
byte l = c[i][j];
System.out.print(l == 1 ? "x":" ");
}
System.out.print(" ");
for (int j=0; j < 4; j++)
{
byte l = h[i][j];
System.out.print(l == 1 ? "x":" ");
}
System.out.println("");
}
}
}

How to delete last element in array and put new in front?

I have a question concerning Java. I started up new to Java and my google search brought many results but non was the final help.
I created a class to track historical information. I have different values for different days and need to update them un a regular basis. I want to keep track of the last 30 days and created an array with 30 elements. When I call my 'shift' function I want to drop the last n elements and put zeros in front. Here is a minial example for 5 days:
public class Testclass {
private int[] histInfo;
public Element()
{
this.histInfo = new int[5];
}
public void shift_histInfo(long m)
{
//do magic
}
}
What I want shift to do is
INPUT:
histInfo = [50,21,1,45,901]
OPERATION:
shift_histInfo(2);
RESULT:
histInfo = [0,0,50,21,1]
I am thankfull for every kind of help you can support as well for thought-provoking impulses if you think that there is a way more elegant or efficient way.
Best :-)
Unless there are very tight performance constraints using the standard Collection classes will get the job done. Have a look at java.util.LinkedList.
As a programming exercise you might consider creating a ring buffer. The idea being to avoid copying the array on every insertion.
Keep a oldestIndex value.
When writing simply replace item[oldestIndex] and increment oldestIndex.
To iterate you start at oldestIndex and use an increment method to deal with wrapping round to the start of the array.
int nextIndex(int current) {
return (current + 1) % arrayLength;
}
Writing a nice encapsulating class to hide all this would be a good exercise.
You can try this :
public static void shift_histInfo(long m)
{
int[] myIntArray = {50,21,1,45,901};
int[] myIntArray2 = {50,21,1,45,901};
for (int j=0 ;j< myIntArray.length ; j++){
int temp = (int) (j+m);
if (temp >= myIntArray.length){
temp = temp - myIntArray.length;
myIntArray2[temp] = 0;
} else {
myIntArray2[temp] = myIntArray[j];
}
}
for (int j=0 ;j< myIntArray2.length ; j++){
System.out.println(myIntArray2[j]);
}
}
Output :
when shift_histInfo(2) ,
[0,0,50,21,1]
int[] array={1,2,3,4,5,6};
int removelength=2;
int e=1;
while(e<=removelength) {
for(int i=1;i<array.length;i++)
array[array.length-i]=array[array.length-i-1];
e++;
}
for(int i=0;i<removelength;i++) {
array[i]=0;
}
for(int g:array)
{
System.out.print(g);
}
For constraints that you wanted, although I did initialise the data in the same method instead of Element(). I don't know why the parameter is of type long so I left it and made an int local variable.
All it does is copy the index value over to the new array starting at m then increments/iterates until the end of the array.
You can also make the method return type int[] and then simply return changedInfo array. Instead of histInfo = changedInfo.clone();
private int[] histInfo;
public void shift_histInfo(long m) {
int n = (int) m;
this.histInfo = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15};
int length = this.histInfo.length;
int[] changedInfo = new int[length];
if (length - n >= 0) System.arraycopy(histInfo, 0, changedInfo, n + 0, length - n); //Edit: shortened to one line.
histInfo = changedInfo.clone();
System.out.println("Remove: " + n + " - " + Arrays.toString(changedInfo) + "\n");
}
public static void main(String[] args) {
Main main = new Main();
main.shift_histInfo(0);
main.shift_histInfo(30);
main.shift_histInfo(1);
main.shift_histInfo(15);
main.shift_histInfo(29);
}
println:
Remove: 0 - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
Remove: 30 - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Remove: 1 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
Remove: 15 - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
Remove: 29 - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]

Equivalent of for x, y in z in java

In python, you can use the structure for x in [a, b, c, d] for loops. This can be replicated using a foreach loop in java.
What about if I wanted to replicate a for x, y in z loop, such as the one below, in java?
for x_off, y_off in ( (1, 2), (-1, 2), (1, -2), (-1, -2), (2, 1), (-2, 1), (2, -1), (-2, -1) ):
#do something
I ended up just using variables for each index. But this won't be useful for 2d arrays with large counts for each inner array.
int[][] offsets = new int[][] { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1} };
for(int[] offset: offsets) {
int x = offset[0], y = offset[1];
// do something with x and y
You should create a class for storing the three values:
final class Point3D {
private final int x, y, z;
// constructor, getters, and equals/hashCode/toString here
}
Then you can use an array initializer with an enhanced for loop:
for (Point3D point : new Point3D[] { new Point3D(1, 1, 1), new Point3D(-1, 1, 1),
new Point3D(-1, -1, 1), new Point3D(1, -1, 1) }) {
// code here
}
It reads better if you create the array separately, especially if there are many points:
Point3D[] points = {
new Point3D( 1, 1, 1), new Point3D(-1, 1, 1),
new Point3D(-1, -1, 1), new Point3D( 1, -1, 1),
new Point3D( 1, 1, -1), new Point3D(-1, 1, -1),
new Point3D(-1, -1, -1), new Point3D( 1, -1, -1)
};
for (Point3D point : points) {
// code here
}

How disable changing variable inside array? [duplicate]

This question already has answers here:
Problem with assigning an array to other array in Java
(4 answers)
Closed 4 years ago.
I have 2D array:
int[] zero = {
1, 1, 1, 1, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 1, 1, 1, 1};
int[][] tab = {zero, zero};
I want to change this:
tab[0][0] = 0;
But when I did that It also change tab[1][0]. Can you tell me how can I disable that?
By making it so the two arrays are different objects rather than the same object.
One way to achieve that would be:
int[][] tab = {zero.clone(), zero.clone()};

Categories