I'm trying to backtrack through a linkedlist I have created to solve a knight's tour problem, but once I hit a condition requiring me to backtrack, it totally empties the list. I have figured out it is because when I return false from the function findpath() to keep my while loop going, it continually loops back through the goback() function. What I'm having trouble figuring out is why. When i go through the goback function and call the calcmove function, it pushes the correct move to the structure I have declared, so passing false should keep the loop going and restart with the boolean cando and figuring out if that is false or not. But, it should be true because I just tested it and pushed it to the stack. Instead, it's emptying the list after I backtrack for the first time. So calcmove() would just be returning false every time after the first pop. But I don't see why that's happening. I need to return false to keep the loop going. What I need it to do is go back only once, find a new move, and continue on. Why would it be looping back to the function where the value on the list gets popped? If the value worked, and a new move is created (which I did verify it is doing correctly), it should be ready to call with a new (true) boolean. Is this just an inherently bad way of implementing the backtracking?
#include "stdafx.h"
#include "Header.h"
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <iomanip>
llist list;
Move m;
int board[8][8];
int cx[] = { -2, -1, 1, 2, 2, 1, -2, -1 };
int cy[] = { 1, 2, 2, 1, -1, -2, -1, -2 };
int movenum = 1;
Move first;
/*Check to see if move is within the constraints of the board*/
bool constraints(int k, int b) {
if ((k < 0) || (b < 0) || (k > 7) || (b > 7) || (board[k][b] != -1)) {
return true;
}
else {
return false;
}
}
/* Initialization of 8x8 board, fill the array with -1 */
void initboard() {
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
board[x][y] = -1;
}
}
}
/* Output the current board array */
void printboard(int arr[8][8]) {
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
cout << std::setw(2) << arr[x][y] << " ";
}
cout << endl;
}
}
void updateboard(int k, int b) {
board[k][b] = movenum;
movenum++;
}
bool calcmove(int x, int y, int i) {
for (i; i < 9; i++) {
int a0 = x + cx[i];
int a1 = y + cy[i];
/*if(board[a0][a1] == board[first.x][first.y]){
}*/
if (constraints(a0, a1) == false) {
updateboard(a0, a1);
m.x = a0;
m.y = a1;
m.index = i;
list.push(m);
//list.display();
return true;
}
}
return false;
}
void goback(int k, int b) {
board[k][b] = -1;
list.display();
Move m = list.pop();
bool cando = calcmove(m.x, m.y, m.index);
cout << "prev is " << m.x << " , " << m.y << endl;
if (cando) {
return;
}
else {
goback(m.x,m.y);
}
}
bool findpath(){
bool cando = calcmove(m.x, m.y, 0);
if (cando) {
return false;
}
else {
movenum--;
goback(m.x, m.y);
return false; /*------> inserting this here drains the list*/
}
return true;
}
int main()
{
int m1 = 1;
int m2 = 2; //random
first.x = m1;
first.y = m2;
first.index = 0;
list.push(first); //push first node on to stack
initboard();
updateboard(m1, m2); //update board
while (!findpath()) {
;
}
printboard(board);
}
the .h file:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include <ostream>
using std::cout;
using std::endl;
using std::setw;
struct Move {
int x;
int y;
uint32_t index;
};
struct node
{
public:
Move info;
struct node *next;
};
class llist {
struct node *start;
public:
void push(Move coords) {
struct node *p = new node;
p = newnode(coords);
if (start == NULL) {
start = p;
}
else {
p->next = start;
start = p;
//cout << "pushed" << endl;
}
}
Move pop() {
if (start == NULL) {
throw std::runtime_error("The list is empty");
}
else {
struct node *temp = new node;
temp = start;
Move data = start->info;
start = start->next;
delete temp;
//cout << "pop successful" << endl;
return data;
}
}
node *newnode(Move value) {
struct node *temp = new(struct node);
if (temp == NULL) {
return 0;
}
else {
temp->info = value;
temp->next = NULL;
return temp;
}
}
void display()
{
struct node *temp;
if (start == NULL)
{
cout << "The List is Empty" << endl;
return;
}
temp = start;
cout << "Elements of list are: " << endl;
while (temp != NULL)
{
cout << temp->info.x << "->";
temp = temp->next;
}
cout << "empty" << endl;
}
};
The goal of this is to create a linked list, solve the problem using the list for backtracking (push the current move unless no moves are available, then pop the previous values), and return the completed board.