00050 .PR POINT .PR 00110 # QUEEN # 00120 .COMMENT THIS PROGRAM PLACES 8 QUEENS ON A CHESSBOARD 00130 SUCH THAT NO TWO QUEENS ATTACK ONE ANOTHER. THE METHOD USED 00140 IS OF RECURSIVE DESCENT : ALL VALID POSSIBILITIES 00150 ON A GIVEN ROW ARE TRIED - EACH PRODUCES ANOTHER BRANCH OF 00160 POSSIBILITIES ON FURTHER ROWS. IF A QUEEN MAY BE PLACED ON THE 00170 LAST ROW THEN THIS IS A SOLUTION AND IS OUTPUT. 00180 NOTE: TO SAVE MACHINE TIME SIMPLE REFLECTIONS ARE PRODUCED 00190 MECHANICALLY IF EXHAUSTIVE SOLUTIONS ARE ONLY FOUND FOR 00200 THE QUEEN ON THE FIRST ROW POSITIONS 1,2,3,4. THE 00210 SYMMETRY OF THE CHESSBOARD MEANS THAT SOLUTIONS WITH 00220 THE QUEEN IN ROW 1 IN POSITIONS 5,6,7,8 CORRESPOND 1-1 00230 WITH THESE. 00240 .COMMENT 00250 ## 00260 .BEGIN 00270 .LOC .INT ROW := 0, COUNTSOLN := 0; 00280 .LOC[1:8].INT RESULT; 00282 .LOC[1:8, -6:15].BOOL ALLOWS; 00290 ## 00300 .PROC SOLUTIONHEAD = .VOID: 00310 .BEGIN PRINT((NEWLINE, "SOLUTION", WHOLE(COUNTSOLN, -5), ":- ")); COUNTSOLN +:=1 .END; 00320 ## 00330 .PROC PLACE = (.INT POSITION).VOID: 00340 .COMMENT THIS IS A RECURSIVE PROCEDURE. 00350 IT ALLOCATES ALL POSSIBLE VALUES IN THE CURRENT ROW AS DEFINED 00360 BY EACH ROW. AFTER CONSIDERING WHICH SQUARES ARE NOT PERMISSIBLE 00370 (BECAUSE ALREADY ATTACKED), IT OUTPUTS ANY SOLUTIONS IT FINDS 00380 (I.E. WHEN WE REACH THE LAST ROW). 00390 .COMMENT 00400 .BEGIN 00420 ROW +:= 1; RESULT[ROW] := POSITION; 00422 .REF [] .BOOL ALLOW = ALLOWS[ROW, ]; 00430 .IF ROW=8 00440 .THEN #WE HAVE FOUND SOLUTION NUMBER COUNTSOLN 00450 SO OUTPUT IT# 00460 SOLUTIONHEAD; 00470 .FOR K .TO 8 .DO PRINT(.REPR(RESULT[K]+.ABS"0")) .OD; 00480 SOLUTIONHEAD; 00490 .FOR K .TO 8 .DO PRINT(.REPR(9-RESULT[K]+.ABS"0")) .OD 00500 .ELSE 00510 .FOR I .TO 8 .DO ALLOW[I] := .TRUE .OD; 00520 #DISALLOW ATTACKED SQUARES# 00530 .FOR I .TO ROW 00540 .DO .INT RES = RESULT[I]; 00550 ALLOW[RES] := .FALSE; 00560 ALLOW[RES+ROW+1-I] := .FALSE; 00570 ALLOW[RES-ROW-1+I] := .FALSE 00580 .OD; 00590 #CONSTRUCT ANOTHER LEVEL WHERE POSSIBLE# 00600 .FOR I .TO 8 .DO .IF ALLOW[I] .THEN PLACE(I) .FI .OD 00610 .FI; 00620 #NOW UP A LEVEL# 00630 ROW -:= 1 00640 .END; #OF PLACE# 00650 ## 00660 #INITIALISE OUTPUT# 00670 PRINT(("PLACEMENT OF QUEENS SUCH THAT NO TWO" 00680 " ATTACK EACH OTHER", NEWLINE)); 00690 .FOR J .TO 4 .DO PLACE(J) .OD; 00700 #TIDY UP OUTPUT# 00710 PRINT(("LIST COMPLETE", NEWLINE)) 00720 .END