'Java GUI Knights tour wrong algorithm
I am a beginner to java and new to data structures and algorithms. I am trying to implement the Knights tour to GUI with java swing. There are no errors in the code, but I think I made a mistake in applying the algorithm. So I made an 8x8 board made up of buttons and lets the user pick the initial move of the knight. At first, the knight moves correctly but when it does not have any available moves, it goes randomly to another box. I couldn't find the problems since I new to recursion and backtracking. here is the code:
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.*;
import java.util.Timer;
import javax.swing.*;
public class Chess implements ActionListener{
JFrame frame = new JFrame();
JButton[][] buttons = new JButton[8][8];
JPanel boardPanel = new JPanel();
final int BOARDSIZE = 8;
final int NUM_OF_MOVES = BOARDSIZE;
private int startx;
private int starty;
private int delay = 10000;
private int stepCount;
public int [] xMoves = {2,1,-1,-2,-2,-1,1,2};
public int [] yMoves = {1,2,2,1,-1,-2,-2,-1};
public Chess(){
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Chess Algo");
frame.setSize(800, 800);
boardPanel.setLayout(new GridLayout(8,8));
for(int i=0; i<buttons.length; i++){
for(int j=0; j<buttons.length;j++){
buttons[i][j] = new JButton();
buttons[i][j].setFocusable(false);
buttons[i][j].setBackground(Color.white);
buttons[i][j].addActionListener(this);
boardPanel.add(buttons[i][j]);
}
}
frame.add(boardPanel, BorderLayout.CENTER);
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e){
for(int i=0; i<buttons.length; i++){
for(int j=0; j<buttons.length;j++){
if(e.getSource() == buttons[i][j]){
stepCount++;
buttons[i][j].setBackground(Color.green);
buttons[i][j].setEnabled(false);
buttons[i][j].setText(Integer.toString(stepCount));;
startx = j;
starty = i;
stepCount++;
start();
}
}
}
}
public void start(){
for(int i=0; i<buttons.length; i++){
for(int j=0; j<buttons.length;j++){
buttons[i][j].setEnabled(false);
}
}
solve(stepCount, startx, starty);
}
public boolean solve(int stepCount, int x, int y){
if(stepCount == BOARDSIZE * BOARDSIZE){
return true;
}
for(int i=0; i<NUM_OF_MOVES;i++){
int nextX = x + xMoves[i];
int nextY = y + yMoves[i];
if( isStepValid(nextX,nextY)){
new javax.swing.Timer(delay, this).start();
moveNext(nextX, nextY);
if( solve(stepCount+1, nextX, nextY))
return true;
}
}
return false;
}
public void moveNext(int x, int y){
buttons[y][x].setBackground(Color.green);
buttons[y][x].setText(Integer.toString(stepCount));;
buttons[y][x].doClick();
stepCount++;
}
public boolean isStepValid(int x, int y){
if( x < 0 || x >= BOARDSIZE) return false;
if( y < 0 || y >= BOARDSIZE) return false;
if(!(buttons[y][x].getText().equals(""))) return false;
if(buttons[y][x].getText().equals("")) ;
return true;
}
public static void main(String[] args) {
new Chess();
}
}
Solution 1:[1]
I hope I understood the problem correctly:
I think your "exit strategy" is wrong. So you never tell recursion to stop recursion. I've redesigned the relevant section a bit. Of course, there is still room for improvement and optimization.
public boolean solve(int stepCount, int x, int y){
System.out.println(stepCount + " stepCount: " + x + " | " + y);
if(stepCount == BOARDSIZE * BOARDSIZE){
return false;
}
int nextX = x;
int nextY = y;
boolean valid = false;
for(int i=0; i<NUM_OF_MOVES;i++){
nextX = x + xMoves[i];
nextY = y + yMoves[i];
if( isStepValid(nextX,nextY)){
new javax.swing.Timer(delay, this).start();
moveNext(nextX, nextY);
valid = true;
break;
//if( solve(stepCount+1, nextX, nextY))
// return true;
}
}
if(valid){
return solve(stepCount+1, nextX, nextY);
}
else{
return false;
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Steffi |
