Flipping bits game: Difference between revisions
Content added Content deleted
SqrtNegInf (talk | contribs) m (→{{header|Perl 6}}: numeric sorting of rows) |
(→{{header|Haskell}}: Specified imports, applied hlint, hindent) |
||
Line 1,264: | Line 1,264: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
Maximum game size is 9x9 because the array indices are the characters 1 until 9. |
Maximum game size is 9x9 because the array indices are the characters 1 until 9. |
||
<lang Haskell> |
<lang Haskell>import Data.Array (Array, (!), (//), array, bounds) |
||
import Data.Array |
|||
import Data.List |
import Data.List (intersperse) |
||
import Control.Monad |
|||
import Control.Monad (zipWithM_, replicateM, foldM, when) |
|||
⚫ | |||
⚫ | |||
type Board = Array (Char, Char) Int |
type Board = Array (Char, Char) Int |
||
Line 1,276: | Line 1,278: | ||
flp 1 = 0 |
flp 1 = 0 |
||
numRows, numCols :: Board -> |
numRows, numCols :: Board -> String |
||
numRows t = |
|||
let ((a, _), (b, _)) = bounds t |
|||
in [a .. b] |
|||
numCols t = |
|||
⚫ | |||
in [a .. b] |
|||
⚫ | |||
⚫ | |||
flipRow, flipCol :: Board -> Char -> Board |
flipRow, flipCol :: Board -> Char -> Board |
||
flipRow t r = |
flipRow t r = |
||
let e = |
|||
⚫ | |||
[ (ix, flp (t ! ix)) |
|||
⚫ | |||
in t // e |
|||
flipCol t c = |
flipCol t c = |
||
let e = |
|||
⚫ | |||
[ (ix, flp (t ! ix)) |
|||
⚫ | |||
in t // e |
|||
printBoard :: Board -> IO () |
printBoard :: Board -> IO () |
||
printBoard t = do |
printBoard t = do |
||
let rows = numRows t |
|||
cols = numCols t |
|||
f 0 = '0' |
|||
f 1 = '1' |
|||
p r xs = putStrLn $ [r, ' '] ++ intersperse ' ' (map f xs) |
|||
putStrLn $ " " ++ intersperse ' ' cols |
|||
zipWithM_ |
|||
zipWithM_ p rows [ [ t ! (y, x) | x <- cols ] | y <- rows ] |
|||
⚫ | |||
⚫ | |||
[ [ t ! (y, x) |
|||
⚫ | |||
| y <- rows ] |
|||
-- create a random goal board, and flip rows and columns randomly |
-- create a random goal board, and flip rows and columns randomly |
||
-- to get a starting board |
-- to get a starting board |
||
setupGame :: Char -> Char -> IO (Board, Board) |
setupGame :: Char -> Char -> IO (Board, Board) |
||
setupGame sizey sizex |
setupGame sizey sizex |
||
-- random cell value at (row, col) |
-- random cell value at (row, col) |
||
= do |
|||
⚫ | |||
let mk rc = (\v -> (rc, v)) <$> randomRIO (0, 1) |
|||
rows = ['a' .. sizey] |
|||
cols = ['1' .. sizex] |
|||
goal <- |
|||
mapM mk [ (r, c) | r <- rows, c <- cols ] |
|||
array (('a', '1'), (sizey, sizex)) <$> |
|||
⚫ | |||
mapM |
|||
⚫ | |||
mk |
|||
-- flip random row |
|||
[ (r, c) |
|||
⚫ | |||
| r <- rows |
|||
, c <- cols ] |
|||
⚫ | |||
start <- |
|||
numMoves <- randomRIO (3, 15) -- how many flips (3 - 15) |
|||
⚫ | |||
-- determine if rows or cols are flipped |
|||
-- flip random row |
|||
⚫ | |||
⚫ | |||
-- flip random col |
|||
⚫ | |||
⚫ | |||
numMoves <- randomRIO (3, 15) -- how many flips (3 - 15) |
|||
-- determine if rows or cols are flipped |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
then return (goal, start) -- all ok, return both boards |
|||
else setupGame sizey sizex -- try again |
|||
main :: IO () |
main :: IO () |
||
main = do |
main = do |
||
putStrLn "Select a board size (1 - 9).\nPress any other key to exit." |
|||
sizec <- getChar |
|||
when (sizec `elem` ['1' .. '9']) $ |
|||
do let size = read [sizec] - 1 |
|||
(g, s) <- setupGame (['a' ..] !! size) (['1' ..] !! size) |
|||
turns g s 0 |
|||
where |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
printBoard current |
|||
⚫ | |||
when (moves > 0) $ |
|||
putStrLn $ "\nYou've made " ++ show moves ++ " moves so far." |
|||
putStrLn $ |
|||
"\nFlip a row (" ++ |
|||
numRows current ++ ") or a column (" ++ numCols current ++ ")" |
|||
v <- getChar |
|||
if v `elem` numRows current |
|||
then check $ flipRow current v |
|||
else if v `elem` numCols current |
|||
then check $ flipCol current v |
|||
else tryAgain |
|||
where |
|||
check t = |
|||
if t == goal |
|||
then putStrLn $ "\nYou've won in " ++ |
|||
then putStrLn $ "\nYou've won in " ++ show (moves + 1) ++ " moves!" |
|||
else turns goal t (moves + 1) |
|||
tryAgain = do |
|||
putStrLn ": Invalid row or column." |
|||
turns goal current moves</lang> |
|||
putStrLn ": Invalid row or column." |
|||
{{Out}} |
|||
⚫ | |||
⚫ | |||
</lang> |
|||
<b>Output:</b> |
|||
<pre> |
|||
⚫ | |||
Press any other key to exit. |
Press any other key to exit. |
||
3 |
3 |
||
Line 1,395: | Line 1,413: | ||
Flip a row (abc) or a column (123) |
Flip a row (abc) or a column (123) |
||
c |
c |
||
You've won in 2 moves! |
You've won in 2 moves!</pre> |
||
</pre> |
|||
=={{header|J}}== |
=={{header|J}}== |