forgivingStrategy :: [Char] -> [Char] -> Int -> [Char] forgivingStrategy opponentMoves generatedMoves n | n > 100 || length opponentMoves == 1 = generatedMoves | n == 0 = forgivingStrategy opponentMoves (generatedMoves ++ ['С']) (n + 1) | head opponentMoves == 'С' = forgivingStrategy (tail opponentMoves) (generatedMoves ++ ['С']) (n + 1) | otherwise = forgivingStrategy (tail opponentMoves) (generatedMoves ++ ['П']) (n + 1) indexOf :: (Eq t) => [t] -> t -> Int indexOf [] _ = -1 indexOf (x : xs) target | x == target = 0 | otherwise = 1 + indexOf xs target nashEquilibriumStrategy :: [Char] -> [Char] -> Int -> [Char] nashEquilibriumStrategy opponentMoves generatedMoves n = if n <= 100 && length opponentMoves > 0 then nashEquilibriumStrategy (tail opponentMoves) (generatedMoves ++ [nextStep]) (n + 1) else generatedMoves where cases = [['С', 'С'], ['С', 'П'], ['П', 'С'], ['П', 'П']] results = [[1, 1], [10, 0], [0, 10], [5, 5]] p_years = min (results !! 1 !! 1) (results !! 3 !! 1) s_years = min (results !! 0 !! 1) (results !! 2 !! 1) nextStep | p_years <= s_years = 'П' | otherwise = 'С' getScore :: [Char] -> [Char] -> Int -> Int -> (Int, Int) getScore moves1 moves2 score1 score2 = if length moves1 == 0 then (score1, score2) else getScore (tail moves1) (tail moves2) newScore1 newScore2 where cases = [['С', 'С'], ['С', 'П'], ['П', 'С'], ['П', 'П']] results = [[1, 1], [10, 0], [0, 10], [5, 5]] newScore1 = score1 + results !! indexOf cases [head moves1, head moves2] !! 0 newScore2 = score2 + results !! indexOf cases [head moves1, head moves2] !! 1 game :: [Char] -> ([Char] -> [Char] -> Int -> [Char]) -> [Char] game playerMoves gameStrategy | null playerMoves = [] | otherwise = gameStrategy playerMoves [] 0 playerMoves = ['С', 'П', 'С', 'С', 'П', 'П', 'С', 'С', 'П', 'П'] -- gameStrategy = forgivingStrategy gameStrategy = nashEquilibriumStrategy computerMoves = game playerMoves gameStrategy (score1, score2) = getScore playerMoves computerMoves 0 0 main :: IO () main = do putStrLn $ "Ходы компьютера: " ++ computerMoves putStrLn $ "Годы заключения: " ++ show score1 ++ " (игрок) - " ++ show score2 ++ " (компьютер)"