import Reversi import Data.List import Debug.Trace -- import System.Console.ANSI data Color = Red | Green | White deriving (Bounded, Enum, Show) data ColorIntensity = Dull | Vivid deriving (Enum, Show) data ConsoleLayer = Foreground | Background deriving (Enum, Show) data SGR = SetColor ConsoleLayer ColorIntensity Color setSGRCode _ = "" {- helper function: -} sameAs:: Eq a => [a] -> [a] -> Bool sameAs a b = if (length a) /= (length b) then False else (length a) == (length (a `intersect` b)) test name condition = if not condition then (setSGRCode [ SetColor Foreground Vivid Red ] ++ "Test " ++ name ++ ": failure!!!!! \n") else (setSGRCode [ SetColor Foreground Vivid Green ] ++ "Test " ++ name ++ ": OK \n") createGameFieldTests = let field = createGameField 10 8 [((5,5),Head), ((5,6),Tail), ((5,3),Head)] in [test "GameField get (5,5) == Head: " ((get (5,5) field) == Just Head), test "GameField get (4,5) == None: " ((get (4,5) field) == Nothing), test "GameField get (5,6) == Tail: " ((get (5,6) field) == Just Tail)] piecesMaintananceTest = let field' = createGameField 10 8 [((5,5),Head), ((5,6),Tail)] in let field = push (2,2) Head field' in test "piecesMaintananceTest" ((pieces field) `sameAs` [((5,5),Head), ((5,6),Tail), ((2,2),Head)]) getPossibleMovesTestSimple3x3 = let field = createGameField 3 3 [((0,0),Head), ((1,0),Tail)] in {- now the Head player can 'jump' over (1,0) Tail to (2,0) -} [test "getPossibleMovesTestSimple3x3" ((getPossibleMoves Head field) == [(2,0)])] getPossibleMovesTestWikiExample = let field = createGameField 4 4 [((1,1),Head), ((2,2),Head), ((2,1),Tail), ((1,2),Tail)] in let expected = [(1,0), (0,1), (3,2), (2,3)] in [test "getPossibleMovesTestWikiExample for Tail" ((getPossibleMoves Tail field) `sameAs` expected), test "getPossibleMovesTestWikiExample for Tail with Eval" (and [length == 1 | (start,pos,length) <- (getPossibleMovesWithEval Tail field)])] getPossibleMovesBug = let field = createGameField 5 5 [((1,1),Head), ((1,2),Head), ((1,3),Head), ((2,2),Head), ((2,3),Tail)] in let result = getPossibleMoves Tail field in let expected = [(2,1), (0,1), (0,3)] in test "getPossibleMovesBug" (result `sameAs` expected) getPossibleMovesLongLine = let field = createGameField 5 3 [((0,0),Head), ((1,0),Tail), ((2,0),Tail), ((3,0),Tail)] in let ((startX,startY),(x,y),length) = head $ getPossibleMovesWithEval Head field in test "getPossibleMovesLongLine" (x == 4 && y == 0 && length == 3 && startX == 0 && startY == 0) flipLineTest = let field = createGameField 10 10 [((5,5),Head), ((5,6),Tail), ((5,7),Tail)] in let flipped = last $ flipLine (5,5) (5,8) field in test "flipLineTest:" (((get (5,5) flipped) `isJustThis` Head) && ((get (5,6) flipped) `isJustThis` Head) && ((get (5,7) flipped) `isJustThis` Head) && ((get (5,8) flipped) == Nothing)) flipLinesTest = let field = createGameField 6 7 [((0,0),Head), ((1,0),Tail), ((3,0),Tail), ((4,0),Head)] in let moves = (getPossibleMovesWithEval Head field) in let flipped = head $ reverse $ flipLines (2,0) moves field in test "flipLinesTest:" (((get (1,0) flipped) `isJustThis` Head) && ((get (3,0) flipped) `isJustThis` Head)) minimaxCrashTest = let field = createGameField 10 10 [((3,3),Head), ((4,4),Head), ((4,3),Tail), ((3,4),Tail)] in let (result,score) = (minimax field Head 2) in test "minimaxCrashTest: " (result /= (-1,-1)) minimaxTest = let field = createGameField 8 5 ((zip ([(0,1),(1,2),(2,3),(3,3)]++[(x,1)|x<-[2..6]]) (repeat Head)) ++ [((1,3),Tail)]) in let (result,score) = (minimax field Tail 200) in trace (show (result,score)) $ test "minimaxSensibleDecision: " (result == (1,1)) minimaxSpeedTest = let field = createGameField 8 5 ((zip ([(0,1),(1,2),(2,3),(3,3)]++[(x,1)|x<-[2..6]]) (repeat Head)) ++ [((1,3),Tail)]) in let (result,score) = (minimax field Tail 600) in trace (show (result,score)) $ test "minimaxSpeedTest: " (result /= (-1,-1)) minimaxTest3Options = let field = createGameField 8 5 ((zip ([(0,1),(1,4),(1,2),(2,3),(3,3)]++[(x,1)|x<-[2..6]]) (repeat Head)) ++ [((1,3),Tail)]) in let (result,score) = (minimax field Tail 200) in trace (show (result,score)) $ test "minimaxTest3Options: " (result == (1,1)) runTests = let tests = [test "isJustThis test:" ((Just Tail) `isJustThis` Tail), test "switchPiece: Head to Tail" ((switchPiece Head) == Tail), test "switchPiece: Tail to Head" ((switchPiece Tail) == Head), getPossibleMovesLongLine, getPossibleMovesBug, flipLineTest, flipLinesTest, piecesMaintananceTest] ++ getPossibleMovesTestWikiExample ++ getPossibleMovesTestSimple3x3 ++ createGameFieldTests ++ [minimaxCrashTest, minimaxTest] in let text = foldl (\a b -> a ++ b) ("") tests in do putStr (text ++ setSGRCode [ SetColor Foreground Vivid White ])