1 // jumpsaround.go - jumper game 2 // (c) 2020 Alexander Kulbartsch 3 // 4 // Slightly performace optimized version: valid jumpes checked bevore iteration. 5 // added restricted multithreading 6 7 package main 8 9 import ( 10 "fmt" 11 "sync" 12 "sync/atomic" 13 ) 14 15 const SIZEX = 6 16 const SIZEY = 5 17 const SPAWN = 2 18 19 type boardt [SIZEX][SIZEY]int32 20 var jump = [8][2]int32{{-1,-2}, {1,-2}, {-2,-1}, {2,-1}, {-2,1}, {2,1}, {-1,2}, {1,2}} 21 var solutions int32 = 0 22 var roundtrips int32 = 0 23 24 var wg sync.WaitGroup 25 var mutex sync.Mutex 26 27 func main() { 28 fmt.Println("Hello, Jumper!") 29 var board boardt 30 jumpto(board, 0, 0, 1) 31 wg.Wait() // waiting for waitgroup processes 32 fmt.Println("===== Solution #", solutions," (Roundtripps:", roundtrips, ") ====== ") 33 fmt.Println("I am done.") 34 } 35 36 37 func jumpto(board boardt, x, y, iter int32) { 38 39 if iter == (SPAWN + 1) { 40 defer wg.Done() 41 } 42 43 // ok - store position 44 board[x][y] = iter 45 46 // finished ? 47 if iter >= SIZEX*SIZEY { 48 49 // check for jumper roundtrips 50 round := false 51 for _, d := range jump { 52 nx := x + d[0] 53 ny := y + d[1] 54 // check if position is on the board 55 if nx<0 || nx>(SIZEX-1) || ny<0 || ny>(SIZEY-1) { continue } 56 // detect roundtrip 57 if board[nx][ny] == 1 { round = true; atomic.AddInt32(&roundtrips,1); break } // True 58 } 59 60 atomic.AddInt32(&solutions, 1) 61 62 printboard(board, round) 63 64 //board[x][y] = 0 // it's local 65 66 return 67 } 68 69 // try next jump 70 for _, d := range jump { 71 nx := x + d[0] 72 ny := y + d[1] 73 74 // check if position is on the board 75 if nx<0 || nx>(SIZEX-1) || ny<0 || ny>(SIZEY-1) { continue } 76 77 // check if new field position is still empty 78 if board[nx][ny] != 0 { continue } // True 79 80 if iter == SPAWN { // SPAWN = 2 // <<-- 81 wg.Add(1) 82 go jumpto(board, nx, ny, iter + 1); // <<-- 83 } else { 84 jumpto(board, nx, ny, iter + 1); // <<-- 85 } 86 } 87 88 // this iteration is done 89 board[x][y] = 0; 90 91 } 92 93 94 func printboard(board boardt, round bool) { 95 mutex.Lock() // <<-- 96 if round == true { fmt.Println(" *** Roundtrip #", roundtrips, "*** ") 97 fmt.Println("") 98 for i := 0; i < SIZEY; i++ { 99 for j := 0; j < SIZEX; j++ { 100 fmt.Printf("%2d:", board[j][i]) 101 } 102 fmt.Println("") 103 } 104 fmt.Println("") 105 } 106 mutex.Unlock() // <<-- 107 } 108 109 // EOF