我正在尝试编写函数RPS。
该功能需要2个符号列表(' R' P或' S)并根据石头剪刀规则产生一个字符串,即"玩家1获胜" ,"球员2获胜"或" tie"。
该程序的示例执行是:
(RPS(列表' R' R' P)(列表' R' P' S) - >"播放器2胜" (RPS(列表' R' P)(列表' R' R) - >"玩家1获胜"
到目前为止,这是我的代码:
(define (RPS slst1 slst2)
(cond
[(and(empty? slst1)(empty? slst2)) "tie"]
[(empty? slst2) "player 1 wins"]
[(empty? slst1) "player 2 wins"]
[else
(cond
[(and(symbol=?(first slst1) 'R)
(symbol=?(first slst2) 'P))"player 1 wins"]
[(and(symbol=?(first slst1) 'R)
(symbol=?(first slst2) 'S))"player 2 wins"]
[(and(symbol=?(first slst1) 'p)
(symbol=?(first slst2) 'R))"player 2 wins"]
[(and(symbol=?(first slst1) 'P)
(symbol=?(first slst2) 'S))"player 2 wins"]
[(and(symbol=?(first slst1) 'S)
(symbol=?(first slst2) 'R))"player 2 wins"]
[(and(symbol=?(first slst1) 'S)
(symbol=?(first slst2) 'P))"player 1 wins"]
[(and(symbol=?(first slst1) 'S)
(symbol=?(first slst2) 'P))"player 1 wins"]
[(and(symbol=?(first slst1) 'S)
(symbol=?(first slst2) 'R))"player 2 wins"])]))
如何使这个函数递归,以便它移动到列表的其余元素?
答案 0 :(得分:1)
创建一个单独的函数,将一个符号与另一个符号进行比较(当2个符号相等时,不要忘记将这些情况考虑在内,此时你不会这样做)并在{{上调用该函数1}}符号列表。根据比较结果(平局,玩家1胜,玩家2获胜),您可以在原始输入的car
上递归调用RPS函数(如果出现平局)或返回在其他情况下获胜的球员。
确保从新功能中返回一些合理的结果,例如0 =平局,1 =球员1胜,2 =球员2胜。
此版本的RPS将持续到玩家赢得1轮或直到符号列表为空。但是,根据你的问题,这是不是很清楚你是否想要它。
您还可以通过2个输入列表cdr
新功能,这会生成map
或'(0 0 2)
等列表,向您显示每一轮的结果。根据这些结果,您可以获得整个游戏的胜利者。为了更加聪明,如果玩家1获胜则可以返回-1,如果玩家2获胜则返回+1,那么您可以将地图的结果加起来 - >如果它是正面的,则玩家2赢了,0 =平局,负面意味着玩家1赢了。
- >有关地图的更多信息:http://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Mapping-of-Lists.html
答案 1 :(得分:0)
你可以大大简化这个功能。坦白说,这是一些丑陋的代码。
首先(else (cond ...))
永远不是好形式。这意味着如果上述条件不成立,请检查这些其他条件。这是多余的
第二个cond
没有else
条件,并且您之前未在代码中进行测试以确保输入正确。为[(not (member? (first slst1) '(R P S))) "player 2 wins"]
添加slst2
和反向可以解决这个问题。至少(else (error ...))
将在意外输入时停止程序执行。
第三,你错过了一个非常大的条件,那就是条件条件[(symbol=? (first slst1) (first slst1)) "tie")]
或者如果那不是你想要的行为,那就看五个。
第四,你不必比较每个组合。如果没有平局或者球员1没有赢,你可以假设球员2获胜。或者您可以使用if
语句作为第二个cond
子句,如下所示:[(symbol=?(first slst1) 'R) (if (symbol=? (first slst2) 'P) "player 1 wins" "player 2 wins"]
或者您可以创建包含规则的数据结构。 (('R ('R 0) ('P -1) ('S 1)) ...)
并通过该查找结果。
第五,当一个列表为空而另一个列表不是'时,你会使用一些非常奇怪的逻辑。通常,您停止计算并忽略较长列表的最后一部分,或对该列表执行特殊操作。额外的输赢规则尚不清楚。产生胜利的第一个配对决定赢家,还是喜欢X中的最佳配对,其中X是(最短|最长)列表的长度?如果它基于分数,则需要将分数作为显式状态传递,并在其中一个或两个列表为空时进行正确比较。如果它是基于您的[(empty? slst1) "player 2 wins"]
建议的第一场胜利,那么我的四分中的领带捕手应该使用'cdr RPS
slst1 's of
slst2`
鉴于您想要的行为不清楚,这里有三个版本
首胜的版本
(define (RPS slst1 slst2)
(cond
[(and(empty? slst1)(empty? slst2)) "tie"]
[(empty? slst2) "player 1 wins"]
[(empty? slst1) "player 2 wins"]
[(not (member? (first slst2) '(R S P)))
(if (member? (first slst1) '(R S P))
"player 1 wins"
(RPS (rest slst1) (rest slst2)))] ;tie
[(not (member? (first slst1) '(R S P)))
"player 2 wins"]
[(symbol=? (first slst1) (first slst2))
(RPS (rest slst1) (rest slst2))]
[(symbol=? (first slst1) 'R)
(if (symbol=? (first slst2) 'S)
"player 1 wins"
"player 2 wins")]
[(symbol=?(first slst1) 'P)
(if (symbol=?(first slst2) 'R)
"player 1 wins"
"player 2 wins")]
[(symbol=?(first slst1) 'S)
(if (symbol=?(first slst2) 'P)
"player 1 wins"
"player 2 wins")]
[(else (error "RPS -- unexpected input " slst1 " " slst2))]))
包含数据结构规则的分数保留版
(define *RPS-Rules*
(list
(list 'R
(list 'R 0) ;;tie
(list 'P -1) ;;paper beats rock
(list 'S 1)) ;;rock beats siscors
(list 'P
(list 'R 1) ;;paper beats rock
(list 'P 0) ;;tie
(list 'S -1)) ;;siscors beat paper
(list 'S
(list 'R -1) ;;rock beats scissors
(list 'P 1) ;;paper beats rock
(list 'S 0)));;tie
(define (RPS-result throw1 throw2)
(first
(rest
(assoc throw2
(assoc throw1 *RPS-Rules*)))))
;;returns 1,0, or -1
(define (RPS slst1 slst2)
(RPS-helper slst1 slst2 0 )
(define (RPS-helper sl1 sl2 score)
(cond
[(and (empty? sl1)(empty? sl2))
(cond [(> score 0) "player 1 wins"]
[(< score 0) "player 2 wins"]
[else "tie"])]
[(empty? sl1) ;;if you want score based on shortest list
(RPS-helper sl1 '() (- score (length sl2)))]
[(empty? sl2) ;;dont do math on score here
(RPS-helper '() sl2 (+ score (length sl1)))]
[(not (member? (first sl1) '(R S P)))
(if (member? (first sl2) '(R S P))
(RPS-helper (rest sl1)
(rest sl2)
(- score 1))
(RPS-helper (rest sl1)
(rest sl2)
score))]
[(not (member? (first sl2) '(R S P)))
(RPS-helpter (rest sl1)
(rest sl2)
(+ score 1))]
[Else (RPS-helper (rest sl1)
(rest sl2)
(+ score
(RPS-result (first sl1)
(first sl2))))])
答案 2 :(得分:0)
Rock-paper-scissors-lizard-spock有点偏离主题,但我会在一个单独的答案中作为事后的想法发布,以显示第二个例子中更好的代码组织。
(define (RPS slst1 slst2)
(compare-game slst2 slst2 *RPS-Rules*))
(define (RPSLS slst1 slst2)
(compare-game slst2 slsts2 *RPSLK-Rules*))
(define (compare-game game slst1 slst2 rules)
(define (helper sl1 sl2 score)
(cond
[(and (empty? sl1)(empty? sl2))
(cond [(> score 0) "player 1 wins"]
[(< score 0) "player 2 wins"]
[else "tie"])]
[(empty? sl1)
(helper sl1 '() (- score (length sl2)))]
[(empty? sl2)
(helper '() sl2 (+ score (length sl1)))]
[else
(helper (rest sl1)
(rest sl2)
(+ score
(game-result (first sl1)
(first sl2)
rules)))]))
(helper slst1 slst2 0))
;if you want score of X to be
;based on length of shortest list
;dont do math on score after the
;[(empty?...] cond clauses
(define (game-result throw1 throw2 rules)
(let ((assoc1 (assoc throw1 rules))
(assoc2 (assoc throw2 rules))
(value (lambda (assoc-elem) (if assoc-pair
(first (rest (assoc-elem)))
#f))))
(cond [(not (and assoc1 assoc2))
(cond [(and (not assoc1) (not assoc2)) 0]
[assoc1 1]
[else -1])]
[(symbol=? throw1 throw2) 0]
[(value (assoc thow2 (rest assoc1)))]
[(let ((assoc2.1 (assoc throw1 (rest assoc2))))
(if assoc2.1 (- (value assoc2.1)) #f))]
[else (error "compare-game-result failed with args "
throw1
throw2
rules
"Rules incomplete?")])))
;returns 0, +-1, +- win value from rules, or error
;;playing fast and lose with anything not #f is true
;;and one-clause cond statements
;;;assumes ties are 0 points
;;;assumes default/forfiets are worth 1 point
;;;Does not assume all genuine wins are 1 point
(define *RPS-Rules*
(list
(list 'R
(list 'S 1)) ;;rock crushes scissors
(list 'P
(list 'R 1)) ;;paper covers rock
(list 'S
(list 'P 1)));;scissors cuts paper
(define *RPSLK-Rules*
(list
(list 'R
(list 'S 1) ;;rock crushes siscors
(list 'L 1)) ;;rock crushes lizard
(list 'P
(list 'R 1) ;;paper covers rock
(list 'K 1)) ;;paper disproves spock
(list 'S
(list 'P 1) ;;scissors cut paper
(list 'L 1)) ;;scissors decapitate lizard
(list 'L
(list 'K 1) ;;lizard poisons spock
(list 'P 1)) ;;lizard eats paper
(list 'K
(list 'S 1) ;;spock smashes scissors
(list 'R 1)));;spock vaporizes rock