{- Main module. Copyright (C) 2020 Max Schröder This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . This module contains the game settings and the main function for simulating a game and generating a video. NOTE: Have a look at Readme.md for information on this project, the different modules and how to build and run the program. -} module Wettbewerb.Main (main) where import Prelude hiding (Either(..)) import Data.Sequence (Seq, fromList) import System.Random (randomIO) import System.Environment (getArgs) import Wettbewerb.Types (Board, Direction(Right), Snake(Snake), State(State), StrategyParams, Position, snake, parts) import Wettbewerb.Snake (simulateGame, generateFood) import Wettbewerb.Strategy (hamiltonStrategyParams) import Wettbewerb.Graphics (generateVideo, stateToImage) {--- Game settings ---} -- frames per second fps :: Int fps = 10 lastFrameDuration :: Int lastFrameDuration = 4 * fps -- 4 seconds -- board dimensions board :: Board board = (8, 8) -- initial game state (a random number is needed to generate food at a random position) genState :: Int -> State genState rand = State (Snake snakeParts False) (generateFood board snakeParts rand) Right where snakeParts = fromList [(5, 3), (4, 3), (3, 3)] -- initial snake initialSnakeLength :: Int initialSnakeLength = 3 -- used strategy strategyParams :: StrategyParams (Seq Position) strategyParams = hamiltonStrategyParams defaultSeed :: Int defaultSeed = -12 {--- Main program ---} main :: IO () main = do printLicenseInfo args <- getArgs randomSeed <- randomIO case args of [path] -> run path defaultSeed ["random", path] -> run path randomSeed [path, "random"] -> run path randomSeed _ -> do putStrLn "Usage: stack run [random] OUTPUT_FILE\n" putStrLn "Available options:" putStrLn " random\tUse a random seed instead of the default one." -- Simulates a Snake game, generates a video and saves it under the specified path. run :: String -> Int -> IO () run path seed = do putStrLn ("Using seed " ++ show seed ++ ".") putStrLn "Simulating game..." let states = simulateGame board (genState seed) strategyParams seed frames = length states images <- mapM (\(n, state) -> do putStrLn ("Generating video frame " ++ show n ++ "/" ++ show frames ++ "...") stateToImage board state initialSnakeLength) (zip [1..] states) putStrLn "Saving video..." generateVideo (images ++ replicate (lastFrameDuration - 1) (last images)) fps path putStrLn ("\nThe video has been saved to " ++ path ++ "!") printLicenseInfo :: IO () printLicenseInfo = do putStrLn "Copyright (C) 2020 Max Schröder " putStrLn "This is free software, and you are welcome to redistribute it under certain conditions." putStrLn "The exact distribution terms are described in the LICENSE file." putStrLn "This program comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law.\n\n"