From 85485774042806d7ab77b116bfd8ed8800b5f43a Mon Sep 17 00:00:00 2001 From: Arity-T Date: Sun, 10 Nov 2024 03:53:14 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=B8=D0=BB=D0=B5=D0=BC=D0=BC=D0=B0=20?= =?UTF-8?q?=D0=B2=20=D0=BE=D1=81=D0=BE=D0=B1=D0=B5=D0=BD=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D1=8F=D1=85=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab2/report/report.tex | 72 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/lab2/report/report.tex b/lab2/report/report.tex index 4a0ebf7..cd2caa4 100644 --- a/lab2/report/report.tex +++ b/lab2/report/report.tex @@ -341,7 +341,79 @@ xs <- barnsleyFern x' (n - 1) return (startPoint : xs) \end{lstlisting} + + + \subsection{Повторяющаяся дилемма заключённого} + \subsubsection{Равновесие Нэша} + + Функция \texttt{nashEquilibriumStrategy}, код которой представлен в листинге~\ref{lst:nashEquilibriumStrategy}, реализует равновесие Нэша. Функция рекурсивная, она принимает на вход список действий оппонента, список уже сгенерированных действий и число -- счётчик количества ходов. Функция завершается, когда достигается максимум ходов, либо когда заканчиваются ходы оппонента. Также она использует вспомогательную функцию \texttt{indexOf}. Она принимает на вход некоторый список и элемент этого списка, а возвращает индекс первого совпавшего с указанным элемента. Она возвращает список ходов игрока в соответствии со стратегией. + + \begin{lstlisting}[caption={Код функций, резализующих стратегию в соответствии с равновесием Нэша.}, label={lst:nashEquilibriumStrategy}] + 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 = [[0, 10], [5, 5]] + result = + [ min (results !! 0 !! 1) (results !! 1 !! 1), + max (results !! 0 !! 0) (results !! 1 !! 0) + ] + nextStep = cases !! indexOf results result !! 1 + \end{lstlisting} + + \subsubsection{Прощающая стратегия} + + Функция \texttt{forgivingStrategy}, код которой представлен в листинге~\ref{lst:forgivingStrategy}, реализует прощающую стратегию. Функция рекурсивная, она принимает на вход список действий оппонента, список уже сгенерированных действий и число -- счётчик количества ходов. Функция завершается, когда достигается максимум ходов, либо когда заканчиваются ходы оппонента. Она возвращает список ходов игрока в соответствии со стратегией. + + \begin{lstlisting}[caption={Код функции, реализующей прощающую стратегию.}, label={lst:forgivingStrategy}] + 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) + \end{lstlisting} + + \subsubsection{Подсчёт очков} + Функция \texttt{getScore}, код которой представлен в листинге~\ref{lst:getScore}, подсчитывает количество лет заключения для каждого игрока. Функция рекурсивная, она принимает на вход список действий первого игрока, список действий второго игрока, и два числа -- количество лет заключения для перового и второго игроков. Функция возвращает пару из двух чисел -- количества лет заключения для игроков. + + \begin{lstlisting}[caption={Код функции для подсчёта лет заключения.}, label={lst:getScore}] + 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 + \end{lstlisting} + + + \subsubsection{Организация игры} + Функция \texttt{game}, код которой представлен в листинге~\ref{lst:game}, запускает игру. Она принимает на вход список действий первого игрока и функцию, реализующую стратегию игры. Функция возвращает список ответных ходов, выбранных в соответствии с указанной стратегией. + + \begin{lstlisting}[caption={Код функции для подсчёта лет заключения.}, label={lst:game}] + game :: [Char] -> ([Char] -> [Char] -> Int -> [Char]) -> [Char] + game playerMoves gameStrategy + | null playerMoves = [] + | otherwise = gameStrategy playerMoves [] 0 + \end{lstlisting} + \newpage \section {Результаты работы программы}