62 lines
1.8 KiB
Haskell
62 lines
1.8 KiB
Haskell
{-# LANGUAGE DataKinds #-}
|
|
{-# LANGUAGE DeriveGeneric #-}
|
|
{-# LANGUAGE FlexibleInstances #-}
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
{-# LANGUAGE StandaloneDeriving #-}
|
|
{-# LANGUAGE TypeOperators #-}
|
|
|
|
module Main where
|
|
|
|
import Lib
|
|
import Options.Generic
|
|
import System.Random
|
|
import Text.Read
|
|
|
|
data Parameters w =
|
|
Parameters
|
|
{ width :: w ::: Int <?> "Width of the board"
|
|
, length :: w ::: Int <?> "Length of the board"
|
|
, bombs :: w ::: Int <?> "Number of bombs to be placed"
|
|
}
|
|
deriving (Generic)
|
|
|
|
instance ParseRecord (Parameters Wrapped)
|
|
|
|
deriving instance Show (Parameters Unwrapped)
|
|
|
|
main :: IO ()
|
|
main = do
|
|
(Parameters boardWidth boardLength bombsCount) <- unwrapRecord "Minesweeper"
|
|
generator <- newStdGen
|
|
gameStep . createBoard boardWidth boardLength $
|
|
generateRandomCoordinates (boardWidth - 1) (boardLength - 1) bombsCount generator
|
|
|
|
gameStep :: Board -> IO ()
|
|
gameStep board = do
|
|
putStrLn . convertBoardToString $ board
|
|
coordinates <- getCoordinates
|
|
let nextBoard = revealTile coordinates board
|
|
if isGameLost nextBoard
|
|
then gameLost nextBoard
|
|
else if isGameWon nextBoard
|
|
then gameWon nextBoard
|
|
else gameStep nextBoard
|
|
|
|
getCoordinates :: IO (Int, Int)
|
|
getCoordinates = do
|
|
putStrLn "Enter the coordinates of the tile to reveal (X then Y, zero indexed):"
|
|
xString <- getLine
|
|
yString <- getLine
|
|
case (readMaybe xString, readMaybe yString) of
|
|
(Just x, Just y) -> return (x, y)
|
|
_ -> putStrLn "Invalid coordinates!" >> getCoordinates
|
|
|
|
gameLost :: Board -> IO ()
|
|
gameLost board = do
|
|
putStrLn . convertBoardToString . revealAll $ board
|
|
putStrLn "Boom! You lost!"
|
|
|
|
gameWon :: Board -> IO ()
|
|
gameWon board = do
|
|
putStrLn . convertBoardToString $ board
|
|
putStrLn "You won! All the bombs were found!"
|