FlippingBits := module() export ModuleApply; local gameSetup, flip, printGrid, checkInput; local board; gameSetup := proc(n) local r, c, i, toFlip, target; randomize(): target := Array( 1..n, 1..n, rand(0..1) ); board := copy(target); for i to rand(3..9)() do toFlip := [0, 0]; toFlip[1] := StringTools[Random](1, "rc"); toFlip[2] := convert(rand(1..n)(), string); flip(toFlip); end do; return target; end proc; flip := proc(line) local i, lineNum; lineNum := parse(op(line[2..-1])); for i to upperbound(board)[1] do if line[1] = "R" then board[lineNum, i] := `if`(board[lineNum, i] = 0, 1, 0); else board[i, lineNum] := `if`(board[i, lineNum] = 0, 1, 0); end if; end do; return NULL; end proc; printGrid := proc(grid) local r, c; for r to upperbound(board)[1] do for c to upperbound(board)[1] do printf("%a ", grid[r, c]); end do; printf("\n"); end do; printf("\n"); return NULL; end proc; checkInput := proc(input) try if input[1] = "" then return false, ""; elif not input[1] = "R" and not input[1] = "C" then return false, "Please start with 'r' or 'c'."; elif not type(parse(op(input[2..-1])), posint) then error; elif parse(op(input[2..-1])) < 1 or parse(op(input[2..-1])) > upperbound(board)[1] then return false, "Row or column number too large or too small."; end if; catch: return false, "Please indicate a row or column number." end try; return true, ""; end proc; ModuleApply := proc(n) local gameOver, toFlip, target, answer, restart; restart := true; while restart do target := gameSetup(n); while ArrayTools[IsEqual](target, board) do target := gameSetup(n); end do; gameOver := false; while not gameOver do printf("The Target:\n"); printGrid(target); printf("The Board:\n"); printGrid(board); if ArrayTools[IsEqual](target, board) then printf("You win!! Press enter to play again or type END to quit.\n\n"); answer := StringTools[UpperCase](readline()); gameOver := true; if answer = "END" then restart := false end if; else toFlip := ["", ""]; while not checkInput(toFlip)[1] and not gameOver do ifelse (not op(checkInput(toFlip)[2..-1]) = "", printf("%s\n\n", op(checkInput(toFlip)[2..-1])), NULL); printf("Please enter a row or column to flip. (ex: r1 or c2) Press enter for a new game or type END to quit.\n\n"); answer := StringTools[UpperCase](readline()); if answer = "END" or answer = "" then gameOver := true; if answer = "END" then restart := false; end if; end if; toFlip := [substring(answer, 1), substring(answer, 2..-1)]; end do; if not gameOver then flip(toFlip); end if; end if; end do; end do; printf("Game Over!\n"); end proc; end module: FlippingBits(3);