Rebol3 Code Examplex
Knight's tour
Find a path that visits every square of a chessboard once.
Rebol [
title: "Rosetta code: Knight's tour"
file: %Knight's_tour.r3
url: https://rosettacode.org/wiki/Knight%27s_tour
]
knights-tour: function/with [
board-size [integer!]
][
;; Prepare board...
brd: make block! size: board-size
loop size [
row: make block! size
append/dup row 0 size
append/only brd row
]
;; Starting position...
pos: as-pair random size random size
brd/(pos/x)/(pos/y): 1
;; Found solutions...
found: solve pos 2
either found [
print-brd print ""
][ print ["no solutions found:" pos] ]
][
dirs: [1x2 1x-2 2x1 2x-1 -1x2 -1x-2 -2x-1 -2x1]
size: brd: pos: none
cnt-moves: function [m [pair!]] [
n: 0
foreach d dirs [
p: m + d
rn: p/x
cn: p/y
if all [
rn >= 1 rn <= size
cn >= 1 cn <= size
zero? brd/:rn/:cn
][
n: n + 1
]
]
n
]
sort-moves: function [movs [block!]] [
cnt: map-each m movs [cnt-moves m]
i: 1
while [i <= ((length? cnt) - 1)] [
j: i + 1
while [j <= length? cnt] [
if cnt/:j < cnt/:i [
tmp: cnt/:i cnt/:i: cnt/:j cnt/:j: tmp
tmp: movs/:i movs/:i: movs/:j movs/:j: tmp
]
j: j + 1
]
i: i + 1
]
movs
]
solve: function [pos [pair!] cnt] [
if cnt > (size * size) [return true]
movs: make block! 8
foreach d dirs [
p: pos + d
rn: p/x cn: p/y
if all [
rn >= 1 rn <= size
cn >= 1 cn <= size
zero? brd/:rn/:cn
][
append movs p
]
]
movs: sort-moves movs
foreach p movs [
rn: p/x cn: p/y
brd/:rn/:cn: cnt
if solve p cnt + 1 [return true]
brd/:rn/:cn: 0
]
false
]
print-brd: func [/local fmt] [
foreach row brd [
foreach cell row [prin pad cell 4]
print ""
]
]
]
knights-tour 8
knights-tour 16Output:
34 59 12 51 36 47 10 49
13 52 35 60 11 50 23 46
58 33 64 53 44 37 48 9
63 14 55 38 61 22 45 24
32 57 62 43 54 25 8 21
15 42 29 56 39 18 5 2
28 31 40 17 26 3 20 7
41 16 27 30 19 6 1 4
160 21 206 245 162 23 208 175 164 25 186 177 120 27 122 179
205 240 161 22 207 246 163 24 209 176 165 26 187 178 119 28
20 159 244 241 248 253 230 227 174 189 210 185 166 121 180 123
221 204 239 254 237 242 247 252 229 226 173 188 181 184 29 118
158 19 222 243 256 249 228 231 190 233 182 211 172 167 124 169
203 220 255 238 223 236 251 234 225 214 191 138 183 170 117 30
18 157 200 217 250 151 224 215 232 141 212 171 116 125 168 113
197 202 219 154 199 216 235 150 213 192 137 142 139 114 31 78
156 17 198 201 218 149 152 193 136 143 140 115 126 79 112 1
47 196 155 148 153 194 135 144 109 90 127 104 111 96 77 32
16 147 48 195 134 145 108 89 128 105 110 91 80 103 2 95
49 46 133 146 59 64 129 106 99 84 87 102 97 92 33 76
132 15 50 63 130 107 54 83 88 101 98 81 86 75 94 3
45 12 131 58 53 60 65 100 55 82 85 74 93 36 69 34
14 51 10 43 62 57 8 41 66 73 6 39 68 71 4 37
11 44 13 52 9 42 61 56 7 40 67 72 5 38 35 70