// jumpsaround - jumper game
// (c) 2011-2020 Alexander Kulbartsch

import std.stdio;

enum byte SIZEX = 6;
enum byte SIZEY = 5;

/* static array */
byte[2][8] jump = [[-1,-2], [1,-2], [-2,-1], [2,-1], [-2,1], [2,1], [-1,2], [1,2]];

byte[SIZEY][SIZEX] board;
byte[64] iters; // SIZEX*SIZEY

long solutions;
long roundtrips;

int main () {
    writeln("Hello, Jumper!\n");

	// init

	for (byte i = 0; i < SIZEX; i++) {
	    for (byte j = 0; j < SIZEY; j++) {
			board[i][j] = 0;
		}
	}
	for	(byte i = 0; i < (SIZEX*SIZEY); i++) iters[i] = 0;
	iters[0] = ' ';

	jumpto(0, 0, 1, 0);

	writeln("I am done.\n");

	return 0;
}


void jumpto(byte x, byte y, byte iter, byte arity) {

	// ok - store position
	board[x][y] = iter;
	iters[iter] = arity;

	// finished?
	if (iter >= SIZEX*SIZEY ) {

		// check for jumper roundtrips
		byte round = 0;
		for (int i = 0; i < 8; i++) {
			byte nx = cast(byte)(x + jump[i][0]);
			byte ny = cast(byte)(y + jump[i][1]);
           	// check if position is on the board
			if ( nx<0 || nx>(SIZEX-1) || ny<0 || ny>(SIZEY-1) ) continue;
            // detect roundtrip
			if ( board[nx][ny] == 1 ) { round = 1; roundtrips++; break; } // True
		}

        solutions++;
		printboard(round);

		board[x][y] = 0;
	    iters[iter] = 0;
		return;
	}

	// try next jump
    for (byte i = 0; i < 8; i++) {

		// new position
		byte nx = cast(byte)(x + jump[i][0]);
		byte ny = cast(byte)(y + jump[i][1]);

        // check if new position is on the board
		if ( nx<0 || nx>(SIZEX-1) || ny<0 || ny>(SIZEY-1) ) continue;

        //  check if new field position is still empty
		if ( board[nx][ny] != 0 ) continue;

		jumpto(nx, ny, cast(byte)(iter + 1), i);
	}

	// this iteration is done
	board[x][y] = 0;
	iters[iter] = 0;

}

void printboard(int round) {
	printf("===== Solution # %ld - Roundtripps: %ld ====== ", solutions, roundtrips);
	if (round) printf(" *** Roundtrip *** ");
	printf("\n");
    for	(int i = 0; i < SIZEY; i++) {
	    for (int j = 0; j < SIZEX; j++) {
			printf("%2i:", board[j][i]);
		}
		printf("\n");
	}
	printf("\n");
}

// EOF
