\codebegin{0}{ac = {\bf array}[char]}\codeend
\codebegin{0}{io = input\_obj}\codeend
\codebegin{0}{ub = undo\_buf}\codeend
\codebegin{0}{kb = keyboard}\codeend
\codebegin{0}{wo = window\_obj}\codeend
\codebegin{0}{ss = simplescreen}\codeend
\codebegin{0}{RED = `\verb^O^'}\codeend
\codebegin{0}{BLACK = `\verb^X^'}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{start\_up = {\bf proc} () }\codeend
\codebegin{4}{}\codeend
\comment{\%}{4}{}{requires 80x24 screen
}
\codebegin{4}{input\_row = 21}\codeend
\codebegin{4}{input\_col = 2}\codeend
\codebegin{4}{input\_width = 77}\codeend
\codebegin{4}{prompt = ``\verb^Command> ^''}\codeend
\codebegin{4}{help\_row = 2}\codeend
\codebegin{4}{help\_col = 2}\codeend
\codebegin{4}{help\_width = 18}\codeend
\codebegin{4}{help\_height = 19}\codeend
\codebegin{4}{error\_row = 22}\codeend
\codebegin{4}{error\_col = 2}\codeend
\codebegin{4}{error\_width = 77}\codeend
\codebegin{4}{error\_height = 2}\codeend
\codebegin{4}{}\codeend
\comment{\%}{4}{}{time = 25 minutes
}
\codebegin{4}{stime = 1500}\codeend
\comment{\%}{4}{}{first player
}
\codebegin{4}{sp = BLACK}\codeend
\comment{\%}{4}{}{status mesg
}
\codebegin{4}{sstr =  ``\verb^Black moves.^''}\codeend
\comment{\%}{4}{}{depth of undo
}
\codebegin{4}{undos = 10}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{pi: stream := stream\$primary\_input()}\codeend
\codebegin{4}{keyb: kb := kb\$open(pi)}\codeend
\codebegin{5}{{\bf except} {\bf when} not\_possible(s: string): {\bf signal} failure(s) {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{screen: ss := ss\$open()}\codeend
\codebegin{4}{{\bf if} screen.width {$<$} 80 {$|$} screen.height {$<$} 24 }\codeend
\codebegin{8}{{\bf then} {\bf signal} failure(``\verb^Screen is smaller than 80x24.^'') {\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{input: io := io\$create(screen,input\_row,input\_col,input\_width,prompt)}\codeend
\codebegin{4}{help: wo := wo\$create(screen,help\_row,help\_col,help\_width,help\_height)}\codeend
\codebegin{4}{error: wo := wo\$create(screen,error\_row,error\_col,error\_width,error\_height)}\codeend
\codebegin{4}{st: status := status\$create(0,0,0,0,0,0,1,sp,sstr,screen)}\codeend
\codebegin{4}{b: board := board\$new(screen)}\codeend
\codebegin{4}{moves: ub := ub\$create(undos)}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{t: timer := timer\$new()}\codeend
\codebegin{4}{quitp: bool := false}\codeend
\codebegin{4}{cmd: bool := false}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{new(b,st,help,error,moves)   \% new initializes everything}\codeend
\codebegin{4}{io\$redraw(input)}\codeend
\codebegin{4}{timer\$start(t)}\codeend
\codebegin{0}{}\codeend
\codebegin{4}{{\bf while} {$\sim$}quitp {\bf do}}\codeend
\codebegin{8}{wait\_for\_input(keyb,input,st,t)}\codeend
\codebegin{9}{{\bf except} {\bf when} over:}\codeend
\codebegin{12}{st.mesg := ``\verb^Red wins.^''}\codeend
\codebegin{12}{status\$redraw\_mesg(st)}\codeend
\codebegin{12}{quitp := {$\sim$}again(keyb,screen,error,error\_row,error\_col)}\codeend
\codebegin{12}{{\bf if} {$\sim$}quitp {\bf then} new(b,st,help,error,moves); cmd := false}\codeend
\codebegin{16}{{\bf else} continue {\bf end}}\codeend
\codebegin{12}{{\bf end}}\codeend
\codebegin{8}{io\$moveto\_end(input)}\codeend
\codebegin{8}{cmd := get\_input(keyb,input,help,error,t,st,b,moves,screen,cmd)}\codeend
\codebegin{9}{{\bf except} {\bf when} over:}\codeend
\codebegin{12}{{\bf if} status\$get\_time\_left(st,RED) = 0 }\codeend
\codebegin{16}{{\bf then} st.mesg := ``\verb^Black wins.^'' {\bf end}}\codeend
\codebegin{12}{status\$redraw\_mesg(st)}\codeend
\codebegin{12}{quitp := {$\sim$}again(keyb,screen,error,error\_row,error\_col)}\codeend
\codebegin{12}{{\bf if} {$\sim$}quitp {\bf then} new(b,st,help,error,moves); cmd := false {\bf end}}\codeend
\codebegin{12}{{\bf end}}\codeend
\codebegin{8}{{\bf end}}\codeend
\codebegin{4}{ss\$close(screen)}\codeend
\codebegin{4}{kb\$close(keyb)}\codeend
\codebegin{4}{stream\$putl(stream\$primary\_output(),``\verb^\nGoodbye.^'')}\codeend
\codebegin{4}{{\bf end} start\_up}\codeend
\codebegin{4}{}\codeend
\codebegin{0}{wait\_for\_input = {\bf proc} (keyb: kb, i: io, st: status, t:timer) {\bf signals}(over)}\codeend
\comment{\%}{4}{modifies:}{ st, t
effects: Waits for input from keyboard and checks time\_left for current
player. If player's time runs out, signals over.
}
\codebegin{4}{}\codeend
\codebegin{4}{{\bf while} {$\sim$}kb\$pending(keyb) {\bf do}}\codeend
\codebegin{8}{{\bf if} status\$get\_time\_left(st,BLACK) - timer\$elapsed(t) {$<$}= 0}\codeend
\codebegin{12}{{\bf then} {\bf signal} over {\bf end}}\codeend
\codebegin{8}{{\bf if} timer\$elapsed(t) {$>$}= 10 }\codeend
\codebegin{12}{{\bf then}        }\codeend
\codebegin{12}{status\$update\_time(st,timer\$elapsed(t),BLACK)}\codeend
\codebegin{12}{timer\$reset(t); timer\$start(t)}\codeend
\codebegin{12}{{\bf end}}\codeend
\codebegin{8}{io\$moveto\_end(i)}\codeend
\codebegin{8}{{\bf end}}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf end} wait\_for\_input}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{get\_input = {\bf proc} (keyb: kb, input: input\_obj, ho: wo, eo: wo, t:timer,}\codeend
\codebegin{8}{st:status, b:board, moves: ub, scr: ss, cmd: bool) {\bf returns}(bool) }\codeend
\codebegin{8}{{\bf signals}(over)}\codeend
\comment{\%}{4}{}{modifies all args
effects Processes input from the keyboard, echoing it to the screen,
executing commands, and printing errors when appropriate.
Signals over if computer (RED) runs out of time.
}
\codebegin{4}{}\codeend
\codebegin{4}{cmdp: bool := cmd}\codeend
\codebegin{4}{keyp: key}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{{\bf while} kb\$pending(keyb) {\bf do}}\codeend
\codebegin{8}{keyp := kb\$get\_next\_key(keyb)}\codeend
\codebegin{8}{tagcase keyp}\codeend
\codebegin{12}{tag normal (mc: char): }\codeend
\codebegin{12}{{\bf if} {$\sim$}cmdp \& mc = `\verb^ ^' {\bf then}}\codeend
\codebegin{16}{cmdp := true}\codeend
\codebegin{16}{input.buffer := completion(input.buffer)}\codeend
\codebegin{17}{{\bf except} {\bf when} invalid:}\codeend
\codebegin{20}{ss\$beep(scr)}\codeend
\codebegin{20}{wo\$display(eo,``\verb^No such command.^'')}\codeend
\codebegin{20}{cmdp := false}\codeend
\codebegin{20}{break}\codeend
\codebegin{20}{{\bf end}}\codeend
\codebegin{16}{io\$redraw(input)}\codeend
\codebegin{16}{{\bf end}}\codeend
\codebegin{12}{input\_obj\$add\_char(input,mc)}\codeend
\codebegin{13}{{\bf except} {\bf when} too\_long: ss\$beep(scr) {\bf end} }\codeend
\codebegin{12}{tag control (mc: char):}\codeend
\codebegin{12}{i: int := char\$c2i(mc)}\codeend
\codebegin{12}{{\bf if} i = 8 {$|$} i = 127  \% backspace or delete}\codeend
\codebegin{16}{{\bf then} }\codeend
\codebegin{16}{input\_obj\$delete\_char(input) }\codeend
\codebegin{17}{{\bf except} {\bf when} no\_char: ss\$beep(scr) {\bf end} }\codeend
\codebegin{22}{completion(string\$s2ac(get\_command(input.buffer)))}\codeend
\codebegin{17}{{\bf except} {\bf when} no\_command: cmdp := false {\bf end}}\codeend
\codebegin{17}{{\bf except} {\bf when} invalid: cmdp := false {\bf end}}\codeend
\codebegin{14}{{\bf elseif} i = 12     \% Ctl-L}\codeend
\codebegin{16}{{\bf then} }\codeend
\codebegin{16}{ss\$clear(scr)}\codeend
\codebegin{16}{board\$redraw(b)}\codeend
\codebegin{16}{status\$redraw(st)}\codeend
\codebegin{16}{wo\$redraw(ho)}\codeend
\codebegin{16}{wo\$redraw(eo)}\codeend
\codebegin{16}{input\_obj\$redraw(input) }\codeend
\codebegin{14}{{\bf elseif} i = 21     \% Ctl-U}\codeend
\codebegin{16}{{\bf then}}\codeend
\codebegin{16}{io\$clear(input)}\codeend
\codebegin{22}{cmdp := false}\codeend
\codebegin{14}{{\bf elseif} i = 10     \% Return}\codeend
\codebegin{16}{{\bf then} }\codeend
\codebegin{16}{status\$update\_time(st,timer\$elapsed(t),BLACK)}\codeend
\codebegin{16}{timer\$restart(t)}\codeend
\codebegin{16}{cs: string := get\_command(input.buffer)}\codeend
\codebegin{17}{{\bf except} {\bf when} no\_command: ss\$beep(scr); break {\bf end}}\codeend
\codebegin{16}{cs := string\$ac2s(completion(string\$s2ac(cs)))}\codeend
\codebegin{17}{{\bf except} {\bf when} invalid:}\codeend
\codebegin{20}{ss\$beep(scr)}\codeend
\codebegin{20}{wo\$display(eo,``\verb^Invalid command.^'')}\codeend
\codebegin{20}{io\$clear(input)}\codeend
\codebegin{20}{break}\codeend
\codebegin{20}{{\bf end}}\codeend
\codebegin{16}{{\bf if} cs = ``\verb^MOVE^'' }\codeend
\codebegin{20}{{\bf then} }\codeend
\codebegin{20}{st.mesg := ``\verb^Red moves.^''}\codeend
\codebegin{20}{status\$redraw\_mesg(st)}\codeend
\codebegin{20}{{\bf end}}\codeend
\codebegin{16}{exec\_command(input,ho,eo,st,b,moves) {\bf resignal} over}\codeend
\codebegin{17}{{\bf except} {\bf when} no\_command: }\codeend
\codebegin{20}{ss\$beep(scr)}\codeend
\codebegin{20}{io\$clear(input)}\codeend
\codebegin{20}{break}\codeend
\codebegin{20}{{\bf end}}\codeend
\codebegin{16}{{\bf if} cs = ``\verb^MOVE^'' }\codeend
\codebegin{20}{{\bf then} }\codeend
\codebegin{20}{status\$update\_time(st,timer\$elapsed(t),RED)}\codeend
\codebegin{18}{{\bf else} status\$update\_time(st,timer\$elapsed(t),BLACK) {\bf end}}\codeend
\codebegin{16}{status\$redraw\_time(st)  }\codeend
\codebegin{16}{{\bf if} status\$get\_time\_left(st,RED) {$<$}= 0}\codeend
\codebegin{20}{{\bf then} {\bf signal} over {\bf end}}\codeend
\codebegin{16}{st.mesg := ``\verb^Black moves.^''}\codeend
\codebegin{16}{status\$redraw\_mesg(st)}\codeend
\codebegin{16}{cmdp := false}\codeend
\codebegin{16}{io\$clear(input)}\codeend
\codebegin{16}{timer\$restart(t)}\codeend
\codebegin{16}{{\bf end}}\codeend
\codebegin{12}{others: {\bf end}}\codeend
\codebegin{8}{{\bf end}}\codeend
\codebegin{4}{{\bf return}(cmdp)}\codeend
\codebegin{4}{{\bf end} get\_input}\codeend
\codebegin{0}{}\codeend
\codebegin{0}{again = {\bf proc} (keyb: kb, s: ss, e: wo, r, c: int) {\bf returns} (bool) }\codeend
\comment{\%}{4}{modifies:}{ s, e
}
\comment{\%}{4}{}{}
\comment{\%}{4}{effects:}{ Asks if user wants to play again. Returns true if the 
answer is yes, false if the answer is no.
}
\codebegin{4}{}\codeend
\codebegin{4}{mesg = ``\verb^Do you want to play again? (y/n) ^''}\codeend
\codebegin{4}{wo\$display(e,mesg)}\codeend
\codebegin{4}{ss\$move\_to(s, r, c + string\$size(mesg))}\codeend
\codebegin{4}{}\codeend
\codebegin{4}{k: key }\codeend
\codebegin{4}{{\bf while} true {\bf do}}\codeend
\codebegin{12}{kb\$wait(keyb)}\codeend
\codebegin{12}{k := kb\$get\_next\_key(keyb)}\codeend
\codebegin{12}{{\bf if} key\$is\_normal(k) }\codeend
\codebegin{12}{{\bf then}}\codeend
\codebegin{12}{ch: char := key\$value\_normal(k)}\codeend
\codebegin{12}{ss\$putc\_at(s,r,c+string\$size(mesg),ch)}\codeend
\codebegin{12}{{\bf if} ch = `\verb^y^' {$|$} ch = `\verb^Y^'}\codeend
\codebegin{16}{{\bf then} {\bf return}(true) {\bf end}}\codeend
\codebegin{12}{{\bf if} ch = `\verb^n^' {$|$} ch = `\verb^N^'}\codeend
\codebegin{16}{{\bf then} {\bf return}(false) {\bf end}}\codeend
\codebegin{14}{{\bf end}}\codeend
\codebegin{4}{{\bf end}}\codeend
\codebegin{2}{}\codeend
\codebegin{2}{{\bf end} again}\codeend
