home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v941.tgz
/
icon.v941src.tar
/
icon.v941src
/
ipl
/
progs
/
vnq.icn
< prev
next >
Wrap
Text File
|
2000-07-29
|
4KB
|
166 lines
############################################################################
#
# File: vnq.icn
#
# Subject: Program to display solutions to n-queens problem
#
# Author: Stephen B. Wampler
#
# Date: August 14, 1996
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# This program displays solutions to the n-queens problem.
#
############################################################################
#
# Links: options
#
############################################################################
link options
global n, nthq, solution, goslow, showall, line, border
procedure main(args)
local i, opts
opts := options(args, "sah")
n := integer(get(args)) | 8 # default is 8 queens
if \opts["s"] then goslow := "yes"
if \opts["a"] then showall := "yes"
if \opts["h"] then helpmesg()
line := repl("| ", n) || "|"
border := repl("----", n) || "-"
clearscreen()
movexy(1, 1)
write()
write(" ", border)
every 1 to n do {
write(" ", line)
write(" ", border)
}
nthq := list(n+2) # need list of queen placement routines
solution := list(n) # ... and a list of column solutions
nthq[1] := &main # 1st queen is main routine.
every i := 1 to n do # 2 to n+1 are real queen placement
nthq[i+1] := create q(i) # routines, one per column.
nthq[n+2] := create show() # n+2nd queen is display routine.
write(n, "-Queens:")
@nthq[2] # start by placing queen in first colm.
movexy(1, 2 * n + 5)
end
# q(c) - place a queen in column c (this is c+1st routine).
procedure q(c)
local r
static up, down, rows
initial {
up := list(2 * n -1, 0)
down := list(2 * n -1, 0)
rows := list(n, 0)
}
repeat {
every (0 = rows[r := 1 to n] = up[n + r - c] = down[r + c -1] &
rows[r] <- up[n + r - c] <- down[r + c -1] <- 1) do {
solution[c] := r # record placement.
if \showall then {
movexy(4 * (r - 1) + 5, 2 * c + 1)
writes("@")
}
@nthq[c + 2] # try to place next queen.
if \showall then {
movexy(4 * (r - 1) + 5, 2 * c + 1)
writes(" ")
}
}
@nthq[c] # tell last queen placer 'try again'
}
end
# show the solution on a chess board.
procedure show()
local c
static count, lastsol
initial {
count := 0
}
repeat {
if /showall & \lastsol then {
every c := 1 to n do {
movexy(4 * (lastsol[c] - 1) + 5, 2 * c + 1)
writes(" ")
}
}
movexy(1, 1)
write("solution: ", right(count +:= 1, 10))
if /showall then {
every c := 1 to n do {
movexy(4 * (solution[c] - 1) + 5, 2 * c + 1)
writes("Q")
}
lastsol := copy(solution)
}
if \goslow then {
movexy(1, 2 * n + 4)
writes("Press return to see next solution:")
read() | {
movexy(1, 2 * n + 5)
stop("Aborted.")
}
movexy(1, 2 * n + 4)
clearline()
}
@nthq[n+1] # tell last queen placer to try again
}
end
procedure helpmesg()
write(&errout, "Usage: vnq [-s] [-a] [n]")
write(&errout, " where -s means to stop after each solution, ")
write(&errout, " -a means to show placement of every queen")
write(&errout, " while trying to find a solution")
write(&errout, " and n is the size of the board (defaults to 8)")
stop()
end
# Move cursor to x, y
#
procedure movexy (x, y)
writes("\^[[", y, ";", x, "H")
return
end
#
# Clear the text screen
#
procedure clearscreen()
writes("\^[[2J")
return
end
#
# Clear the rest of the line
#
procedure clearline()
writes("\^[[2K")
return
end