Skip to content

Instantly share code, notes, and snippets.

@rblaze
Last active August 29, 2015 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rblaze/11062822 to your computer and use it in GitHub Desktop.
Save rblaze/11062822 to your computer and use it in GitHub Desktop.
Minesweeper cheater
type Field = array<bool>
let rec printField xsize (field : Field) =
let printLine i = Array.sub field (i * xsize) xsize |> Array.map (fun v -> if v then 'X' else '.')
[for n in 0 .. field.Length / xsize - 1 -> System.String(printLine n)]
let genField size (g : System.Random) = Array.init size (fun _ -> g.Next(100) < 20)
let hasMine xsize (field : Field) (x, y) = field.[y * xsize + x]
let countMines xsize (field : Field) x y =
let ysize = field.Length / xsize
let pts = List.filter (fun (px, py) -> px >= 0 && px < xsize && py >= 0 && py <= ysize) [(x-1, y-1); (x, y-1); (x+1, y-1); (x-1, y); (x+1, y); (x-1, y+1); (x, y+1); (x+1, y+1)]
List.length <| List.filter (hasMine xsize field) pts
let checkField xsize (field : Field) (counts : list<int * int * int>) (mines : list<int * int>) =
List.forall (hasMine xsize field) mines && List.forall (fun (x,y,n) -> countMines xsize field x y = n) counts
[<EntryPoint>]
let main _ =
let counts = [(5,6,3); (9,9,2); (6,10,1); (6,11,3)]
let mines = [(5,9)]
let xsize = 20
let ysize = 20
let rnd = System.Random()
let rec findField n =
let field = genField (xsize * ysize) rnd
if checkField xsize field counts mines then (n, field) else findField (n + 1)
let (n, field) = findField 0
let strs = printField xsize field
for s in strs do
printfn "%s" s
printfn "%d" n
0 // return an integer exit code
{-# LANGUAGE BangPatterns #-}
module Main where
-- assume field 20x20, where user opened few cells
-- .................... 0
-- .................... 1
-- .................... 2
-- .................... 3
-- .................... 4
-- .................... 5
-- .....3.............. 6
-- .................... 7
-- .................... 8
-- .....X...2.......... 9
-- ......1............. 10
-- ......3............. 11
-- .................... 12
-- .................... 13
-- .................... 14
-- .................... 15
-- .................... 16
-- .................... 17
-- .................... 18
-- .................... 19
-- 01234567890123456789
--
-- (5,6) = 3
-- (9,9) = 2
-- (6,10) = 1
-- (6,11) = 3
-- (5,9) has mine
import System.Random
import Data.Vector.Generic ((!))
import qualified Data.Vector.Unboxed as V
type Field = V.Vector Bool
printField :: Int -> Field -> [String]
printField _ field | V.null field = []
printField xsize field =
let (r, rs) = V.splitAt xsize field
str = map (\v -> if v then 'X' else '.') (V.toList r)
in str : printField xsize rs
hasMine :: Int -> Field -> Int -> Int -> Bool
hasMine xsize field x y = field ! (y * xsize + x)
countMines :: Int -> Field -> Int -> Int -> Int
countMines xsize field x y =
let ysize = V.length field `div` xsize
pts = filter (\(px, py) -> px >= 0 && px < xsize && py >=0 && py < ysize) [(x-1, y-1), (x-1, y), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y-1), (x+1,y), (x+1,y+1)]
in length $ filter (uncurry $ hasMine xsize field) pts
checkField :: Int -> Field -> [(Int, Int, Int)] -> [(Int, Int)] -> Bool
checkField xsize field cnts mines =
all (uncurry $ hasMine xsize field) mines &&
all (\(x, y, c) -> countMines xsize field x y == c) cnts
genField :: RandomGen r => Int -> r -> Field
genField size g = V.fromList $ take size $ map step $ randomRs (0, 100) g
where
step :: Int -> Bool
step n = n < 20
main :: IO ()
main = do
let cnts = [(5,6,3),(9,9,2),(6,10,1),(6,11,3)]
let mines = [(5,9)]
gen <- getStdGen
let loop !n g = do
let (g1, g2) = split g
let field = genField 400 g1
-- let f = printField 20 field
-- mapM_ putStrLn f
-- putStrLn ("--- " ++ show n)
if checkField 20 field cnts mines
then return (n, field)
else loop (n + 1 :: Int) g2
(n, field) <- loop 0 gen
let f = printField 20 field
mapM_ putStrLn f
putStrLn ("iteration " ++ show n)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment