64 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
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
 |