How to resolve the algorithm Knight's tour step by step in the EchoLisp programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Knight's tour step by step in the EchoLisp programming language

Table of Contents

Problem Statement

Problem: you have a standard 8x8 chessboard, empty but for a single knight on some square. Your task is to emit a series of legal knight moves that result in the knight visiting every square on the chessboard exactly once. Note that it is not a requirement that the tour be "closed"; that is, the knight need not end within a single move of its start position. Input and output may be textual or graphical, according to the conventions of the programming environment. If textual, squares should be indicated in algebraic notation. The output should indicate the order in which the knight visits the squares, starting with the initial position. The form of the output may be a diagram of the board with the squares numbered according to visitation sequence, or a textual list of algebraic coordinates in order, or even an actual animation of the knight moving around the chessboard. Input: starting square Output: move sequence

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Knight's tour step by step in the EchoLisp programming language

Source code in the echolisp programming language

(require 'plot)
(define *knight-moves* 
	'((2 . 1)(2 . -1 ) (1 . -2) (-1 . -2  )(-2 . -1) (-2 . 1) (-1 . 2) (1 . 2))) 
(define *hit-squares* null)
(define *legal-moves* null)
(define *tries* 0)

(define (square x y n ) (+ y (* x n)))
(define (dim n) (1- (* n n))) ; n^2 - 1

;; check legal knight move from sq
;; return null or (list destination-square)

(define (legal-disp n sq k-move)
 (let ((x (+ (quotient sq n) (first k-move)))
 	   (y (+  (modulo sq n)  (rest k-move))))
 	   (if (and (>= x 0) (< x n) (>= y 0) (< y n))
 	       (list (square x y n))  null)))
 	       
 ;; list of legal destination squares from sq
 (define (legal-moves  sq  k-moves n )
           (if (null? k-moves) null
           (append (legal-moves sq (rest k-moves) n) (legal-disp n sq (first k-moves)))))

;; square freedom = number of destination squares not already reached
(define (freedom sq)
		(for/sum ((dest (vector-ref *legal-moves* sq)))
				(if (vector-ref *hit-squares* dest) 0 1)))
				
;; The chess adage" A knight on the rim is dim" is false here :
;; choose to move to square with smallest freedom : Warnsdorf's rule
(define (square-sort a b)
	(< (freedom a) (freedom b)))
				
;; knight tour engine
(define (play sq step starter last-one wants-open)
(set! *tries* (1+ *tries*))
		(vector-set! *hit-squares* sq step) ;; flag used square
		(if (= step last-one) (throw 'HIT last-one)) ;; stop on first path found

		(when (or wants-open ;; cut search iff closed path
		(and  (< step last-one) (> (freedom starter) 0))) ;; this ensures a closed path
		
		(for ((target (list-sort square-sort (vector-ref *legal-moves* sq))))
			 (unless (vector-ref *hit-squares* target)
			         (play target (1+ step)  starter last-one wants-open))))
		(vector-set! *hit-squares* sq #f)) ;; unflag used square
		
(define (show-steps n wants-open)
	(string-delimiter "")
	(if wants-open
		(printf "♘-tour: %d tries."  *tries*)
		(printf "♞-closed-tour: %d tries."  *tries*))
	(for ((x n))
		(writeln)
		(for((y n))
        	(write (string-pad-right (vector-ref *hit-squares*  (square x y n)) 4)))))


(define (k-tour (n  8) (starter 0) (wants-open #t))
(set! *hit-squares* (make-vector (* n n) #f))
;; build vector of legal moves for squares 0..n^2-1
(set! *legal-moves* 
		(build-vector (* n n) (lambda(sq) (legal-moves sq *knight-moves* n))))
(set! *tries* 0) ; counter
	(try
		(play starter 0 starter (dim n) wants-open)
		(catch (hit mess) (show-steps n wants-open))))


(k-tour 8 0 #f)
♞-closed-tour: 66 tries.
0   47  14  31  62  27  12  29 
15  32  63  54  13  30  57  26 
48  1   46  61  56  59  28  11 
33  16  55  50  53  44  25  58 
2   49  42  45  60  51  10  39 
17  34  19  52  43  40  7   24 
20  3   36  41  22  5   38  9  
35  18  21  4   37  8   23  6  

(k-tour 20 57)
♘-tour: 400 tries.
31  34  29  104 209 36  215 300 211 38  213 354 343 40  345 386 383 42  1   388
28  103 32  35  216 299 210 37  214 335 342 39  346 385 382 41  390 387 396 43 
33  30  105 208 201 308 301 336 323 212 353 340 355 344 391 384 395 0   389 2  
102 27  202 219 298 217 322 309 334 341 356 347 358 351 376 381 378 399 44  397
203 106 207 200 307 228 311 302 337 324 339 352 373 364 379 392 375 394 3   368
26  101 220 229 218 297 304 321 310 333 348 357 350 359 374 377 380 367 398 45 
107 204 199 206 227 306 231 312 303 338 325 330 363 372 365 328 393 254 369 4  
100 25  122 221 230 233 296 305 320 313 332 349 326 329 360 371 366 251 46  253
121 108 205 198 145 226 237 232 295 286 319 314 331 362 327 316 255 370 5   178
24  99  144 123 222 129 234 279 236 281 294 289 318 315 256 361 250 179 252 47 
109 120 111 130 197 146 225 238 285 278 287 272 293 290 317 180 257 162 177 6  
98  23  124 143 128 223 276 235 280 239 282 291 288 265 270 249 176 181 48  161
115 110 119 112 131 196 147 224 277 284 273 266 271 292 245 258 163 174 7   58 
22  97  114 125 142 127 140 275 194 267 240 283 264 269 248 175 182 59  160 49 
87  116 95  118 113 132 195 148 187 274 263 268 191 244 259 246 173 164 57  8  
96  21  88  133 126 141 150 139 262 193 190 241 260 247 172 183 60  159 50  65 
77  86  117 94  89  138 135 188 149 186 261 192 171 184 243 156 165 64  9   56 
20  81  78  85  134 93  90  151 136 189 170 185 242 155 166 61  158 53  66  51 
79  76  83  18  91  74  137 16  169 72  153 14  167 70  157 12  63  68  55  10 
82  19  80  75  84  17  92  73  152 15  168 71  154 13  62  69  54  11  52  67


(define (step-color x y n last-one)
		(letrec ((sq (square (floor x) (floor y) n))
		(step (vector-ref *hit-squares* sq) n n))
		(cond ((= 0 step) (rgb 1 0 0)) ;; red starter
			  ((= last-one step) (rgb 0 1 0)) ;; green end
			  (else (gray (// step n n))))))
		
(define  ( k-plot n)
	(plot-rgb (lambda (x y) (step-color x y n (dim n))) (- n epsilon) (- n epsilon)))


  

You may also check:How to resolve the algorithm Pinstripe/Display step by step in the Delphi programming language
You may also check:How to resolve the algorithm Terminal control/Ringing the terminal bell step by step in the FreeBASIC programming language
You may also check:How to resolve the algorithm A+B step by step in the Lasso programming language
You may also check:How to resolve the algorithm Execute HQ9+ step by step in the Ursala programming language
You may also check:How to resolve the algorithm Ramanujan's constant step by step in the Nim programming language