0 / 0 / 0
Регистрация: 16.09.2012
Сообщений: 8
|
|
1 | |
Упражнение про IO (игра в кости)01.08.2013, 22:34. Показов 2341. Ответов 6
Метки нет Все метки)
(
С помощью стандартных функций для генерации случайных чисел напишите программу, которая проводит состязание по игре в кости. Программа принимает аргументом суммарное число очков необходимых для победы. Двое игроков бросают по очереди кости побеждает тот, кто первым наберёт заданную сумму.
Сделайте так чтобы результаты выводились постепенно. С каждым нажатием на Enter вы подбрасываете кости (два шестигранных кубика). После каждого раунда программа выводит промежуточные результаты. (упражнение из этой книжки: http://anton-k.github.io/ru-ha... /home.html) Функция, которая делает этот цикл, принимает несколько обычных (без IO в типе) значений и возвращает IO () и должна вызывать себя, но я не понимаю, как применить функцию a -> b -> m c к значениям типов m a и m b. Есть ли аналог оператора =<< для функций нескольких аргументов? Или эта задача решается вообще по-другому?
0
|
|
01.08.2013, 22:34 | |
Ответы с готовыми решениями:
6
Игра в кости Игра в кости Игра кости Игра в кости |
![]() |
|||||||||||
01.08.2013, 23:01 | 2 | ||||||||||
0
|
![]() 5827 / 3478 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
|
02.08.2013, 01:53 | 3 |
Если применять функцию типа (a -> b -> c), а не (a -> b -> m c), то задачу можно решить с помощью той же функции liftM2 либо с помощью аппликативных функторов.
0
|
0 / 0 / 0
Регистрация: 16.09.2012
Сообщений: 8
|
||||||
02.08.2013, 02:26 [ТС] | 4 | |||||
Про приведённый код ghc говорит так: Couldn't match expected type `t -> a1' against inferred type `Int' In the second argument of `liftM2', namely `b' In the second argument of `liftM3', namely `(liftM2 (>=) b a)' In the second argument of `(>>)', namely `liftM3 ifthenelse (liftM2 (>=) b a) putStrLn "Fst w" (liftM3 ifthenelse (liftM2 (>=) c a) putStrLn "Snd w" (iter a (if d == Fst then (liftM2 (+)) b (randomInt 6) else b) (if d == Fst then c else (liftM2 (+)) c (randomInt 6)) (succ d)))' Добавлено через 2 минуты В этой функции прибавляется случайное число, поэтому её результат не может быть без IO в типе.
0
|
![]() 5827 / 3478 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
||||||
02.08.2013, 02:54 | 5 | |||||
Следует отделять чистые функции от функций с побочными эффектами, когда это возможно:
1
|
0 / 0 / 0
Регистрация: 16.09.2012
Сообщений: 8
|
|
03.08.2013, 18:25 [ТС] | 6 |
Я понимаю, что код должен быть чистым, когда это возможно, но в этой задаче программа должна выводить промежуточные результаты после нажатия клавиши. Можно сделать функцию game :: [Int] -> Int -> Player -> Player -> IO Player и выводить результаты прямо в ней? Или она должна возвращать список промежуточных результатов и быть чистой?
А вообще, всё получилось, спасибо. Только у меня функция game не чистая.
0
|
![]() 5827 / 3478 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
||||||
03.08.2013, 20:55 | 7 | |||||
Можно сделать и так, и так. Расскажу про второй вариант.
По сути, у нас в игре есть состояние — это номер хода, есть лог действий, есть неизменяемое состояние — это количество очков для победы. Под эти сущности подходят монады State, Writer и Reader, которые комбинируется с помощью Monad Transformers. Код достаточно сложен для первого понимания, бОльшую часть в нём занимают описания структур данных и вспомогательных функций, логика же игры осталась неизменной.
Грязную версию game с Monad Transformers можно получить из предыдущей, заменив WriterT [String] Identity на IO, а tell на putStrLn. Соответственно придется внести изменения в execGame.
0
|
03.08.2013, 20:55 | |
Помогаю со студенческими работами здесь
7
Игра в кости Игра в кости C++ Игра в кости
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |