1
7
8 Function printString(PointerToCharacter str)
11 Which Returns Nothing Is External;
12 Function clearScreen() Which Returns Nothing Is External;
13 Function shouldWePrintChessBoards() Which Returns Integer32 Is External;
14
15 Structure Queen Consists Of
17 Integer32 row, column;
18 EndStructure
19
20 Function areQueensInTheSameColumn(PointerToQueen first, PointerToQueen second)
21 Which Returns Integer32 Does
22 Return first->column = second->column;
23 EndFunction
24
25 Function areQueensInTheSameRow(PointerToQueen first, PointerToQueen second)
26 Which Returns Integer32 Does
27 Return first->row = second->row;
28 EndFunction
29
30 Function areQueensOnTheSameDiagonal(PointerToQueen first,
31 PointerToQueen second)
32 Which Returns Integer32 Does
33 Return first->row + first->column = second->row + second->column or
34 first->row - first->column = second->row - second->column;
35 EndFunction
36
37 Function areQueensAttackingEachOther(PointerToQueen first,
38 PointerToQueen second)
39 Which Returns Integer32 Does
40 Return areQueensInTheSameRow(first, second) or
41 areQueensInTheSameColumn(first, second) or
42 areQueensOnTheSameDiagonal(first, second);
43 EndFunction
44
45 Structure ChessBoard Consists Of
47 Integer32 length;
48 Queen queens[12]; EndStructure
50
51 Function chessBoardContainsThatQueen(PointerToChessBoard chessBoard,
52 PointerToQueen queen)
53 Which Returns Integer32 Does
54 Integer32 i := 0;
55 While i < chessBoard->length Loop
56 If chessBoard->queens[i].column = queen->column and
57 chessBoard->queens[i].row = queen->row Then
58 Return 1;
59 EndIf
60 i += 1;
61 EndWhile
62 Return 0;
63 EndFunction
64
65 Function validatePartialSolutionAndTryToExtend(PointerToChessBoard chessBoard,
68 Integer32 n)
69 Which Returns Integer32 Is Declared;
70
71 Function convertIntegerToString(PointerToCharacter str,
72 Integer32 n)
73 Which Returns Nothing Is Declared;
74
75 Function strcat(PointerToCharacter dest,
76 PointerToCharacter src) Which Returns Nothing Is Declared;
77
78 Function strlen(PointerToCharacter str) Which Returns Integer32 Is Declared;
79
80 Function nQueensPuzzle(Integer32 n) Which Returns Integer32 Does
82 clearScreen();
83 If not(1 <= n <= 12) Then
84 printString("Please enter a number between 1 and 12!");
85 Return -1;
86 EndIf
87 InstantiateStructure ChessBoard chessBoard;
88 Character stringToBePrinted[64] := {0};
89 PointerToCharacter stringToBePrinted := AddressOf(stringToBePrinted[0]);
90 strcat(stringToBePrinted, "Solving the n-queens puzzle for ");
91 convertIntegerToString(stringToBePrinted + strlen(stringToBePrinted),
92 n);
93 strcat(stringToBePrinted,":\n");
94 printString(stringToBePrinted);
95 Integer32 result := validatePartialSolutionAndTryToExtend(AddressOf(chessBoard), n);
96 stringToBePrinted[0] := 0;
97 strcat(stringToBePrinted, "Found ");
98 convertIntegerToString(stringToBePrinted + strlen(stringToBePrinted),
99 result);
100 strcat(stringToBePrinted, " solutions!");
101 printString(stringToBePrinted);
102 Return result;
103 EndFunction
104
105 Function printAsASolution(PointerToChessBoard chessBoard)
108 Which Returns Nothing Does
109 Character stringToBePrinted[64] := {0};
110 Character stringToBeAdded[8];
111 Integer32 i := 0;
112 While i < chessBoard->length Loop
113 stringToBeAdded[0] := 'A' + chessBoard->queens[i].column;
114 convertIntegerToString(AddressOf(stringToBeAdded[1]),
115 chessBoard->queens[i].row + 1);
116 strcat(AddressOf(stringToBeAdded[0]), " ");
117 strcat(AddressOf(stringToBePrinted[0]),
118 AddressOf(stringToBeAdded[0]));
119 i += 1;
120 EndWhile
121 strcat(AddressOf(stringToBePrinted[0]), "\n");
122 printString(AddressOf(stringToBePrinted[0]));
123 If shouldWePrintChessBoards() Then
124 stringToBePrinted[0] := 0;
125 PointerToCharacter stringToBePrinted := AddressOf(stringToBePrinted[0]);
126 strcat(stringToBePrinted, " +");
127 i := 0;
128 While i < chessBoard->length Loop
129 strcat(stringToBePrinted, "-+");
130 i += 1;
131 EndWhile
132 strcat(stringToBePrinted, "\n");
133 printString(stringToBePrinted);
134 i := chessBoard->length;
135 While i > 0 Loop
136 stringToBePrinted[0] := 0;
137 If i < 10 Then
139 strcat(stringToBePrinted, " ");
140 EndIf
141 convertIntegerToString(stringToBePrinted + strlen(stringToBePrinted), i);
142 strcat(stringToBePrinted, "|");
143 Integer32 j := 0;
144 While j < chessBoard->length Loop
145 InstantiateStructure Queen newQueen;
146 newQueen.column := j;
147 newQueen.row := i - 1;
148 strcat(stringToBePrinted,
149 chessBoardContainsThatQueen(chessBoard, AddressOf(newQueen))?
150 "Q|":
151 mod(i + j - 1, 2)?
152 " |": "*|" );
155 j += 1;
156 EndWhile
157 strcat(stringToBePrinted, "\n");
158 printString(stringToBePrinted);
159 stringToBePrinted[0] := 0;
160 strcat(stringToBePrinted, " +");
161 j := 0;
162 While j < chessBoard->length Loop
163 strcat(stringToBePrinted, "-+");
164 j += 1;
165 EndWhile
166 strcat(stringToBePrinted, "\n");
167 printString(stringToBePrinted);
168 i -= 1;
169 EndWhile
170 stringToBePrinted[0] := 0;
171 PointerToCharacter stringToBeAdded := AddressOf(stringToBeAdded[0]);
172 stringToBeAdded[2] := 0;
173 stringToBeAdded[0] := ' ';
174 strcat(stringToBePrinted, " ");
175 i := 0;
176 While i < chessBoard->length Loop
177 stringToBeAdded[1] := 'A' + i;
178 strcat(stringToBePrinted, stringToBeAdded);
179 i += 1;
180 EndWhile
181 strcat(stringToBePrinted, "\n");
182 printString(stringToBePrinted);
183 EndIf
184 EndFunction
185
186 Function validatePartialSolutionAndTryToExtend (PointerToChessBoard chessBoard,
190 Integer32 n)
191 Which Returns Integer32 Does
192 If chessBoard->length > n Then
194 printString("Bug: Chessboard length too large!");
195 Return 0;
196 EndIf
197 Integer32 i := 0, j := 0;
198 While i < chessBoard->length Loop
199 If chessBoard->queens[i].column < 0 or
200 chessBoard->queens[i].row < 0 or
201 chessBoard->queens[i].column > n or
202 chessBoard->queens[i].row > n Then
203 printString("Bug: Corrupt chessboard!");
204 Return 0;
205 EndIf
206 i += 1;
207 EndWhile
208 i := j := 0;
211 While i < chessBoard->length Loop
212 j := i + 1;
213 While j < chessBoard->length Loop
214 If not(i = j) and areQueensAttackingEachOther(
215 AddressOf(chessBoard->queens[i]),
216 AddressOf(chessBoard->queens[j])
217 ) Then
218 Return 0;
219 EndIf
220 j += 1;
221 EndWhile
222 i += 1;
223 EndWhile
224 If chessBoard->length = n Then
226 printAsASolution(chessBoard);
227 Return 1;
228 EndIf
229 Integer32 result := 0;
233 i := 0;
234 While i<n Loop
235 InstantiateStructure ChessBoard newChessBoard := ValueAt(chessBoard);
236 newChessBoard.length += 1;
237 newChessBoard.queens[chessBoard->length].column := chessBoard->length;
238 newChessBoard.queens[chessBoard->length].row := i;
239 result += validatePartialSolutionAndTryToExtend(AddressOf(newChessBoard), n);
240 i += 1;
241 EndWhile
242 Return result;
243 EndFunction
244
245 Function strlen(PointerToCharacter str) Which Returns Integer32 Does
249 Integer32 length := 0;
250 While ValueAt(str + length) Loop
251 length := length + 1;
252 EndWhile
253 Return length;
254 EndFunction
255
256 Function strcpy(PointerToCharacter dest,
257 PointerToCharacter src) Which Returns Nothing Does
258 While ValueAt(src) Loop
259 ValueAt(dest) := ValueAt(src);
260 dest := dest + 1;
261 src := src + 1;
262 EndWhile
263 ValueAt(dest) := 0;
264 EndFunction
265
266 Function strcat(PointerToCharacter dest,
267 PointerToCharacter src) Which Returns Nothing Does
268 strcpy(dest + strlen(dest), src);
269 EndFunction
270
271 Function reverseString(PointerToCharacter string) Which Returns Nothing Does
272 PointerToCharacter pointerToLastCharacter := string + strlen(string) - 1;
273 While pointerToLastCharacter - string > 0 Loop
274 Character tmp := ValueAt(string);
275 ValueAt(string) := ValueAt(pointerToLastCharacter);
276 ValueAt(pointerToLastCharacter) := tmp;
277 string := string + 1;
278 pointerToLastCharacter := pointerToLastCharacter - 1;
279 EndWhile
280 EndFunction
281
282 Function convertIntegerToString(PointerToCharacter string,
283 Integer32 number)
284 Which Returns Nothing Does
285 Integer32 isNumberNegative := 0;
286 If number < 0 Then
287 number := -number;
288 isNumberNegative := 1;
289 EndIf
290 Integer32 i := 0;
291 While number > 9 Loop
292 ValueAt(string + i) := '0' + mod(number, 10);
293 number := number / 10;
294 i := i + 1;
295 EndWhile
296 ValueAt(string + i) := '0' + number;
297 i := i + 1;
298 If isNumberNegative Then
299 ValueAt(string + i) := '-';
300 i := i + 1;
301 EndIf
302 ValueAt(string + i) := 0;
303 reverseString(string);
304 EndFunction
305