-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.hs
95 lines (86 loc) · 2.44 KB
/
main.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import Board
import Data.Maybe (fromJust, isNothing)
import GameState
import Helper (emptyGrids, getItem, listToString)
import MiniMax (generateOptimalMove)
import Move
import Text.Read (readMaybe)
import System.IO
import Control.Monad (when, unless)
main :: IO ()
main =
do
hSetBuffering stdout NoBuffering
hSetBuffering stdin NoBuffering
tictactoe
tictactoe :: IO ()
tictactoe =
do
let board = generateEmptyBoard
tictactoe' board
tictactoe' :: Grid -> IO ()
tictactoe' board =
do
x <- getInput board
let playerBoard = move board X x
let computerBoard = generateOptimalMove playerBoard
let gameState = checkGameState computerBoard
if fst gameState
then
do
let winner = (fromJust . snd) gameState
print computerBoard
if winner == X then putStrLn "IMPOSSIBLE! You won!"
else putStrLn "You lost, better luck next time!"
playAgain
return ()
else if (isNothing . snd) gameState
then
do
tictactoe' computerBoard
else
do
print computerBoard
putStrLn "Draw! Close game!"
playAgain
-- Input
getInput :: Grid -> IO Int
getInput board =
do
print board
let opts = listToString (emptyGrids board)
putStr("Choose your move from " ++ opts)
moveNumber <- validIntInput opts
if getItem board moveNumber == Empty
then return moveNumber
else
do
putStrLn "Space is already taken, choose again!"
getInput board
validIntInput :: String -> IO Int
validIntInput opts =
do
i <- intInput opts
if i < 9 && i >= 0 then return i
else intInput' opts
intInput :: String -> IO Int
intInput opts =
do
i <- getLine
let int = readMaybe i :: Maybe Int
maybe (intInput' opts) return int
intInput' :: String -> IO Int
intInput' opts =
do
putStr ("Invalid input! Please choose again from " ++ opts)
validIntInput opts
-- Play Again
playAgain :: IO ()
playAgain =
do
putStr"Would you like to play again (y/n)? "
choice <- getLine
case choice of
"y" -> tictactoe
"n" -> return ()
choice -> playAgain