-- Christos Scordellis (cs62) Informatics -- Functional Programming Coursework 2 - 17th March 2005 -- In making this submission I declare that my work contains no examples -- of misconduct, such as plagiarism, collusion or fabrication of results. module DominoesGame where import Char import Dominoes -- functions that store messages that will be displayed during the game startM, moveM, numPlayersM, starsM, nextM, chainM, handM, blankM, retryM, errorIn, lazyM :: String startM = starsM ++ "\n** Welcome to Huskel's Domino Game. **\n" ++ starsM ++ lazyM starsM = "**************************************" moveM = "\nPlease Enter move: " numPlayersM = "\nPlease enter number of Players: (2-7) \n" nextM = "\nEnter yout Move: \n" chainM = "\nChain is: \n" handM = "\nYour Hand is: \n" blankM = "\n\n\n" retryM = "\nPlease try again.\n>" errorIn = "\nInvalid Input. \nPlease Try Again with 'a-a' where a is number from 1 to 6 or press Enter to pass: \n" errorDom = "\n\nDomino not in hand or cannot match chain. Please Try again:\n" lazyM = "\n-If you feel lazy on entering Dominoes type '?'for autoplay." anyKeyM = "\nPress 'Enter' see your Hand:\n" numPlay = "\nPlease enter number of Human Players: (1-6) \n" randomM = "\nPlease insert a random number between 1 and 900 to shuffle:\n" -- this will select the highest in score available and valid domino to play. If non-exist it will pass. dominoesGame :: IO () dominoesGame = do msg (blankM ++ startM) numOfPlayer <- insertNum 2 7 numPlayersM rnd <- insertNum 1 900 randomM setupGame numOfPlayer rnd -- Setup the game given the number of player and random number setupGame :: Int -> Int -> IO() setupGame numOfPlayers rnd = do let (hands,currentP,currentD) = starter numOfPlayers rnd msg ("Player " ++ show currentP ++ " has played first domino " ++ show currentD ++ "\n") let update = firstMove currentP currentD (getHand currentP hands) chainD = fst update newHands = updateHands hands (snd update) nextP = getHand (turn currentP numOfPlayers) newHands currentPlayer = fst nextP gameLoop currentPlayer numOfPlayers newHands chainD 0 -- main loop of the game -- EndOfFlag game is increased by one each time a player passes, -- and set to 0 when a player makes a move with a domino -- If that number reaches the number of player then the game is over -- Also the hand of the current player is checked to discover whether a player has reached -- an empty hand. Then the numeric flag is set to a value higher to the value -- of the players (100) to force the end of game. gameLoop :: Int -> Int -> [Hand] -> Chain -> EndOfGameFlag -> IO() gameLoop player players hands chai eog | eog >= players = do msg (gameEnd hands) return () | otherwise = do msg (blankM ++ "\r\nPlayer " ++ show player ++ " playing:\n") let hnd = getHand player hands msg (chainM ++ show chai) anyKey msg (handM ++ show (snd (hnd))) msg nextM moveD <- getMove; if (validMove (moveD) hnd chai) then let (h,g) = playMove (moveD) hnd chai in (gameLoop (turn player players) players (updateHands hands h) g (findWinner h (passPlay moveD eog))) else ( do msg errorDom gameLoop player players hands chai eog) -- function that checks whether a players hand is empty findWinner :: Hand -> EndOfGameFlag -> EndOfGameFlag findWinner hd eog | (length (snd hd)) == 0 = 100 | otherwise = eog -- function to be used as Press any key to continue anyKey :: IO () anyKey = do msg anyKeyM c <- getChar return () -- insert num checks that a number input is within the parameter bounds -- it also displays a relevant parameter msg, -- it recurses until the input is correct insertNum :: Int -> Int -> String -> IO(Int) insertNum x y display = do msg display line <- getLine let numL = (read line :: Int) if ((numL < x) || (numL > y)) then (do reinsert <- insertNum x y display return (reinsert )) else return (numL) -- function that gives the number of the next player at each turn turn :: Int -> Int -> Int turn pr total | pr == total = 1 | otherwise = pr + 1