From f94f03cfb01011f0b0416cb624842b86ad1b1666 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Wed, 27 Dec 2017 23:30:43 -0800 Subject: 4167 - show square colors in chessboard app --- chessboard.mu | 12 +- html/chessboard.mu.html | 808 ++++++++++++++++++++++++------------------------ 2 files changed, 420 insertions(+), 400 deletions(-) diff --git a/chessboard.mu b/chessboard.mu index 946708e1..3797c805 100644 --- a/chessboard.mu +++ b/chessboard.mu @@ -161,7 +161,8 @@ def print screen:&:screen, board:board -> screen:&:screen [ break-if done? f:&:@:char <- index *board, col c:char <- index *f, row - print screen, c + bg:num <- square-color row, col + print screen, c, 7/white, bg print screen, space col <- add col, 1 loop @@ -177,6 +178,15 @@ def print screen:&:screen, board:board -> screen:&:screen [ cursor-to-next-line screen ] +def square-color row:num, col:num -> result:num [ + local-scope + load-inputs + result <- copy 0/black + x:num <- add row, col + _, rem:num <- divide-with-remainder x, 2 + return-if rem, 238 +] + def initial-position -> board:board [ local-scope # layout in memory (in raster order): diff --git a/html/chessboard.mu.html b/html/chessboard.mu.html index f7ed3205..7bc3a098 100644 --- a/html/chessboard.mu.html +++ b/html/chessboard.mu.html @@ -116,7 +116,7 @@ if ('onhashchange' in window) { 52 ¦ . +---------------- . 53 ¦ . a b c d e f g h . 54 ¦ . . - 55 ¦ .Type in your move as <from square>-<to square>. For example: 'a2-a4'. Then press <enter>. . + 55 ¦ .Type in your move as <from square>-<to square>. For example: 'a2-a4'. Then press <enter>. . 56 ¦ . . 57 ¦ .Hit 'q' to exit. . 58 ¦ . . @@ -133,7 +133,7 @@ if ('onhashchange' in window) { 69 def chessboard screen:&:screen, console:&:console -> screen:&:screen, console:&:console [ 70 local-scope 71 load-inputs - 72 board:board <- initial-position + 72 board:board <- initial-position 73 # hook up stdin 74 stdin-in:&:source:char, stdin-out:&:sink:char <- new-channel 10/capacity 75 start-running send-keys-to-channel, console, stdin-out, screen @@ -146,7 +146,7 @@ if ('onhashchange' in window) { 82 ¦ cursor-to-next-line screen 83 ¦ print screen, board 84 ¦ cursor-to-next-line screen - 85 ¦ print screen, [Type in your move as <from square>-<to square>. For example: 'a2-a4'. Then press <enter>. + 85 ¦ print screen, [Type in your move as <from square>-<to square>. For example: 'a2-a4'. Then press <enter>. 86 ] 87 ¦ cursor-to-next-line screen 88 ¦ print screen [Hit 'q' to exit. @@ -154,12 +154,12 @@ if ('onhashchange' in window) { 90 ¦ { 91 ¦ ¦ cursor-to-next-line screen 92 ¦ ¦ screen <- print screen, [move: ] - 93 ¦ ¦ m:&:move, quit:bool, error:bool <- read-move buffered-stdin-in, screen + 93 ¦ ¦ m:&:move, quit:bool, error:bool <- read-move buffered-stdin-in, screen 94 ¦ ¦ break-if quit, +quit 95 ¦ ¦ buffered-stdin-in <- clear buffered-stdin-in # cleanup after error. todo: test this? 96 ¦ ¦ loop-if error 97 ¦ } - 98 ¦ board <- make-move board, m + 98 ¦ board <- make-move board, m 99 ¦ screen <- clear-screen screen 100 ¦ loop 101 } @@ -168,7 +168,7 @@ if ('onhashchange' in window) { 104 105 ## a board is an array of files, a file is an array of characters (squares) 106 -107 def new-board initial-position:&:@:char -> board:board [ +107 def new-board initial-position:&:@:char -> board:board [ 108 local-scope 109 load-inputs 110 # assert(length(initial-position) == 64) @@ -181,7 +181,7 @@ if ('onhashchange' in window) { 117 { 118 ¦ done?:bool <- equal col, 8 119 ¦ break-if done? -120 ¦ file:&:@:char <- new-file initial-position, col +120 ¦ file:&:@:char <- new-file initial-position, col 121 ¦ *board <- put-index *board, col, file 122 ¦ col <- add col, 1 123 ¦ loop @@ -225,405 +225,415 @@ if ('onhashchange' in window) { 161 ¦ ¦ break-if done? 162 ¦ ¦ f:&:@:char <- index *board, col 163 ¦ ¦ c:char <- index *f, row -164 ¦ ¦ print screen, c -165 ¦ ¦ print screen, space -166 ¦ ¦ col <- add col, 1 -167 ¦ ¦ loop -168 ¦ } -169 ¦ row <- subtract row, 1 -170 ¦ cursor-to-next-line screen -171 ¦ loop -172 } -173 # print file letters as legend -174 print screen, [ +----------------] -175 cursor-to-next-line screen -176 print screen, [ a b c d e f g h] -177 cursor-to-next-line screen -178 ] -179 -180 def initial-position -> board:board [ -181 local-scope -182 # layout in memory (in raster order): -183 # R P _ _ _ _ p r -184 # N P _ _ _ _ p n -185 # B P _ _ _ _ p b -186 # Q P _ _ _ _ p q -187 # K P _ _ _ _ p k -188 # B P _ _ _ _ p B -189 # N P _ _ _ _ p n -190 # R P _ _ _ _ p r -191 initial-position:&:@:char <- new-array 82/R, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 114/r, 78/N, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 110/n, 66/B, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 98/b, 81/Q, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 113/q, 75/K, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 107/k, 66/B, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 98/b, 78/N, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 110/n, 82/R, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 114/r -192 #? 82/R, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 114/r, -193 #? 78/N, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 110/n, -194 #? 66/B, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 98/b, -195 #? 81/Q, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 113/q, -196 #? 75/K, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 107/k, -197 #? 66/B, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 98/b, -198 #? 78/N, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 110/n, -199 #? 82/R, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 114/r -200 board <- new-board initial-position -201 ] -202 -203 scenario printing-the-board [ -204 local-scope -205 board:board <- initial-position -206 assume-screen 30/width, 12/height -207 run [ -208 ¦ screen <- print screen, board -209 ] -210 screen-should-contain [ -211 # 012345678901234567890123456789 -212 ¦ .8 | r n b q k b n r . -213 ¦ .7 | p p p p p p p p . -214 ¦ .6 | . -215 ¦ .5 | . -216 ¦ .4 | . -217 ¦ .3 | . -218 ¦ .2 | P P P P P P P P . -219 ¦ .1 | R N B Q K B N R . -220 ¦ . +---------------- . -221 ¦ . a b c d e f g h . -222 ¦ . . -223 ¦ . . -224 ] -225 ] -226 -227 ## data structure: move -228 -229 container move [ -230 # valid range: 0-7 -231 from-file:num -232 from-rank:num -233 to-file:num -234 to-rank:num +164 ¦ ¦ bg:num <- square-color row, col +165 ¦ ¦ print screen, c, 7/white, bg +166 ¦ ¦ print screen, space +167 ¦ ¦ col <- add col, 1 +168 ¦ ¦ loop +169 ¦ } +170 ¦ row <- subtract row, 1 +171 ¦ cursor-to-next-line screen +172 ¦ loop +173 } +174 # print file letters as legend +175 print screen, [ +----------------] +176 cursor-to-next-line screen +177 print screen, [ a b c d e f g h] +178 cursor-to-next-line screen +179 ] +180 +181 def square-color row:num, col:num -> result:num [ +182 local-scope +183 load-inputs +184 result <- copy 0/black +185 x:num <- add row, col +186 _, rem:num <- divide-with-remainder x, 2 +187 return-if rem, 238 +188 ] +189 +190 def initial-position -> board:board [ +191 local-scope +192 # layout in memory (in raster order): +193 # R P _ _ _ _ p r +194 # N P _ _ _ _ p n +195 # B P _ _ _ _ p b +196 # Q P _ _ _ _ p q +197 # K P _ _ _ _ p k +198 # B P _ _ _ _ p B +199 # N P _ _ _ _ p n +200 # R P _ _ _ _ p r +201 initial-position:&:@:char <- new-array 82/R, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 114/r, 78/N, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 110/n, 66/B, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 98/b, 81/Q, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 113/q, 75/K, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 107/k, 66/B, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 98/b, 78/N, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 110/n, 82/R, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 114/r +202 #? 82/R, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 114/r, +203 #? 78/N, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 110/n, +204 #? 66/B, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 98/b, +205 #? 81/Q, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 113/q, +206 #? 75/K, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 107/k, +207 #? 66/B, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 98/b, +208 #? 78/N, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 110/n, +209 #? 82/R, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 114/r +210 board <- new-board initial-position +211 ] +212 +213 scenario printing-the-board [ +214 local-scope +215 board:board <- initial-position +216 assume-screen 30/width, 12/height +217 run [ +218 ¦ screen <- print screen, board +219 ] +220 screen-should-contain [ +221 # 012345678901234567890123456789 +222 ¦ .8 | r n b q k b n r . +223 ¦ .7 | p p p p p p p p . +224 ¦ .6 | . +225 ¦ .5 | . +226 ¦ .4 | . +227 ¦ .3 | . +228 ¦ .2 | P P P P P P P P . +229 ¦ .1 | R N B Q K B N R . +230 ¦ . +---------------- . +231 ¦ . a b c d e f g h . +232 ¦ . . +233 ¦ . . +234 ] 235 ] 236 -237 # prints only error messages to screen -238 def read-move stdin:&:source:char, screen:&:screen -> result:&:move, quit?:bool, error?:bool, stdin:&:source:char, screen:&:screen [ -239 local-scope -240 load-inputs -241 from-file:num, quit?:bool, error?:bool <- read-file stdin, screen -242 return-if quit?, 0/dummy -243 return-if error?, 0/dummy -244 # construct the move object -245 result:&:move <- new move:type -246 *result <- put *result, from-file:offset, from-file -247 from-rank:num, quit?, error? <- read-rank stdin, screen -248 return-if quit?, 0/dummy -249 return-if error?, 0/dummy -250 *result <- put *result, from-rank:offset, from-rank -251 error? <- expect-from-channel stdin, 45/dash, screen -252 return-if error?, 0/dummy, 0/quit -253 to-file:num, quit?, error? <- read-file stdin, screen -254 return-if quit?, 0/dummy -255 return-if error?, 0/dummy -256 *result <- put *result, to-file:offset, to-file -257 to-rank:num, quit?, error? <- read-rank stdin, screen +237 ## data structure: move +238 +239 container move [ +240 # valid range: 0-7 +241 from-file:num +242 from-rank:num +243 to-file:num +244 to-rank:num +245 ] +246 +247 # prints only error messages to screen +248 def read-move stdin:&:source:char, screen:&:screen -> result:&:move, quit?:bool, error?:bool, stdin:&:source:char, screen:&:screen [ +249 local-scope +250 load-inputs +251 from-file:num, quit?:bool, error?:bool <- read-file stdin, screen +252 return-if quit?, 0/dummy +253 return-if error?, 0/dummy +254 # construct the move object +255 result:&:move <- new move:type +256 *result <- put *result, from-file:offset, from-file +257 from-rank:num, quit?, error? <- read-rank stdin, screen 258 return-if quit?, 0/dummy 259 return-if error?, 0/dummy -260 *result <- put *result, to-rank:offset, to-rank -261 error? <- expect-from-channel stdin, 10/newline, screen +260 *result <- put *result, from-rank:offset, from-rank +261 error? <- expect-from-channel stdin, 45/dash, screen 262 return-if error?, 0/dummy, 0/quit -263 ] -264 -265 # valid values for file: 0-7 -266 def read-file stdin:&:source:char, screen:&:screen -> file:num, quit:bool, error:bool, stdin:&:source:char, screen:&:screen [ -267 local-scope -268 load-inputs -269 c:char, eof?:bool, stdin <- read stdin -270 return-if eof?, 0/dummy, 1/quit, 0/error -271 q-pressed?:bool <- equal c, 81/Q -272 return-if q-pressed?, 0/dummy, 1/quit, 0/error -273 q-pressed? <- equal c, 113/q -274 return-if q-pressed?, 0/dummy, 1/quit, 0/error -275 empty-fake-keyboard?:bool <- equal c, 0/eof -276 return-if empty-fake-keyboard?, 0/dummy, 1/quit, 0/error -277 { -278 ¦ newline?:bool <- equal c, 10/newline -279 ¦ break-unless newline? -280 ¦ print screen, [that's not enough] -281 ¦ return 0/dummy, 0/quit, 1/error -282 } -283 file:num <- subtract c, 97/a -284 # 'a' <= file <= 'h' -285 { -286 ¦ above-min:bool <- greater-or-equal file, 0 -287 ¦ break-if above-min -288 ¦ print screen, [file too low: ] -289 ¦ print screen, c -290 ¦ cursor-to-next-line screen +263 to-file:num, quit?, error? <- read-file stdin, screen +264 return-if quit?, 0/dummy +265 return-if error?, 0/dummy +266 *result <- put *result, to-file:offset, to-file +267 to-rank:num, quit?, error? <- read-rank stdin, screen +268 return-if quit?, 0/dummy +269 return-if error?, 0/dummy +270 *result <- put *result, to-rank:offset, to-rank +271 error? <- expect-from-channel stdin, 10/newline, screen +272 return-if error?, 0/dummy, 0/quit +273 ] +274 +275 # valid values for file: 0-7 +276 def read-file stdin:&:source:char, screen:&:screen -> file:num, quit:bool, error:bool, stdin:&:source:char, screen:&:screen [ +277 local-scope +278 load-inputs +279 c:char, eof?:bool, stdin <- read stdin +280 return-if eof?, 0/dummy, 1/quit, 0/error +281 q-pressed?:bool <- equal c, 81/Q +282 return-if q-pressed?, 0/dummy, 1/quit, 0/error +283 q-pressed? <- equal c, 113/q +284 return-if q-pressed?, 0/dummy, 1/quit, 0/error +285 empty-fake-keyboard?:bool <- equal c, 0/eof +286 return-if empty-fake-keyboard?, 0/dummy, 1/quit, 0/error +287 { +288 ¦ newline?:bool <- equal c, 10/newline +289 ¦ break-unless newline? +290 ¦ print screen, [that's not enough] 291 ¦ return 0/dummy, 0/quit, 1/error 292 } -293 { -294 ¦ below-max:bool <- lesser-than file, 8 -295 ¦ break-if below-max -296 ¦ print screen, [file too high: ] -297 ¦ print screen, c -298 ¦ return 0/dummy, 0/quit, 1/error -299 } -300 return file, 0/quit, 0/error -301 ] -302 -303 # valid values for rank: 0-7 -304 def read-rank stdin:&:source:char, screen:&:screen -> rank:num, quit?:bool, error?:bool, stdin:&:source:char, screen:&:screen [ -305 local-scope -306 load-inputs -307 c:char, eof?:bool, stdin <- read stdin -308 return-if eof?, 0/dummy, 1/quit, 0/error -309 q-pressed?:bool <- equal c, 81/Q -310 return-if q-pressed?, 0/dummy, 1/quit, 0/error -311 q-pressed? <- equal c, 113/q -312 return-if q-pressed?, 0/dummy, 1/quit, 0/error -313 empty-fake-keyboard?:bool <- equal c, 0/eof -314 return-if empty-fake-keyboard?, 0/dummy, 1/quit, 0/error -315 { -316 ¦ newline?:bool <- equal c, 10 # newline -317 ¦ break-unless newline? -318 ¦ print screen, [that's not enough] -319 ¦ return 0/dummy, 0/quit, 1/error -320 } -321 rank:num <- subtract c, 49/'1' -322 # assert'1' <= rank <= '8' -323 { -324 ¦ above-min:bool <- greater-or-equal rank, 0 -325 ¦ break-if above-min -326 ¦ print screen, [rank too low: ] -327 ¦ print screen, c -328 ¦ return 0/dummy, 0/quit, 1/error -329 } -330 { -331 ¦ below-max:bool <- lesser-or-equal rank, 7 -332 ¦ break-if below-max -333 ¦ print screen, [rank too high: ] -334 ¦ print screen, c -335 ¦ return 0/dummy, 0/quit, 1/error -336 } -337 return rank, 0/quit, 0/error -338 ] -339 -340 # read a character from the given channel and check that it's what we expect -341 # return true on error -342 def expect-from-channel stdin:&:source:char, expected:char, screen:&:screen -> result:bool, stdin:&:source:char, screen:&:screen [ -343 local-scope -344 load-inputs -345 c:char, eof?:bool, stdin <- read stdin -346 return-if eof? 1/true -347 { -348 ¦ match?:bool <- equal c, expected -349 ¦ break-if match? -350 ¦ print screen, [expected character not found] -351 } -352 result <- not match? -353 ] -354 -355 scenario read-move-blocking [ -356 local-scope -357 assume-screen 20/width, 2/height -358 source:&:source:char, sink:&:sink:char <- new-channel 2/capacity -359 read-move-routine:num/routine <- start-running read-move, source, screen -360 run [ -361 ¦ # 'read-move' is waiting for keypress -362 ¦ wait-for-routine-to-block read-move-routine -363 ¦ read-move-state:num <- routine-state read-move-routine -364 ¦ waiting?:bool <- not-equal read-move-state, 2/discontinued -365 ¦ assert waiting?, [ -366 F read-move-blocking: routine failed to pause after coming up (before any keys were pressed)] -367 ¦ # press 'a' -368 ¦ sink <- write sink, 97/a -369 ¦ restart read-move-routine -370 ¦ # 'read-move' still waiting for keypress -371 ¦ wait-for-routine-to-block read-move-routine -372 ¦ read-move-state <- routine-state read-move-routine -373 ¦ waiting? <- not-equal read-move-state, 2/discontinued -374 ¦ assert waiting?, [ -375 F read-move-blocking: routine failed to pause after rank 'a'] -376 ¦ # press '2' -377 ¦ sink <- write sink, 50/'2' -378 ¦ restart read-move-routine -379 ¦ # 'read-move' still waiting for keypress -380 ¦ wait-for-routine-to-block read-move-routine -381 ¦ read-move-state <- routine-state read-move-routine -382 ¦ waiting? <- not-equal read-move-state, 2/discontinued -383 ¦ assert waiting?, [ -384 F read-move-blocking: routine failed to pause after file 'a2'] -385 ¦ # press '-' -386 ¦ sink <- write sink, 45/'-' -387 ¦ restart read-move-routine -388 ¦ # 'read-move' still waiting for keypress -389 ¦ wait-for-routine-to-block read-move-routine -390 ¦ read-move-state <- routine-state read-move-routine -391 ¦ waiting? <- not-equal read-move-state, 2/discontinued -392 ¦ assert waiting?, [ -393 F read-move-blocking: routine failed to pause after hyphen 'a2-'] -394 ¦ # press 'a' -395 ¦ sink <- write sink, 97/a -396 ¦ restart read-move-routine -397 ¦ # 'read-move' still waiting for keypress -398 ¦ wait-for-routine-to-block read-move-routine -399 ¦ read-move-state <- routine-state read-move-routine -400 ¦ waiting? <- not-equal read-move-state, 2/discontinued -401 ¦ assert waiting?, [ -402 F read-move-blocking: routine failed to pause after rank 'a2-a'] -403 ¦ # press '4' -404 ¦ sink <- write sink, 52/'4' -405 ¦ restart read-move-routine -406 ¦ # 'read-move' still waiting for keypress -407 ¦ wait-for-routine-to-block read-move-routine -408 ¦ read-move-state <- routine-state read-move-routine -409 ¦ waiting? <- not-equal read-move-state, 2/discontinued -410 ¦ assert waiting?, [ -411 F read-move-blocking: routine failed to pause after file 'a2-a4'] -412 ¦ # press 'newline' -413 ¦ sink <- write sink, 10 # newline -414 ¦ restart read-move-routine -415 ¦ # 'read-move' now completes -416 ¦ wait-for-routine-to-block read-move-routine -417 ¦ read-move-state <- routine-state read-move-routine -418 ¦ completed?:bool <- equal read-move-state, 1/completed -419 ¦ assert completed?, [ -420 F read-move-blocking: routine failed to terminate on newline] -421 ¦ trace 1, [test], [reached end] -422 ] -423 trace-should-contain [ -424 ¦ test: reached end -425 ] -426 ] -427 -428 scenario read-move-quit [ -429 local-scope -430 assume-screen 20/width, 2/height -431 source:&:source:char, sink:&:sink:char <- new-channel 2/capacity -432 read-move-routine:num <- start-running read-move, source, screen -433 run [ -434 ¦ # 'read-move' is waiting for keypress -435 ¦ wait-for-routine-to-block read-move-routine -436 ¦ read-move-state:num <- routine-state read-move-routine -437 ¦ waiting?:bool <- not-equal read-move-state, 2/discontinued -438 ¦ assert waiting?, [ -439 F read-move-quit: routine failed to pause after coming up (before any keys were pressed)] -440 ¦ # press 'q' -441 ¦ sink <- write sink, 113/q -442 ¦ restart read-move-routine -443 ¦ # 'read-move' completes -444 ¦ wait-for-routine-to-block read-move-routine -445 ¦ read-move-state <- routine-state read-move-routine -446 ¦ completed?:bool <- equal read-move-state, 1/completed -447 ¦ assert completed?, [ -448 F read-move-quit: routine failed to terminate on 'q'] -449 ¦ trace 1, [test], [reached end] -450 ] -451 trace-should-contain [ -452 ¦ test: reached end -453 ] -454 ] -455 -456 scenario read-move-illegal-file [ -457 local-scope -458 assume-screen 20/width, 2/height -459 source:&:source:char, sink:&:sink:char <- new-channel 2/capacity -460 read-move-routine:num <- start-running read-move, source, screen -461 run [ -462 ¦ # 'read-move' is waiting for keypress -463 ¦ wait-for-routine-to-block read-move-routine -464 ¦ read-move-state:num <- routine-state read-move-routine -465 ¦ waiting?:bool <- not-equal read-move-state, 2/discontinued -466 ¦ assert waiting?, [ -467 F read-move-illegal-file: routine failed to pause after coming up (before any keys were pressed)] -468 ¦ sink <- write sink, 50/'2' -469 ¦ restart read-move-routine -470 ¦ wait-for-routine-to-block read-move-routine -471 ] -472 screen-should-contain [ -473 ¦ .file too low: 2 . -474 ¦ . . -475 ] -476 ] -477 -478 scenario read-move-illegal-rank [ -479 local-scope -480 assume-screen 20/width, 2/height -481 source:&:source:char, sink:&:sink:char <- new-channel 2/capacity -482 read-move-routine:num <- start-running read-move, source, screen -483 run [ -484 ¦ # 'read-move' is waiting for keypress -485 ¦ wait-for-routine-to-block read-move-routine -486 ¦ read-move-state:num <- routine-state read-move-routine -487 ¦ waiting?:bool <- not-equal read-move-state, 2/discontinued -488 ¦ assert waiting?, [ -489 F read-move-illegal-rank: routine failed to pause after coming up (before any keys were pressed)] -490 ¦ sink <- write sink, 97/a -491 ¦ sink <- write sink, 97/a -492 ¦ restart read-move-routine -493 ¦ wait-for-routine-to-block read-move-routine -494 ] -495 screen-should-contain [ -496 ¦ .rank too high: a . -497 ¦ . . -498 ] -499 ] -500 -501 scenario read-move-empty [ -502 local-scope -503 assume-screen 20/width, 2/height -504 source:&:source:char, sink:&:sink:char <- new-channel 2/capacity -505 read-move-routine:num <- start-running read-move, source, screen -506 run [ -507 ¦ # 'read-move' is waiting for keypress -508 ¦ wait-for-routine-to-block read-move-routine -509 ¦ read-move-state:num <- routine-state read-move-routine -510 ¦ waiting?:bool <- not-equal read-move-state, 2/discontinued -511 ¦ assert waiting?, [ -512 F read-move-empty: routine failed to pause after coming up (before any keys were pressed)] -513 ¦ sink <- write sink, 10/newline -514 ¦ sink <- write sink, 97/a -515 ¦ restart read-move-routine -516 ¦ wait-for-routine-to-block read-move-routine -517 ] -518 screen-should-contain [ -519 ¦ .that's not enough . -520 ¦ . . -521 ] -522 ] -523 -524 def make-move board:board, m:&:move -> board:board [ -525 local-scope -526 load-inputs -527 from-file:num <- get *m, from-file:offset -528 from-rank:num <- get *m, from-rank:offset -529 to-file:num <- get *m, to-file:offset -530 to-rank:num <- get *m, to-rank:offset -531 from-f:&:@:char <- index *board, from-file -532 to-f:&:@:char <- index *board, to-file -533 src:char/square <- index *from-f, from-rank -534 *to-f <- put-index *to-f, to-rank, src -535 *from-f <- put-index *from-f, from-rank, 32/space -536 ] -537 -538 scenario making-a-move [ -539 local-scope -540 assume-screen 30/width, 12/height -541 board:board <- initial-position -542 move:&:move <- new move:type -543 *move <- merge 6/g, 1/'2', 6/g, 3/'4' -544 run [ -545 ¦ board <- make-move board, move -546 ¦ screen <- print screen, board -547 ] -548 screen-should-contain [ -549 # 012345678901234567890123456789 -550 ¦ .8 | r n b q k b n r . -551 ¦ .7 | p p p p p p p p . -552 ¦ .6 | . -553 ¦ .5 | . -554 ¦ .4 | P . -555 ¦ .3 | . -556 ¦ .2 | P P P P P P P . -557 ¦ .1 | R N B Q K B N R . -558 ¦ . +---------------- . -559 ¦ . a b c d e f g h . -560 ¦ . . -561 ] -562 ] +293 file:num <- subtract c, 97/a +294 # 'a' <= file <= 'h' +295 { +296 ¦ above-min:bool <- greater-or-equal file, 0 +297 ¦ break-if above-min +298 ¦ print screen, [file too low: ] +299 ¦ print screen, c +300 ¦ cursor-to-next-line screen +301 ¦ return 0/dummy, 0/quit, 1/error +302 } +303 { +304 ¦ below-max:bool <- lesser-than file, 8 +305 ¦ break-if below-max +306 ¦ print screen, [file too high: ] +307 ¦ print screen, c +308 ¦ return 0/dummy, 0/quit, 1/error +309 } +310 return file, 0/quit, 0/error +311 ] +312 +313 # valid values for rank: 0-7 +314 def read-rank stdin:&:source:char, screen:&:screen -> rank:num, quit?:bool, error?:bool, stdin:&:source:char, screen:&:screen [ +315 local-scope +316 load-inputs +317 c:char, eof?:bool, stdin <- read stdin +318 return-if eof?, 0/dummy, 1/quit, 0/error +319 q-pressed?:bool <- equal c, 81/Q +320 return-if q-pressed?, 0/dummy, 1/quit, 0/error +321 q-pressed? <- equal c, 113/q +322 return-if q-pressed?, 0/dummy, 1/quit, 0/error +323 empty-fake-keyboard?:bool <- equal c, 0/eof +324 return-if empty-fake-keyboard?, 0/dummy, 1/quit, 0/error +325 { +326 ¦ newline?:bool <- equal c, 10 # newline +327 ¦ break-unless newline? +328 ¦ print screen, [that's not enough] +329 ¦ return 0/dummy, 0/quit, 1/error +330 } +331 rank:num <- subtract c, 49/'1' +332 # assert'1' <= rank <= '8' +333 { +334 ¦ above-min:bool <- greater-or-equal rank, 0 +335 ¦ break-if above-min +336 ¦ print screen, [rank too low: ] +337 ¦ print screen, c +338 ¦ return 0/dummy, 0/quit, 1/error +339 } +340 { +341 ¦ below-max:bool <- lesser-or-equal rank, 7 +342 ¦ break-if below-max +343 ¦ print screen, [rank too high: ] +344 ¦ print screen, c +345 ¦ return 0/dummy, 0/quit, 1/error +346 } +347 return rank, 0/quit, 0/error +348 ] +349 +350 # read a character from the given channel and check that it's what we expect +351 # return true on error +352 def expect-from-channel stdin:&:source:char, expected:char, screen:&:screen -> result:bool, stdin:&:source:char, screen:&:screen [ +353 local-scope +354 load-inputs +355 c:char, eof?:bool, stdin <- read stdin +356 return-if eof? 1/true +357 { +358 ¦ match?:bool <- equal c, expected +359 ¦ break-if match? +360 ¦ print screen, [expected character not found] +361 } +362 result <- not match? +363 ] +364 +365 scenario read-move-blocking [ +366 local-scope +367 assume-screen 20/width, 2/height +368 source:&:source:char, sink:&:sink:char <- new-channel 2/capacity +369 read-move-routine:num/routine <- start-running read-move, source, screen +370 run [ +371 ¦ # 'read-move' is waiting for keypress +372 ¦ wait-for-routine-to-block read-move-routine +373 ¦ read-move-state:num <- routine-state read-move-routine +374 ¦ waiting?:bool <- not-equal read-move-state, 2/discontinued +375 ¦ assert waiting?, [ +376 F read-move-blocking: routine failed to pause after coming up (before any keys were pressed)] +377 ¦ # press 'a' +378 ¦ sink <- write sink, 97/a +379 ¦ restart read-move-routine +380 ¦ # 'read-move' still waiting for keypress +381 ¦ wait-for-routine-to-block read-move-routine +382 ¦ read-move-state <- routine-state read-move-routine +383 ¦ waiting? <- not-equal read-move-state, 2/discontinued +384 ¦ assert waiting?, [ +385 F read-move-blocking: routine failed to pause after rank 'a'] +386 ¦ # press '2' +387 ¦ sink <- write sink, 50/'2' +388 ¦ restart read-move-routine +389 ¦ # 'read-move' still waiting for keypress +390 ¦ wait-for-routine-to-block read-move-routine +391 ¦ read-move-state <- routine-state read-move-routine +392 ¦ waiting? <- not-equal read-move-state, 2/discontinued +393 ¦ assert waiting?, [ +394 F read-move-blocking: routine failed to pause after file 'a2'] +395 ¦ # press '-' +396 ¦ sink <- write sink, 45/'-' +397 ¦ restart read-move-routine +398 ¦ # 'read-move' still waiting for keypress +399 ¦ wait-for-routine-to-block read-move-routine +400 ¦ read-move-state <- routine-state read-move-routine +401 ¦ waiting? <- not-equal read-move-state, 2/discontinued +402 ¦ assert waiting?, [ +403 F read-move-blocking: routine failed to pause after hyphen 'a2-'] +404 ¦ # press 'a' +405 ¦ sink <- write sink, 97/a +406 ¦ restart read-move-routine +407 ¦ # 'read-move' still waiting for keypress +408 ¦ wait-for-routine-to-block read-move-routine +409 ¦ read-move-state <- routine-state read-move-routine +410 ¦ waiting? <- not-equal read-move-state, 2/discontinued +411 ¦ assert waiting?, [ +412 F read-move-blocking: routine failed to pause after rank 'a2-a'] +413 ¦ # press '4' +414 ¦ sink <- write sink, 52/'4' +415 ¦ restart read-move-routine +416 ¦ # 'read-move' still waiting for keypress +417 ¦ wait-for-routine-to-block read-move-routine +418 ¦ read-move-state <- routine-state read-move-routine +419 ¦ waiting? <- not-equal read-move-state, 2/discontinued +420 ¦ assert waiting?, [ +421 F read-move-blocking: routine failed to pause after file 'a2-a4'] +422 ¦ # press 'newline' +423 ¦ sink <- write sink, 10 # newline +424 ¦ restart read-move-routine +425 ¦ # 'read-move' now completes +426 ¦ wait-for-routine-to-block read-move-routine +427 ¦ read-move-state <- routine-state read-move-routine +428 ¦ completed?:bool <- equal read-move-state, 1/completed +429 ¦ assert completed?, [ +430 F read-move-blocking: routine failed to terminate on newline] +431 ¦ trace 1, [test], [reached end] +432 ] +433 trace-should-contain [ +434 ¦ test: reached end +435 ] +436 ] +437 +438 scenario read-move-quit [ +439 local-scope +440 assume-screen 20/width, 2/height +441 source:&:source:char, sink:&:sink:char <- new-channel 2/capacity +442 read-move-routine:num <- start-running read-move, source, screen +443 run [ +444 ¦ # 'read-move' is waiting for keypress +445 ¦ wait-for-routine-to-block read-move-routine +446 ¦ read-move-state:num <- routine-state read-move-routine +447 ¦ waiting?:bool <- not-equal read-move-state, 2/discontinued +448 ¦ assert waiting?, [ +449 F read-move-quit: routine failed to pause after coming up (before any keys were pressed)] +450 ¦ # press 'q' +451 ¦ sink <- write sink, 113/q +452 ¦ restart read-move-routine +453 ¦ # 'read-move' completes +454 ¦ wait-for-routine-to-block read-move-routine +455 ¦ read-move-state <- routine-state read-move-routine +456 ¦ completed?:bool <- equal read-move-state, 1/completed +457 ¦ assert completed?, [ +458 F read-move-quit: routine failed to terminate on 'q'] +459 ¦ trace 1, [test], [reached end] +460 ] +461 trace-should-contain [ +462 ¦ test: reached end +463 ] +464 ] +465 +466 scenario read-move-illegal-file [ +467 local-scope +468 assume-screen 20/width, 2/height +469 source:&:source:char, sink:&:sink:char <- new-channel 2/capacity +470 read-move-routine:num <- start-running read-move, source, screen +471 run [ +472 ¦ # 'read-move' is waiting for keypress +473 ¦ wait-for-routine-to-block read-move-routine +474 ¦ read-move-state:num <- routine-state read-move-routine +475 ¦ waiting?:bool <- not-equal read-move-state, 2/discontinued +476 ¦ assert waiting?, [ +477 F read-move-illegal-file: routine failed to pause after coming up (before any keys were pressed)] +478 ¦ sink <- write sink, 50/'2' +479 ¦ restart read-move-routine +480 ¦ wait-for-routine-to-block read-move-routine +481 ] +482 screen-should-contain [ +483 ¦ .file too low: 2 . +484 ¦ . . +485 ] +486 ] +487 +488 scenario read-move-illegal-rank [ +489 local-scope +490 assume-screen 20/width, 2/height +491 source:&:source:char, sink:&:sink:char <- new-channel 2/capacity +492 read-move-routine:num <- start-running read-move, source, screen +493 run [ +494 ¦ # 'read-move' is waiting for keypress +495 ¦ wait-for-routine-to-block read-move-routine +496 ¦ read-move-state:num <- routine-state read-move-routine +497 ¦ waiting?:bool <- not-equal read-move-state, 2/discontinued +498 ¦ assert waiting?, [ +499 F read-move-illegal-rank: routine failed to pause after coming up (before any keys were pressed)] +500 ¦ sink <- write sink, 97/a +501 ¦ sink <- write sink, 97/a +502 ¦ restart read-move-routine +503 ¦ wait-for-routine-to-block read-move-routine +504 ] +505 screen-should-contain [ +506 ¦ .rank too high: a . +507 ¦ . . +508 ] +509 ] +510 +511 scenario read-move-empty [ +512 local-scope +513 assume-screen 20/width, 2/height +514 source:&:source:char, sink:&:sink:char <- new-channel 2/capacity +515 read-move-routine:num <- start-running read-move, source, screen +516 run [ +517 ¦ # 'read-move' is waiting for keypress +518 ¦ wait-for-routine-to-block read-move-routine +519 ¦ read-move-state:num <- routine-state read-move-routine +520 ¦ waiting?:bool <- not-equal read-move-state, 2/discontinued +521 ¦ assert waiting?, [ +522 F read-move-empty: routine failed to pause after coming up (before any keys were pressed)] +523 ¦ sink <- write sink, 10/newline +524 ¦ sink <- write sink, 97/a +525 ¦ restart read-move-routine +526 ¦ wait-for-routine-to-block read-move-routine +527 ] +528 screen-should-contain [ +529 ¦ .that's not enough . +530 ¦ . . +531 ] +532 ] +533 +534 def make-move board:board, m:&:move -> board:board [ +535 local-scope +536 load-inputs +537 from-file:num <- get *m, from-file:offset +538 from-rank:num <- get *m, from-rank:offset +539 to-file:num <- get *m, to-file:offset +540 to-rank:num <- get *m, to-rank:offset +541 from-f:&:@:char <- index *board, from-file +542 to-f:&:@:char <- index *board, to-file +543 src:char/square <- index *from-f, from-rank +544 *to-f <- put-index *to-f, to-rank, src +545 *from-f <- put-index *from-f, from-rank, 32/space +546 ] +547 +548 scenario making-a-move [ +549 local-scope +550 assume-screen 30/width, 12/height +551 board:board <- initial-position +552 move:&:move <- new move:type +553 *move <- merge 6/g, 1/'2', 6/g, 3/'4' +554 run [ +555 ¦ board <- make-move board, move +556 ¦ screen <- print screen, board +557 ] +558 screen-should-contain [ +559 # 012345678901234567890123456789 +560 ¦ .8 | r n b q k b n r . +561 ¦ .7 | p p p p p p p p . +562 ¦ .6 | . +563 ¦ .5 | . +564 ¦ .4 | P . +565 ¦ .3 | . +566 ¦ .2 | P P P P P P P . +567 ¦ .1 | R N B Q K B N R . +568 ¦ . +---------------- . +569 ¦ . a b c d e f g h . +570 ¦ . . +571 ] +572 ] -- cgit 1.4.1-2-gfad0