CC BY 4.0 (除特别声明或转载文章外)
如果这篇博客帮助到你,可以请我喝一杯咖啡~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
{-
设计一个交互程序,实现计算机(我)和用户(您)玩猜拳「石头、剪刀和布」。
例如,运行程序实现下来交互游戏:
*Main> play
请您出手 (R)石头, (S)剪刀, (P)布:p, 您出了布, 我出了石头
您赢了这手
我的得分: 0
您的得分: 1
请您出手 (R)石头, (S)剪刀, (P)布:s, 您出了剪刀, 我出了布
您赢了这手
我的得分: 0
您的得分: 2
请您出手 (R)石头, (S)剪刀, (P)布:r, 您出了石头, 我出了剪刀
您赢了这手
我的得分: 0
您的得分: 3
算您赢了这轮。
*Main> play
请您出手 (R)石头, (S)剪刀, (P)布:s, 您出了剪刀, 我出了布
您赢了这手
我的得分: 0
您的得分: 1
请您出手 (R)石头, (S)剪刀, (P)布:r, 您出了石头, 我出了石头
这一手平手
我的得分: 0
您的得分: 1
请您出手 (R)石头, (S)剪刀, (P)布:p, 您出了布, 我出了剪刀
我的得分: 1
您的得分: 1
请您出手 (R)石头, (S)剪刀, (P)布:p, 您出了布, 我出了剪刀
我的得分: 2
您的得分: 1
请您出手 (R)石头, (S)剪刀, (P)布:r, 您出了石头, 我出了剪刀
您赢了这手
我的得分: 2
您的得分: 2
请您出手 (R)石头, (S)剪刀, (P)布:s, 您出了剪刀, 我出了石头
我的得分: 3
您的得分: 2
哈哈,我赢了!
作业要求:
1. 模块命名为Game, 程序命名为play:: IO ();
2. 程序要仿照以上例子,输出交互过程和相关详细信息;
3. 使用下面的手势类型及instance定义,需要 import System.Random:
data Hand = Rock | Scissor | Paper deriving (Enum)
instance Random Hand where
random g = case randomR (0,2) g of
(r, g') -> (toEnum r, g')
randomR (a,b) g = case randomR (fromEnum a, fromEnum b) g of
(r, g') -> (toEnum r, g')
你也可以自己将Hand定义为Random的实例,以便能够使用随机手势,如 randomIO :: IO Hand
4. 用户(您)的输入用字母表示:r, s和p(不分大小写)分别表示用户选择的石头、剪刀和布
5. 建议适当定义一些辅助函数,不要把所有的命令都写在函数play中
6. 一点提示:猜数和猜单词中定义了函数:
guess :: Int (或者String) -> IO ()
其中输入参数是要猜的数或单词,在一系列猜测过程中需要这个信息,以便决定是停止还是继续猜(递归)。那么,猜拳时可能也需要类似的信息。
提交要求:
1. 提交模块Game;
2. 仿照以上例子,至少给出计算机(我)和用户(您)各赢一次的运行截图。
-}
module Game where
import System.Random
import Text.Printf
data Hand = Rock | Scissor | Paper deriving (Enum,Eq)
instance Random Hand where
random g = case randomR (0,2) g of
(r, g') -> (toEnum r, g')
randomR (a,b) g = case randomR (fromEnum a, fromEnum b) g of
(r, g') -> (toEnum r, g')
getHand::IO Hand
getHand=
do
s<-getLine
if (s=="r")||(s=="R")
then return Rock
else if (s=="s")||(s=="S")
then return Scissor
else return Paper
isWin::Hand->Hand->Bool
isWin p c=(p==Rock&&c==Scissor)||(p==Scissor&&c==Paper)||(p==Paper&&c==Rock)
toStr::Hand->String
toStr Rock="石头"
toStr Scissor="剪刀"
toStr Paper="布"
play::IO()
play=game 0 0
game::Int->Int->IO()
game a b=
do
putStrLn "请您出手 (R)石头, (S)剪刀, (P)布:"
ta<-getHand
tb<-randomIO::IO Hand
putStrLn(printf "您出了%s, 我出了%s" (toStr ta) (toStr tb))
if isWin ta tb
then do
putStrLn(printf "您赢了这手\n我的得分: %d\n您的得分: %d" b (a+1))
if a>1
then putStrLn "算您赢了这轮。"
else game (a+1) b
else if isWin tb ta
then do
putStrLn(printf "我赢了这手\n我的得分: %d\n您的得分: %d" (b+1) a)
if b>1
then putStrLn "哈哈,我赢了!"
else game a (b+1)
else do
putStrLn(printf "这一手平手\n我的得分: %d\n您的得分: %d" b a)
game a b
--main::IO()
--main=play