-- *************** Comments *****************
--Add game ending stuff = code done needs figuring out
--Create AI = very simple atm, would like best choice
--Fix annoying thing = tracked down ish, needs running through paper
--Check re console stuff
-- **************** Declaring stuff ******************
data Cell = B | W | X | O
deriving (Read, Show, Eq)
type Board = [[Cell]]
myBoard :: Board
myBoard = [
[O,O,O,O,O,O,O,O,O,O],
[O,X,X,X,X,X,X,X,X,O],
[O,X,X,X,X,X,X,X,X,O],
[O,X,X,X,X,X,X,X,X,O],
[O,X,X,X,B,W,X,X,X,O],
[O,X,X,X,W,B,X,X,X,O],
[O,X,X,X,X,X,X,X,X,O],
[O,X,X,X,X,X,X,X,X,O],
[O,X,X,X,X,X,X,X,X,O],
[O,O,O,O,O,O,O,O,O,O]
]
-- ***************** Basic Functions ********************
row y board = board !! (y)
get x y board = (row y board) !! (x)
getNextCoOrd c1 c2 = c2 + (c2 - c1)
getNextXY x1 y1 x2 y2 = [getNextCoOrd x1 x2] ++ [getNextCoOrd y1 y2]
getOppon player =
if player == B
then W
else B
-- **************** Board Output ******************
showBoard board = do
putStrLn (" 1 2 3 4 5 6 7 8")
putStrLn (" _ _ _ _ _ _ _ _")
putStrLn ("1 |" ++ returnRow 1 1 board ++ "|")
putStrLn ("2 |" ++ returnRow 1 2 board ++ "|")
putStrLn ("3 |" ++ returnRow 1 3 board ++ "|")
putStrLn ("4 |" ++ returnRow 1 4 board ++ "|")
putStrLn ("5 |" ++ returnRow 1 5 board ++ "|")
putStrLn ("6 |" ++ returnRow 1 6 board ++ "|")
putStrLn ("7 |" ++ returnRow 1 7 board ++ "|")
putStrLn ("8 |" ++ returnRow 1 8 board ++ "|")
returnRow x y board =
if x /= 8
then (getBlank x y board) ++ "|" ++ returnRow (x+1) y board
else (getBlank x y board)
getBlank x y board =
if (get x y board) == X
then "_"
else (show (get x y board))
-- ***************** Get Scores *************
showStatus board = do
putStrLn ("Board:")
putStrLn ("")
showBoard board
putStrLn ("Black score: " ++ show (getBoardScore B 0 1 1 board))
putStrLn ("White score: " ++ show (getBoardScore W 0 1 1 board))
putStrLn ("")
getRowScore player score x y board =
if x /= 9
then if (get x y board) == player
then getRowScore player (score+1) (x+1) y board
else getRowScore player score (x+1) y board
else score
getBoardScore player score x y board =
if y /= 9
then (getBoardScore player score x (y+1) board) + (getRowScore player score x y board)
else getRowScore player score x y board
-- *************** Game Input/AI Logic ********************
main = do
putStrLn ("Welcome to Reversi!")
putStrLn ("")
humanCompTurn myBoard
humanHumanTurn player board = do
showStatus board
putStrLn ("Player " ++ show (player) ++ " turn:")
putStrLn ("Please enter x co-ordinate")
xc <- getLine
putStrLn ("Please enter y co-ordinate")
yc <- getLine
humanHumanTurn (getOppon player) (makeMove (read xc) (read yc) player board)
humanCompTurn i board = do
showStatus board
if i /= 30
then putStrLn ("Player turn:")
putStrLn ("Please enter x co-ordinate")
xc <- getLine
putStrLn ("Please enter y co-ordinate")
yc <- getLine
computerTurn i (makeMove (read xc) (read yc) B board)
else putStrLn ("Game Over!")
if (getBoardScore B 0 1 1 board) > (getBoardScore W 0 1 1 board)
then putStrLn ("Black wins!")
else if (getBoardScore W 0 1 1 board) > (getBoardScore B 0 1 1 board)
then putStrLn ("White wins!")
else putStrLn ("It's a draw!")
computerTurn i board = do
showStatus board
putStrLn ("Computer turn...")
humanCompTurn (i+1) (makeMove (head (head (checkGoodCellsBoard 1 1 board))) ((head (checkGoodCellsBoard 1 1 board)) !! 1) W board)
checkGoodCellsRow x y board =
if x /= 9
then if (checkPosition x y B W board)
then [[x,y]] ++ checkGoodCellsRow (x+1) y board
else checkGoodCellsRow (x+1) y board
else []
checkGoodCellsBoard x y board =
if y /= 8
then (checkGoodCellsRow x y board) ++ (checkGoodCellsBoard x (y+1) board)
else checkGoodCellsRow x y board
-- ***************** Checking if cell is valid *******************
checkSuccessMove x1 y1 x2 y2 oppon player board =
if (get x1 y1 board) == oppon
then if (get x2 y2 board) == player
then True
else checkSuccessMove x2 y2 (getNextCoOrd x1 x2) (getNextCoOrd y1 y2) oppon player board
else False
checkDirection x y xD yD oppon player board =
if checkSuccessMove xD yD (getNextCoOrd x xD) (getNextCoOrd y yD) oppon player board == True
then True
else False
checkNW x y oppon player board =
if (checkDirection x y (x-1) (y-1) oppon player board) == True
then True
else False
checkN x y oppon player board =
if (checkDirection x y x (y-1) oppon player board) == True
then True
else False
checkNE x y oppon player board =
if (checkDirection x y (x+1) (y-1) oppon player board) == True
then True
else False
checkW x y oppon player board =
if (checkDirection x y (x-1) y oppon player board) == True
then True
else False
checkE x y oppon player board =
if (checkDirection x y (x+1) y oppon player board) == True
then True
else False
checkSW x y oppon player board =
if (checkDirection x y (x-1) (y+1) oppon player board) == True
then True
else False
checkS x y oppon player board =
if (checkDirection x y x (y+1) oppon player board) == True
then True
else False
checkSE x y oppon player board =
if (checkDirection x y (x+1) (y+1) oppon player board) == True
then True
else False
checkPosition x y oppon player board =
if (get x y board) /= B
then if (get x y board) /= W
then if (checkNW x y oppon player board) == True
then True
else if (checkN x y oppon player board) == True
then True
else if (checkNE x y oppon player board) == True
then True
else if (checkW x y oppon player board) == True
then True
else if (checkE x y oppon player board) == True
then True
else if (checkSW x y oppon player board) == True
then True
else if (checkS x y oppon player board) == True
then True
else if (checkSE x y oppon player board) == True
then True
else False
else False
else False
-- ************ Making a move and changing cells ****************
changeRow x y v board = take (x) (row y board) ++ [v] ++ drop (x+1) (row y board)
changeCell x y v board = take (y) board ++ [(changeRow x y v board)] ++ drop (y+1) board
-- Fail is below ______________________________________________________________________
changeCellRec x1 y1 x2 y2 xD1 yD1 xD2 yD2 player board =
if checkDirection xD1 yD1 xD2 yD2 (getOppon player) player board
then if (get x2 y2 board) /= player
then take (y1) (changeCellRec x2 y2 (getNextCoOrd x1 x2) (getNextCoOrd y1 y2) xD1 yD1 xD2 yD2 player board) ++ [changeRow x1 y1 player board] ++ drop (y1+1) (changeCellRec x2 y2 (getNextCoOrd x1 x2) (getNextCoOrd y1 y2) xD1 yD1 xD2 yD2 player board)
else changeCell x1 y1 player board
else board
-- Fail is above """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
makeMove x y player board =
if checkPosition x y (getOppon player) player board == True
then changeCellRec x y (x-1) (y-1) x y (x-1) (y-1) player (changeCellRec x y x (y-1) x y x (y-1) player (changeCellRec x y (x+1) (y-1) x y (x+1) (y-1) player (changeCellRec x y (x-1) y x y (x-1) y player (changeCellRec x y (x+1) y x y (x+1) y player (changeCellRec x y (x-1) (y+1) x y (x-1) (y+1) player (changeCellRec x y x (y+1) x y x (y+1) player (changeCellRec x y (x+1) (y+1) x y (x+1) (y+1) player board)))))))
else board