//initialise stuff #declare BOARDSIZE = 8; #declare OK=1; #declare NOT_OK=0; #declare AVAIL=-1; #declare board = array[ BOARDSIZE ][ BOARDSIZE ] #declare positions = array[ BOARDSIZE ] #declare i=0; #while(i < BOARDSIZE ) #declare j=0; #while( j < BOARDSIZE ) #declare board[i][j] = AVAIL; //Fills the array with -1's #declare j=j+1; #end //j loop #declare positions[i] = < 0, 0, 0 >; //y value not used #declare i=i+1; #end //i loop #macro MarkSquares( i, j, index ) #render concat( "Found a spot at:", str( i, 0, 0 ), ",", str( j, 0, 0 ), "\n" ) #declare board[i][j] = index; //Mark that square as unavailable. #declare positions[index] = < i, 0, j >; //Record queen position #local k=0; #local b=j-i; //ordinate at origin of 1st diag. #local c= i+j; //absissa at origin of 2nd diag. #while ( k < BOARDSIZE ) #if( board[k][j] = AVAIL ) #declare board[k][j] = index; //mark horizontal takable squares #end //if #if( board[i][k] = AVAIL ) #declare board[i][k] = index; //mark vertical takable squares #end //if #if( (k+b >= 0) & ( k+b < BOARDSIZE) ) #if( board[k][k+b] = AVAIL ) #declare board[k][k+b] = index; //mark first diagonal #end //if board #end //if k+b #if( (c-k>=0) & ( (c-k) < BOARDSIZE ) ) #if( board[c-k][k] = AVAIL ) #declare board[c-k][k] = index; //mark second diagonal #end //if board #end //if c-k #local k=k+1; #end //k loop /* --- debug --- #local a=0; #while( a < BOARDSIZE ) #local b=0; #while( b < BOARDSIZE ) #render str( board[b][a], 3, 0 ) #local b=b+1; #end //b loop #render "\n" #local a=a+1; #end //a loop --- debug --- */ #end //macro #macro UnmarkSquares( i, j, index ) #render concat( "Removing queen ", str( index, 0, 0 ), " at:", str( i, 0, 0 ), ",", str( j, 0, 0 ), "\n" ) #declare board[i][j] = AVAIL; //Mark that square as available. #declare positions[index] = < 0, 0, 0 >; //Remove queen position #local k=0; #local b=j-i; //ordinate at origin of 1st diag. #local c= i+j; //absissa at origin of 2nd diag. #while ( k < BOARDSIZE ) #if( board[k][j] = index ) #declare board[k][j] = AVAIL; //unmark horizontal takable squares #end //if #if( board[i][k] = index ) #declare board[i][k] = AVAIL; //unmark vertical takable squares #end //if #if( (k+b >= 0) & ( k+b < BOARDSIZE) ) #if( board[k][k+b] = index ) #declare board[k][k+b] = AVAIL; //unmark first diagonal #end #end //if #if( (c-k >= 0) & ( c-k < BOARDSIZE) ) #if( board[c-k][k] = index ) #declare board[c-k][k] = AVAIL; //unmark second diagonal #end #end //if #local k=k+1; #end //k loop /* --- debug --- #local a=0; #while( a < BOARDSIZE ) #local b=0; #while( b < BOARDSIZE ) #render str( board[b][a], 3, 0 ) #local b=b+1; #end //b loop #render "\n" #local a=a+1; #end //a loop --- debug --- */ #end //macro #macro PlaceQueen( index, status ) #if( index >= BOARDSIZE ) #error "OOPS! We have too many queens!!!\n" //Sanity check! #end //if #render concat( "Placing queen number:", str( index,0,0 ), "\n" ) #local i=0; //find first available spot #while( (i < BOARDSIZE) & (status=NOT_OK) ) #local j=0; #while( (j < BOARDSIZE) & (status=NOT_OK) ) #if( board[i][j] = AVAIL ) MarkSquares( i, j, index ) //Mark the squares that this queen controls #if( index = BOARDSIZE-1 ) //Congrats! we have done it #declare status = OK; #else PlaceQueen( index+1, status ) //recurse #if( status = NOT_OK ) //it did not work! UnmarkSquares( i, j, index ) //clean up #end //if status #end //if index #end //if board #declare j=j+1; #end //j loop #declare i=i+1; #end //i loop #end //macro #declare status = NOT_OK; PlaceQueen( 0, status) light_source{ < 100, 100, 100 > color rgb 1 } camera{ location < 4, 3, -5 > look_at < 4, 0, 4 > } box{ < 0, -0.25, 0 > < 8, 0, 8 > texture { pigment { checker rgb 1 rgb 0 } } } #declare i=0; #while( i < BOARDSIZE ) cylinder{ positions[i], positions[i]+y, 0.25 texture{ pigment{ color rgb < 1, 0, 0 > }} translate < 0.5, 0, 0.5 > } #declare i=i+1; #end //i loop