\codebegin{0}{io = input\_obj}\codeend
\codebegin{0}{wo = window\_obj}\codeend
\codebegin{0}{ub = undo\_buf}\codeend
\codebegin{0}{st = status}\codeend
\codebegin{0}{ac = {\bf array}[char]}\codeend
\codebegin{0}{stime = 1500}\codeend
\codebegin{0}{RED = `\verb^O^'}\codeend
\codebegin{0}{BLACK = `\verb^X^'}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{exec\_command = {\bf proc} (input: io, ho: wo, error: wo, stat: st, brd: board, }\codeend
\codebegin{21}{moves: ub) {\bf signals}(over,no\_command)}\codeend
\comment{\%}{4}{modifies:}{ input, help, error, stat, brd, moves
}
\comment{\%}{4}{}{}
\comment{\%}{4}{effects:}{ Executes the command listed in buf. If the command requires
an argument, but none is there or the arg given is wrong,
prints an error message to the error area represented by 
error. Once command is executed, clears input area, error
area, help area, and the input buffer.
}
\codebegin{3}{}\codeend
\codebegin{4}{wo\$clear(error)}\codeend
\codebegin{4}{wo\$clear(ho)}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{buf: ac := input.buffer}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{cmd: string := upcase(get\_command(buf)) {\bf resignal} no\_command}\codeend
\codebegin{4}{buf2: ac := string\$s2ac(cmd)}\codeend
\codebegin{4}{buf2 := completion(buf2)}\codeend
\codebegin{5}{{\bf except} {\bf when} invalid: }\codeend
\codebegin{8}{wo\$display(error,``\verb^Invalid command^'')}\codeend
\codebegin{8}{{\bf return}}\codeend
\codebegin{8}{{\bf end}}\codeend
\codebegin{4}{ccmd: string := string\$ac2s(buf2)}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{args: string := get\_args(buf, string\$size(cmd)+1)}\codeend
\codebegin{5}{{\bf except} {\bf when} no\_arg: }\codeend
\comment{\%}{8}{}{handle commands with no arguments
}
\codebegin{8}{io\$clear(input)}\codeend
\codebegin{11}{{\bf if} ccmd = ``\verb^ADVISE^'' {\bf then} advise(ho,brd,stat) {\bf return}}\codeend
\codebegin{10}{{\bf elseif} ccmd = ``\verb^NEW^'' {\bf then} new(brd, stat, ho, error, moves) {\bf return}}\codeend
\codebegin{10}{{\bf elseif} ccmd = ``\verb^EXIT^'' {$|$} ccmd = ``\verb^QUIT^'' {\bf then} signal over }\codeend
\codebegin{10}{{\bf elseif} ccmd = ``\verb^HELP^'' {\bf then} help\_general(ho) {\bf return} }\codeend
\codebegin{10}{{\bf elseif} ccmd = ``\verb^UNDO^'' {\bf then} undo(brd,moves,``\verb^1^'')}\codeend
\codebegin{13}{{\bf except} {\bf when} cannot\_undo: }\codeend
\codebegin{16}{wo\$display(error,``\verb^No moves to UNDO.^'') }\codeend
\codebegin{17}{{\bf except} {\bf when} too\_long: {\bf return} {\bf end}}\codeend
\codebegin{16}{{\bf return} {\bf end}}\codeend
\codebegin{12}{{\bf return}}\codeend
\comment{\%}{12}{}{or print an error if argument is required
}
\codebegin{10}{{\bf else} wo\$display(error,``\verb^Argument expected or invalid command^'')}\codeend
\codebegin{15}{{\bf return}}\codeend
\codebegin{13}{{\bf except} {\bf when} too\_long: {\bf return} {\bf end}}\codeend
\codebegin{12}{{\bf end}}\codeend
\codebegin{8}{{\bf end}}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{io\$clear(input)}\codeend
\comment{\%}{4}{}{handle commands with arguments, printing errors for bad args
}
\codebegin{4}{{\bf if} ccmd = ``\verb^MOVE^'' {\bf then} move(args,brd,ho,stat,moves) {\bf resignal} over}\codeend
\codebegin{9}{{\bf except} {\bf when} illegal\_move(m: string): }\codeend
\codebegin{12}{wo\$display(error,m) {\bf end}}\codeend
\codebegin{6}{{\bf elseif} ccmd = ``\verb^TIME^'' {\bf then} args := upcase(args); time(args,stat)}\codeend
\codebegin{9}{{\bf except} {\bf when} bad\_format: }\codeend
\codebegin{12}{wo\$display(error, ``\verb^Bad argument for TIME^'') {\bf end}}\codeend
\codebegin{9}{{\bf except} {\bf when} not\_possible(m:string):}\codeend
\codebegin{12}{wo\$display(error, ``\verb^Not possible: ^'' {$\|$} m) {\bf end}}\codeend
\codebegin{6}{{\bf elseif} ccmd = ``\verb^SAVE^'' {\bf then} save(args,brd,stat)}\codeend
\codebegin{9}{{\bf except} {\bf when} not\_possible: }\codeend
\codebegin{12}{wo\$display(error,``\verb^Cannot save to file: ^'' {$\|$} args) {\bf end}}\codeend
\codebegin{6}{{\bf elseif} ccmd = ``\verb^LOAD^'' {\bf then} load(args,brd,stat,moves)}\codeend
\codebegin{9}{{\bf except} {\bf when} bad\_format: }\codeend
\codebegin{12}{wo\$display(error,``\verb^Bad format for load file: ^'' {$\|$} args) {\bf end}}\codeend
\codebegin{9}{{\bf except} {\bf when} not\_possible: }\codeend
\codebegin{12}{wo\$display(error,``\verb^Empty file or cannot open: ^'' {$\|$} args) {\bf end}}\codeend
\codebegin{9}{{\bf except} {\bf when} bad\_arg(m:string):}\codeend
\codebegin{12}{wo\$display(error,``\verb^Bad value in load file: ^'' {$\|$} m) {\bf end}}\codeend
\codebegin{9}{{\bf except} {\bf when} over: {\bf signal} over {\bf end}}\codeend
\codebegin{6}{{\bf elseif} ccmd = ``\verb^DIFFICULTY^'' {\bf then} difficulty(args,stat)}\codeend
\codebegin{9}{{\bf except} {\bf when} invalid\_level: }\codeend
\codebegin{12}{wo\$display(error,``\verb^Invalid level: ^'' {$\|$} args) {\bf end}}\codeend
\codebegin{6}{{\bf elseif} ccmd = ``\verb^UNDO^'' {\bf then} undo(brd,moves,args) }\codeend
\codebegin{9}{{\bf except} {\bf when} cannot\_undo:}\codeend
\codebegin{12}{wo\$display(error,``\verb^Cannot undo ^'' {$\|$} args {$\|$} ``\verb^ moves.^'') {\bf end}}\codeend
\codebegin{6}{{\bf elseif} ccmd = ``\verb^HELP^'' {\bf then} help(ho,args)}\codeend
\codebegin{9}{{\bf except} {\bf when} invalid\_command: }\codeend
\codebegin{12}{wo\$display(error,``\verb^No such command: ^'' {$\|$} args) {\bf end}}\codeend
\codebegin{6}{{\bf else} wo\$display(error,``\verb^Invalid command: ^''{$\|$}ccmd{$\|$}``\verb^ with args: ^''{$\|$} args) }\codeend
\codebegin{8}{{\bf except} {\bf when} too\_long: {\bf end}}\codeend
\codebegin{7}{{\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf end} exec\_command}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{completion = {\bf proc} (buf: ac) {\bf returns}(ac) {\bf signals}(invalid)}\codeend
\comment{\%}{4}{effects:}{ Completes the partial command in buf if possible. If command
is already complete, just upcases all letters if not already
upcased. Returns an array[char] with completed command, ignoring
everything that appears after the partial command in buf.
Signals invalid if no valid command can be found to complete
or match what is in buf.
}
\codebegin{4}{}\codeend
\codebegin{4}{seqs = sequence[string]}\codeend
\codebegin{4}{cmds =
seqs\$[``\verb^MOVE^'',``\verb^ADVISE^'',``\verb^TIME^'',``\verb^TIME
COMPUTER^'', \\
``\verb^TIME USER^'',``\verb^SAVE^'',``\verb^EXIT^'',``\verb^QUIT^'', \\
``\verb^NEW^'',``\verb^LOAD^'',``\verb^DIFFICULTY^'',``\verb^UNDO^'', \\
``\verb^HELP^'']}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{{\bf if} ac\$size(buf) = 0 {\bf then} signal invalid {\bf end}}\codeend
\codebegin{8}{}\codeend
\codebegin{4}{t: string := string\$ac2s(buf)}\codeend
\codebegin{4}{t := upcase(t)}\codeend
\codebegin{4}{l: int := string\$size(t)}\codeend
\codebegin{4}{{\bf if} t[l] = `\verb^ ^' {\bf then} l := l - 1 {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf for} s: string {\bf in} seqs\$elements(cmds) {\bf do}}\codeend
\comment{\%}{8}{}{ASSUMING THAT THERE ARE NO AMBIGUOUS PARTIAL COMMANDS
}
\codebegin{8}{{\bf if} match(string\$substr(t,1,l),s) }\codeend
\codebegin{12}{{\bf then} }\codeend
\codebegin{12}{{\bf return}(string\$s2ac(s))}\codeend
\codebegin{12}{{\bf end} }\codeend
\codebegin{8}{{\bf end} }\codeend
\codebegin{4}{}\codeend
\comment{\%}{4}{}{no match found
}
\codebegin{4}{{\bf signal} invalid}\codeend
\codebegin{19}{}\codeend
\codebegin{4}{{\bf end} completion}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{match = {\bf proc} (m: string, s: string) {\bf returns}(bool)}\codeend
\comment{\%}{4}{effects:}{ Returns true if the n characters of m match the first n
characters of s. If not, or if the length of m exceeds
the length of s.
}
\codebegin{4}{}\codeend
\codebegin{4}{n: int := 1}\codeend
\codebegin{4}{l: int := string\$size(s)}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf for} c: char {\bf in} string\$chars(m) {\bf do}}\codeend
\codebegin{8}{{\bf if} n {$>$} l {\bf then} return(FALSE) {\bf end}}\codeend
\codebegin{8}{{\bf if} c = s[n] }\codeend
\codebegin{12}{{\bf then} n := n + 1 }\codeend
\codebegin{10}{{\bf else} {\bf return}(FALSE) {\bf end}}\codeend
\codebegin{8}{{\bf end}}\codeend
\codebegin{4}{{\bf return}(TRUE)}\codeend
\codebegin{8}{}\codeend
\codebegin{4}{{\bf end} match}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{get\_command = {\bf proc} (buf: ac) {\bf returns}(string) {\bf signals}(no\_command)}\codeend
\comment{\%}{4}{effects:}{ Returns a string containing the alpha-numeric characters up
to the first space character in buf. Signals no\_command if
there are no alpha-numeric characters in buf.
}
\codebegin{4}{}\codeend
\codebegin{4}{s: string := string\$ac2s(buf)}\codeend
\codebegin{4}{sp: int := string\$indexc(`\verb^ ^',s)}\codeend
\codebegin{4}{e: int := string\$size(s)}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf if} string\$empty(s) {$|$} (sp = 1 \& e = 1) {\bf then} signal no\_command {\bf end}}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{{\bf if} sp = 0 {\bf then} return(s)}\codeend
\codebegin{5}{{\bf else} {\bf return}(string\$substr(s,1,sp-1)) {\bf end}}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{{\bf end} get\_command}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{get\_args = {\bf proc} (buf: ac, i: int) {\bf returns} (string) {\bf signals}(no\_arg)}\codeend
\comment{\%}{4}{effects:}{ Returns a string containing the alpha-numeric characters in 
buf after index i. If there are multiple args, they are
separated by a space in the returned string. Signals no\_arg
if there are no alpha-numeric characters in buf after i.
}
\codebegin{0}{}\codeend
\codebegin{4}{s: string := string\$ac2s(buf)}\codeend
\codebegin{4}{n: int := i + 1}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf if} n {$>$} string\$size(s) {\bf then} signal no\_arg {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{news: string := ``''}\codeend
\codebegin{4}{spaces: bool := false}\codeend
\codebegin{4}{}\codeend
\comment{\%}{4}{}{strip away leading, trailing, and multiple spaces between words
}
\codebegin{4}{{\bf for} c: char {\bf in} string\$chars(string\$rest(s,n)) {\bf do}}\codeend
\codebegin{8}{{\bf if} c {$\sim$}= `\verb^ ^'}\codeend
\codebegin{12}{{\bf then} }\codeend
\codebegin{12}{{\bf if} {$\sim$}spaces}\codeend
\codebegin{16}{{\bf then}}\codeend
\codebegin{16}{news := string\$append(news,c)}\codeend
\codebegin{16}{spaces := false}\codeend
\codebegin{14}{{\bf else} }\codeend
\codebegin{16}{news := string\$append(news,`\verb^ ^')}\codeend
\codebegin{16}{news := string\$append(news,c)}\codeend
\codebegin{16}{spaces := false}\codeend
\codebegin{16}{{\bf end}}\codeend
\codebegin{12}{{\bf else}}\codeend
\codebegin{14}{spaces := true}\codeend
\codebegin{14}{{\bf end}}\codeend
\codebegin{8}{{\bf end} }\codeend
\codebegin{0}{}\codeend
\codebegin{4}{{\bf if} {$\sim$}string\$empty(news) }\codeend
\codebegin{8}{{\bf then} }\codeend
\codebegin{8}{{\bf if} news[1] = `\verb^ ^' }\codeend
\codebegin{12}{{\bf then} news := string\$rest(news,2) {\bf end}}\codeend
\codebegin{8}{{\bf else} {\bf signal} no\_arg {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf return}(news)}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf end} get\_args}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{move = {\bf proc} (s: string, b:board, h:wo, stat: status, moves: ub)}\codeend
\codebegin{7}{{\bf signals}(illegal\_move(string),over)}\codeend
\comment{\%}{4}{}{effects Tells the game to execute move represented by s. Signals
illegal\_move if the game does not accept the move given.
}
\codebegin{0}{}\codeend
\comment{\%}{4}{}{Upcase s.
}
\codebegin{4}{work:string := upcase(s)}\codeend
\codebegin{0}{}\codeend
\comment{\%}{4}{}{Check that there is no space between the chars which make up
the initial coordinate.  If there is at least one space, it is in
an invalid format, so we need only check for one space.
}
\codebegin{4}{}\codeend
\comment{\%}{4}{}{Check the second character, as we are guaranteed that leading spaces
have been removed before move() is called.
}
\codebegin{4}{{\bf if} string\$size(work) {$<$} 2 }\codeend
\codebegin{8}{{\bf then} {\bf signal} illegal\_move(``\verb^Invalid coordinate.^'') {\bf end}}\codeend
\codebegin{4}{{\bf if} work[2] = `\verb^ ^' {\bf then}}\codeend
\codebegin{8}{{\bf signal} illegal\_move(``\verb^Illegal space in coordinate.^'')}\codeend
\codebegin{8}{{\bf end}     \% {\bf if}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{news: string := ``''}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf for} i:int {\bf in} int\$from\_to(1, string\$size(work)) {\bf do}}\codeend
\codebegin{8}{c:char := work[i]}\codeend
\codebegin{8}{{\bf if} c = `\verb^ ^' {\bf then} continue {\bf end}}\codeend
\codebegin{8}{{\bf if} ((c {$>$}= `\verb^A^') \& (c {$<$}= `\verb^Z^')) {$|$} ((c {$>$}= `\verb^0^' \& c {$<$}= `\verb^9^')) {\bf then}}\codeend
\codebegin{12}{news := string\$append(news, c)}\codeend
\codebegin{10}{{\bf else}}\codeend
\codebegin{12}{{\bf signal} illegal\_move(``\verb^Illegal char in MOVE arg.^'')}\codeend
\codebegin{12}{{\bf end}     \% {\bf if}}\codeend
\codebegin{8}{{\bf end}     \% {\bf for}}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{news := string\$c2s(BLACK) {$\|$} news}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{ub\$update(moves,b)}\codeend
\codebegin{4}{new\_move(b,news,h,stat) }\codeend
\codebegin{5}{{\bf except} {\bf when} bad\_move(m:string): {\bf signal} illegal\_move(m) {\bf end}}\codeend
\codebegin{5}{{\bf except} {\bf when} red\_wins: }\codeend
\codebegin{8}{stat.mesg := ``\verb^Red wins!^''; st\$redraw(stat); {\bf signal} over {\bf end}}\codeend
\codebegin{5}{{\bf except} {\bf when} black\_wins:}\codeend
\codebegin{8}{stat.mesg := ``\verb^Black wins!^''; st\$redraw(stat); {\bf signal} over {\bf end}}\codeend
\codebegin{5}{{\bf except} {\bf when} tie:}\codeend
\codebegin{8}{stat.mesg := ``\verb^It's a tie.^''; st\$redraw(stat); {\bf signal} over {\bf end}}\codeend
\codebegin{4}{}\codeend
\comment{\%}{4}{}{Update the status and the undo buffer
}
\codebegin{4}{st\$redraw(stat)}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{{\bf end} move}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{advise = {\bf proc} (h: wo, b: board, s: status) }\codeend
\comment{\%}{4}{modifies:}{ h
}
\comment{\%}{4}{}{}
\comment{\%}{4}{effects:}{ Prints out the best possible move for the user to take in 
help area specified by h.
}
\codebegin{0}{}\codeend
\codebegin{4}{new\_move(b,``\verb^ADVISE^'',h,s)}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf end} advise}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{time = {\bf proc} (t: string, s:st) {\bf signals}(bad\_format,not\_possible(string))}\codeend
\comment{\%}{4}{effects:}{ Adds or substracts time specified in t (with form mm:ss) to
the time left for player specified in t. Signals bad\_format
if t is not in correct form. Signals not\_possible with a 
explanation string when time would be too high or negative.
}
\codebegin{4}{}\codeend
\codebegin{4}{who: string := get\_command(string\$s2ac(t))}\codeend
\codebegin{4}{c: char}\codeend
\codebegin{4}{{\bf if} match(who,``\verb^USER^'')}\codeend
\codebegin{8}{{\bf then} c := BLACK }\codeend
\codebegin{6}{{\bf elseif} match(who,``\verb^COMPUTER^'')}\codeend
\codebegin{8}{{\bf then} c := RED }\codeend
\codebegin{6}{{\bf else} {\bf signal} bad\_format {\bf end}}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{p: char := t[string\$size(who) + 2]}\codeend
\codebegin{5}{{\bf except} {\bf when} bounds: {\bf signal} bad\_format {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{ts: string := string\$rest(t, string\$size(who) + 3)}\codeend
\codebegin{5}{{\bf except} {\bf when} bounds: {\bf signal} bad\_format {\bf end}}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{secs: int := parse\_time(ts) }\codeend
\codebegin{5}{{\bf except} {\bf when} bad\_format: {\bf signal} bad\_format {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf if} p = `\verb^+^' }\codeend
\codebegin{8}{{\bf then} }\codeend
\codebegin{8}{st\$add\_time(s, secs, c) }\codeend
\codebegin{9}{{\bf except} {\bf when} too\_high: }\codeend
\codebegin{12}{{\bf signal} not\_possible(``\verb^Maximum time exceeded.^'') {\bf end}}\codeend
\codebegin{6}{{\bf elseif} p = `\verb^-^' }\codeend
\codebegin{8}{{\bf then} }\codeend
\codebegin{8}{st\$sub\_time(s, secs, c)}\codeend
\codebegin{9}{{\bf except} {\bf when} negative: {\bf signal} not\_possible(``\verb^Negative time.^'') {\bf end}}\codeend
\codebegin{6}{{\bf else} {\bf signal} bad\_format {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{st\$redraw(s)}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{{\bf end} time}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{save = {\bf proc} (f: string, b:board, s:st) {\bf signals}(not\_possible)}\codeend
\comment{\%}{4}{effects:}{ Saves the configuration of the current game to the file with
name f. Signals not\_possible if there is some error in
creating/accessing file f.
}
\codebegin{4}{}\codeend
\codebegin{4}{fn: file\_name := file\_name\$parse(f) }\codeend
\codebegin{5}{{\bf except} {\bf when} bad\_format: {\bf signal} not\_possible {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{fs: stream := stream\$open(fn,``\verb^write^'') }\codeend
\codebegin{5}{{\bf except} {\bf when} not\_possible(m:string): {\bf signal} not\_possible {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{stream\$putl(fs,string\$c2s(s.turn))}\codeend
\codebegin{4}{stream\$putl(fs,int\$unparse(s.level))}\codeend
\codebegin{4}{stream\$puts(fs,int\$unparse(st\$get\_time\_left(s,BLACK)))}\codeend
\codebegin{4}{stream\$putc(fs,`\verb^ ^')}\codeend
\codebegin{4}{stream\$putl(fs,int\$unparse(st\$get\_time\_left(s,RED)))}\codeend
\codebegin{4}{{\bf for} p: position, c: char {\bf in} board\$configuration(b) {\bf do}}\codeend
\codebegin{8}{{\bf if} p.column = 8 {\bf then} stream\$putl(fs,string\$c2s(c))}\codeend
\codebegin{10}{{\bf else} stream\$putc(fs,c) {\bf end}}\codeend
\codebegin{8}{{\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{stream\$close(fs) }\codeend
\codebegin{5}{{\bf except} {\bf when} not\_possible(n:string): {\bf signal} not\_possible {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf end} save}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{new = {\bf proc} (b: board, stat: st, h: wo, e: wo, moves: ub)}\codeend
\comment{\%}{4}{modifies:}{ b, stat, h, e, moves
}
\comment{\%}{4}{}{}
\comment{\%}{4}{effects:}{ Terminates current game and resets everything to start a new
game.
}
\codebegin{4}{}\codeend
\comment{\%}{4}{}{Initialize board
}
\codebegin{4}{bconfig: string :=
``\verb^-O-O-O-O\nO-O-O-O-\n-O-O-O-O\n--------\n^'' \\
``\verb^--------\nX-X-X-X-\n-X-X-X-X\nX-X-X-X-\n^''}\codeend
\codebegin{4}{bstream: stream := stream\$create\_input(bconfig)}\codeend
\codebegin{4}{board\$set\_board(b,bstream)}\codeend
\codebegin{4}{}\codeend
\comment{\%}{4}{}{Initialize status
}
\codebegin{4}{st\$set\_score(stat,0,BLACK)}\codeend
\codebegin{4}{st\$set\_score(stat,0,RED)}\codeend
\codebegin{4}{st\$set\_time\_left(stat,stime,BLACK)}\codeend
\codebegin{4}{st\$set\_time\_left(stat,stime,RED)}\codeend
\codebegin{4}{st\$set\_time\_used(stat,0,BLACK)}\codeend
\codebegin{4}{st\$set\_time\_used(stat,0,RED)}\codeend
\codebegin{4}{st\$set\_level(stat,1)}\codeend
\codebegin{4}{st\$set\_turn(stat,BLACK)}\codeend
\codebegin{4}{st\$set\_mesg(stat,``\verb^Black moves.^'')}\codeend
\codebegin{4}{ub\$clear(moves)}\codeend
\codebegin{4}{}\codeend
\comment{\%}{4}{}{Initialize windows
}
\codebegin{4}{wo\$clear(h)}\codeend
\codebegin{4}{wo\$clear(e)}\codeend
\codebegin{4}{st\$redraw(stat)}\codeend
\codebegin{4}{board\$redraw(b)}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf end} new}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{load = {\bf proc} (file: string, b:board, s:st, moves:ub) }\codeend
\codebegin{7}{{\bf signals}(bad\_format,not\_possible,bad\_arg(string),over)}\codeend
\comment{\%}{4}{modifies:}{ b, s, moves
}
\comment{\%}{4}{}{}
\comment{\%}{4}{effects:}{ Replaces the current game configuration with a new one which
is given by the file with name f or f.brd. Signals bad\_format
if thefile is not in the correct format. Signals not\_possible 
if no such file exists.
}
\codebegin{0}{}\codeend
\codebegin{4}{fn: file\_name := file\_name\$parse(file)}\codeend
\codebegin{12}{{\bf except} {\bf when} bad\_format: {\bf signal} not\_possible {\bf end}}\codeend
\codebegin{4}{fs: stream := stream\$open(fn,``\verb^read^'')}\codeend
\codebegin{5}{{\bf except} {\bf when} not\_possible(m:string): }\codeend
\codebegin{8}{fn := file\_name\$parse(file {$\|$} ``\verb^.brd^'')}\codeend
\codebegin{9}{{\bf except} {\bf when} bad\_format: {\bf signal} not\_possible {\bf end}}\codeend
\codebegin{8}{fs := stream\$open(fn,``\verb^read^'')}\codeend
\codebegin{9}{{\bf except} {\bf when} not\_possible(n:string): }\codeend
\codebegin{12}{{\bf signal} not\_possible {\bf end}}\codeend
\codebegin{8}{{\bf end}}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{{\bf if} stream\$empty(fs) {\bf then} signal not\_possible {\bf end}}\codeend
\codebegin{4}{stream\$peekc(fs)}\codeend
\codebegin{5}{{\bf except} {\bf when} not\_possible(m:string): {\bf signal} not\_possible {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{who: char, level, t1, t2: int := parse\_file(fs) {\bf resignal} bad\_format}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{{\bf if} who = `\verb^O^' {\bf then} signal bad\_arg(``\verb^Current player cannot be `O'.^'') {\bf end}}\codeend
\codebegin{4}{st\$set\_mesg(s,``\verb^Black moves.^'')}\codeend
\codebegin{4}{s.turn := who}\codeend
\codebegin{5}{{\bf except} {\bf when} no\_player: {\bf signal} bad\_arg(``\verb^Invalid player.^'') {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf if} level {$>$} 10 {\bf then} signal bad\_arg(``\verb^Invalid level.^'') {\bf end}}\codeend
\codebegin{4}{old\_level: int := s.level}\codeend
\codebegin{4}{s.level := level}\codeend
\codebegin{5}{{\bf except} {\bf when} bounds: {\bf signal} bad\_arg(``\verb^Invalid level.^'') {\bf end}}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{old\_tlb: int := st\$get\_time\_left(s,BLACK)}\codeend
\codebegin{4}{old\_tlr: int := st\$get\_time\_left(s,RED)}\codeend
\codebegin{4}{old\_tub: int := st\$get\_time\_used(s,BLACK)}\codeend
\codebegin{4}{old\_tur: int := st\$get\_time\_used(s,RED)}\codeend
\codebegin{4}{{\bf begin}}\codeend
\codebegin{4}{st\$set\_time\_left(s,t1,BLACK)}\codeend
\codebegin{4}{st\$set\_time\_left(s,t2,RED)}\codeend
\codebegin{4}{st\$set\_time\_used(s,0,BLACK)}\codeend
\codebegin{4}{st\$set\_time\_used(s,0,RED)}\codeend
\codebegin{4}{{\bf end} }\codeend
\codebegin{5}{{\bf except} {\bf when} negative: }\codeend
\codebegin{9}{s.level := old\_level; {\bf signal} bad\_arg(``\verb^Negative time.^'') {\bf end}}\codeend
\codebegin{5}{{\bf except} {\bf when} too\_high: }\codeend
\codebegin{9}{s.level := old\_level; {\bf signal} bad\_arg(``\verb^Huge time.^'') {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{board\$set\_board(b,fs) }\codeend
\codebegin{5}{{\bf except} {\bf when} bad\_format: }\codeend
\codebegin{8}{s.level := old\_level}\codeend
\codebegin{8}{st\$set\_time\_left(s,old\_tlb,BLACK)}\codeend
\codebegin{8}{st\$set\_time\_left(s,old\_tlr,RED)}\codeend
\codebegin{8}{st\$set\_time\_used(s,old\_tub,BLACK)}\codeend
\codebegin{8}{st\$set\_time\_used(s,old\_tur,RED)}\codeend
\codebegin{8}{{\bf signal} bad\_arg(``\verb^Invalid board.^'') {\bf end}}\codeend
\codebegin{4}{board\$redraw(b)}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{uscore: int := player\_score(b,BLACK)}\codeend
\codebegin{4}{cscore: int := player\_score(b,RED)}\codeend
\codebegin{4}{st\$set\_score(s,uscore,BLACK)}\codeend
\codebegin{4}{st\$set\_score(s,cscore,RED)}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{st\$redraw(s)}\codeend
\codebegin{4}{ub\$clear(moves)}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{check\_game\_over(b) }\codeend
\codebegin{5}{{\bf except} {\bf when} game\_over: }\codeend
\codebegin{8}{check\_for\_win(b)}\codeend
\codebegin{9}{{\bf except} {\bf when} black\_wins: s.mesg := ``\verb^Black wins!^''; {\bf signal} over {\bf end}}\codeend
\codebegin{9}{{\bf except} {\bf when} red\_wins: s.mesg := ``\verb^Red wins!^''; {\bf signal} over {\bf end}}\codeend
\codebegin{9}{{\bf except} {\bf when} tie: s.mesg := ``\verb^It's a tie.^''; {\bf signal} over {\bf end}}\codeend
\codebegin{12}{{\bf end}}\codeend
\codebegin{8}{}\codeend
\codebegin{4}{stream\$close(fs)}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{{\bf end} load}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{difficulty = {\bf proc} (l: string, s: st) {\bf signals}(invalid\_level)}\codeend
\comment{\%}{4}{effects:}{ Changes the level of the game to l.
\\
Signal invalid\_level if $l<1$ or $l>10$.
}
\codebegin{4}{}\codeend
\codebegin{4}{n: int := int\$parse(l)}\codeend
\codebegin{5}{{\bf except} {\bf when} bad\_format: {\bf signal} invalid\_level {\bf end}}\codeend
\codebegin{5}{{\bf except} {\bf when} overflow: {\bf signal} invalid\_level {\bf end}}\codeend
\codebegin{0}{}\codeend
\comment{\%}{4}{}{Make sure level does not exceed 10.  set\_level insures that
the level is not less than 1.
}
\codebegin{4}{{\bf if} n{$>$}10 {\bf then}}\codeend
\codebegin{8}{{\bf signal} invalid\_level}\codeend
\codebegin{8}{{\bf end}}\codeend
\codebegin{4}{}\codeend
\comment{\%}{4}{}{Now actually set the level.
}
\codebegin{4}{st\$set\_level(s,n)}\codeend
\codebegin{5}{{\bf except} {\bf when} bounds: {\bf signal} invalid\_level {\bf end}}\codeend
\codebegin{4}{st\$redraw(s)}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf end} difficulty}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{undo = {\bf proc} (b:board, moves: ub, s:string) {\bf signals}(cannot\_undo)}\codeend
\comment{\%}{4}{modifies:}{ b, s
}
\comment{\%}{4}{}{}
\comment{\%}{4}{effects:}{ Undoes the last move. Signals cannot\_undo if there is
no move to undo.
}
\codebegin{4}{}\codeend
\codebegin{4}{n:int := int\$parse(s)}\codeend
\codebegin{5}{{\bf except} {\bf when} bad\_format: {\bf signal} cannot\_undo {\bf end}}\codeend
\codebegin{5}{{\bf except} {\bf when} overflow: {\bf signal} cannot\_undo {\bf end}}\codeend
\codebegin{4}{{\bf if} n {$<$}= 0 {\bf then} signal cannot\_undo {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{ub\$yank(moves,b,n)}\codeend
\codebegin{5}{{\bf except} {\bf when} depth\_exceeded: {\bf signal} cannot\_undo {\bf end}}\codeend
\codebegin{4}{board\$redraw(b)}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf end} undo}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{help = {\bf proc} (h: wo, s: string) {\bf signals}(invalid\_command)}\codeend
\comment{\%}{4}{modifies:}{ h
}
\comment{\%}{4}{}{}
\comment{\%}{4}{effects:}{ Displays help information for command s. If s is empty,
displays general help info. Signals invalid\_command if s 
is not a valid command.
}
\codebegin{4}{}\codeend
\codebegin{4}{comm: ac := string\$s2ac(s)}\codeend
\codebegin{4}{comm := completion(comm)}\codeend
\codebegin{5}{{\bf except} {\bf when} invalid: {\bf signal} invalid\_command {\bf end}}\codeend
\codebegin{4}{t: string := string\$ac2s(comm)}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf if} t = ``\verb^MOVE^'' {\bf then} help\_move(h) }\codeend
\codebegin{6}{{\bf elseif} t = ``\verb^ADVISE^'' {\bf then} help\_advise(h) }\codeend
\codebegin{6}{{\bf elseif} t = ``\verb^TIME^'' {\bf then} help\_time(h)}\codeend
\codebegin{6}{{\bf elseif} t = ``\verb^SAVE^'' {\bf then} help\_save(h)}\codeend
\codebegin{6}{{\bf elseif} t = ``\verb^EXIT^'' {\bf then} help\_exit(h)}\codeend
\codebegin{6}{{\bf elseif} t = ``\verb^QUIT^'' {\bf then} help\_quit(h)}\codeend
\codebegin{6}{{\bf elseif} t = ``\verb^NEW^'' {\bf then} help\_new(h)}\codeend
\codebegin{6}{{\bf elseif} t = ``\verb^LOAD^'' {\bf then} help\_load(h)}\codeend
\codebegin{6}{{\bf elseif} t = ``\verb^DIFFICULTY^'' {\bf then} help\_difficulty(h)}\codeend
\codebegin{6}{{\bf elseif} t = ``\verb^UNDO^'' {\bf then} help\_undo(h)}\codeend
\codebegin{6}{{\bf elseif} t = ``\verb^HELP^'' {\bf then} help\_help(h) }\codeend
\codebegin{8}{{\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf end} help}\codeend
\codebegin{4}{}\codeend
\codebegin{0}{parse\_time = {\bf proc} (t: string) {\bf returns} (int) {\bf signals}(bad\_format)}\codeend
\comment{\%}{4}{effects:}{ Returns an integer representing the time in seconds 
corresponding to t which is in the form mm:ss. Signals
bad\_format if t is not in this form or mm or ss are not
integers (in string format).
}
\codebegin{0}{}\codeend
\codebegin{4}{secs: int := 0}\codeend
\codebegin{4}{n: int }\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf if} string\$size(t) {$>$} 5 {$|$} string\$size(t) {$<$} 5 {\bf then} signal bad\_format {\bf end}}\codeend
\codebegin{4}{{\bf for} i: int {\bf in} int\$from\_to(1,5) {\bf do}}\codeend
\codebegin{8}{{\bf if} i {$\sim$}= 3 }\codeend
\codebegin{12}{{\bf then} }\codeend
\codebegin{12}{n := int\$parse(string\$c2s(t[i]))}\codeend
\codebegin{13}{{\bf except} {\bf when} not\_possible: {\bf signal} bad\_format {\bf end}}\codeend
\codebegin{12}{{\bf if} i = 1 {\bf then} secs := secs + 600*n }\codeend
\codebegin{14}{{\bf elseif} i = 2 {\bf then} secs := secs + 60*n}\codeend
\codebegin{14}{{\bf elseif} i = 4 {\bf then} secs := secs + 10*n}\codeend
\codebegin{14}{{\bf elseif} i = 5 {\bf then} secs := secs + n}\codeend
\codebegin{16}{{\bf end}}\codeend
\codebegin{10}{{\bf else} {\bf if} t[i] {$\sim$}= `\verb^:^' {\bf then} signal bad\_format {\bf end}}\codeend
\codebegin{12}{{\bf end}}\codeend
\codebegin{8}{{\bf end}}\codeend
\codebegin{4}{{\bf return}(secs)}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf end} parse\_time}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{parse\_file = {\bf proc} (s: stream) {\bf returns} (char,int,int,int)}\codeend
\codebegin{13}{{\bf signals}(bad\_format(string))}\codeend
\comment{\%}{4}{modifies:}{ s
}
\comment{\%}{4}{}{}
\comment{\%}{4}{effects:}{ Returns a char representing next turn color (X/O), an 
integer representing level, an integer representing X's
time left in seconds, and an integer representing O's time
life in seconds. Signals bad\_format if the file is not of
the correct format, giving an explanation string.
}
\codebegin{0}{}\codeend
\codebegin{4}{who: char := stream\$getc(s)}\codeend
\codebegin{5}{{\bf except} {\bf when} end\_of\_file: {\bf signal} bad\_format(``\verb^Empty file.^'') {\bf end}}\codeend
\codebegin{4}{{\bf if} who {$\sim$}= black \& who {$\sim$}= red {\bf then} signal bad\_format(``\verb^Invalid player^'') {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{n: char := stream\$getc(s)}\codeend
\codebegin{5}{{\bf except} {\bf when} end\_of\_file: {\bf signal} bad\_format(``\verb^Premature end of file.^'') {\bf end}}\codeend
\codebegin{4}{{\bf if} n {$\sim$}= `\verb^\n^' {\bf then} signal bad\_format(``\verb^Invalid player^'') {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{i: string := stream\$getl(s)}\codeend
\codebegin{5}{{\bf except} {\bf when} end\_of\_file: {\bf signal} bad\_format(``\verb^Premature end of file.^'') {\bf end}}\codeend
\codebegin{4}{l: int := int\$parse(i)}\codeend
\codebegin{5}{{\bf except} {\bf when} bad\_format: {\bf signal} bad\_format(``\verb^Invalid level.^'') {\bf end}}\codeend
\codebegin{5}{{\bf except} {\bf when} overflow: {\bf signal} bad\_format(``\verb^Invalid level.^'') {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{i := stream\$getl(s)}\codeend
\codebegin{5}{{\bf except} {\bf when} end\_of\_file: {\bf signal} bad\_format(``\verb^Premature end of file.^'') {\bf end}}\codeend
\codebegin{4}{c: int := string\$indexc(`\verb^ ^',i)}\codeend
\codebegin{4}{{\bf if} c = 0 {\bf then} signal bad\_format(``\verb^Missing time.^'') {\bf end}}\codeend
\codebegin{4}{t1: int := int\$parse(string\$substr(i,1,c-1))}\codeend
\codebegin{5}{{\bf except} {\bf when} bad\_format: {\bf signal} bad\_format(``\verb^Invalid time.^'') {\bf end}}\codeend
\codebegin{5}{{\bf except} {\bf when} overflow: {\bf signal} bad\_format(``\verb^Invalid time.^'') {\bf end}}\codeend
\codebegin{4}{t2: int := int\$parse(string\$substr(i,c+1,string\$size(i)-c))}\codeend
\codebegin{5}{{\bf except} {\bf when} bad\_format: {\bf signal} bad\_format(``\verb^Invalid time.^'') {\bf end}}\codeend
\codebegin{5}{{\bf except} {\bf when} overflow: {\bf signal} bad\_format(``\verb^Invalid time.^'') {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf return}(who,l,t1,t2)}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf end} parse\_file}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{upcase = {\bf proc} (s: string) {\bf returns}(string)}\codeend
\comment{\%}{4}{effects:}{ Upcases a-z characters in the string s. Leaves other 
characters alone.
}
\codebegin{0}{}\codeend
\codebegin{4}{news: string := ``''}\codeend
\codebegin{4}{i: int}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf for} c: char {\bf in} string\$chars(s) {\bf do}}\codeend
\codebegin{8}{{\bf if} c {$>$}= `\verb^a^' \& c {$<$}= `\verb^z^' }\codeend
\codebegin{12}{{\bf then} }\codeend
\codebegin{12}{i := char\$c2i(c) - 32}\codeend
\codebegin{12}{news := string\$append(news,char\$i2c(i))}\codeend
\codebegin{10}{{\bf else} }\codeend
\codebegin{12}{news := string\$append(news,c)}\codeend
\codebegin{12}{{\bf end}}\codeend
\codebegin{8}{{\bf end}}\codeend
\codebegin{4}{{\bf return}(news)}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{{\bf end} upcase}\codeend
