// jumpsaround.go - jumper game
// (c) 2020 Alexander Kulbartsch
// 
// (slightly performace optimized version: valid jumpes checked bevore iteration.)

package main

import (
    "fmt"      
)

const SIZEX = 6
const SIZEY = 5

type boardt [SIZEX][SIZEY]int32
var board boardt
var jump = [8][2]int32{{-1,-2}, {1,-2}, {-2,-1}, {2,-1}, {-2,1}, {2,1}, {-1,2}, {1,2}}
var solutions int32  = 0
var roundtrips int32 = 0


func main() {
    fmt.Println("Hello, Jumper!")
	
	jumpto(0, 0, 1)
    
	fmt.Println("I am done.")
}


func jumpto(x, y, iter int32) {

	// ok - store position
	board[x][y] = iter
	
	// finished?
	if iter >= SIZEX*SIZEY {

		// check for jumper roundtrips
	 	round := false
	 	for _, d := range jump {
	 		nx := x + d[0]
	 		ny := y + d[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 = true; roundtrips++; break } // True
	 	}

        solutions++

		printboard(round)

		board[x][y] = 0
		
		return
	}
	
	// try next jump
    for _, d := range jump {
 		nx := x + d[0]
 		ny := y + d[1]

 		// check if 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 } // True

		jumpto(nx, ny, iter + 1);
	}
	
	// this iteration is done
	board[x][y] = 0;
	
}


func printboard(round bool) {
	fmt.Println("===== Solution #", solutions," - Roundtripps:", roundtrips, " ====== ")
	if round == true { fmt.Println(" *** Roundtrip *** ") }
	fmt.Println("")
    for	i := 0; i < SIZEY; i++ {
	    for j := 0; j < SIZEX; j++ {
			fmt.Printf("%2d:", board[j][i])
		}
		fmt.Println("")
	}
    fmt.Println("")
}

// EOF
