将 State monad 结果从程序中的一个步骤传递到另一个步骤 + 提前停止
Passing State monad result form one step to another in a program + stop early
我有这些步骤:
trait BlackjackSteps {
def gamerTakesTwoCards(gamerName:String): State[Deck, Gamer]
def dealerTakesTwoCards: State[Deck, Dealer]
def isBlackjack(gamer: Gamer, dealer: Dealer): Option[Player]
def gamerDrawsCards(gamer: Gamer): State[Deck, Gamer]
def dealerDrawsCards(dealer: Dealer, gamer: Gamer): State[Deck, Dealer]
def determineWinner(gamer: Gamer, dealer: Dealer): Player
def program(gamerName:String): State[Deck, Player] = for {
gamer <- gamerTakesTwoCards(gamerName)
dealer <- dealerTakesTwoCards
//winner = isBlackjack(gamer, dealer)
gamerFinal <- gamerDrawsCards(gamer)
dealerFinal <- dealerDrawsCards(dealer, gamerFinal)
winnerFinal = determineWinner(gamerFinal, dealerFinal)
} yield winnerFinal
}
两个问题:
我如何获得 gamerTakesTwoCards 生成的牌组并将其传递给 dealerTakesTwoCards?
isBlackjack 可能会导致赢家,在这种情况下我需要停止并且 return 赢家。我怎样才能改变上面的代码来做到这一点?
游戏:
- 玩家和荷官玩
- 他们都抽了两张牌
- 如果没有 21 名获胜者
- 玩家继续抽牌直到 17
- 不超过 21 分的最高玩家获胜!
完整代码在这里:https://bitbucket.org/jameskingconsulting/blackjack-scala/src/master/
编辑:
我已经对理解进行了去糖处理,只是弄清楚发生了什么:
def program(gamerName:String): State[Deck, Player] =
gamerTakesTwoCards(gamerName).flatMap( gamer =>
dealerTakesTwoCards.flatMap(dealer =>
isBlackjack(gamer, dealer).fold(
gamerDrawsCards(gamer).flatMap( gamerFinal =>
dealerDrawsCards(dealer, gamerFinal).map( dealerFinal =>
determineWinner(gamerFinal, dealerFinal)
)
)
)(State.pure[Deck, Player])
))
- 无事可做。这就是重点。
无论isBlackjack
return是None
或 Some
。无论哪种方式,您都必须 return 一个 State[Deck, Player]
。例如,您可以通过 Option
上的 fold
实现它,将 success-case 映射到 pure
:
def program(gamerName:String): State[Deck, Player] = for {
gamer <- gamerTakesTwoCards(gamerName)
dealer <- dealerTakesTwoCards
winner <- isBlackjack(gamer, dealer).fold(for {
gamerFinal <- gamerDrawsCards(gamer)
dealerFinal <- dealerDrawsCards(dealer, gamerFinal)
winnerFinal = determineWinner(gamerFinal, dealerFinal)
} yield winnerFinal)(State.pure[Deck, Player])
} yield winner
我有这些步骤:
trait BlackjackSteps {
def gamerTakesTwoCards(gamerName:String): State[Deck, Gamer]
def dealerTakesTwoCards: State[Deck, Dealer]
def isBlackjack(gamer: Gamer, dealer: Dealer): Option[Player]
def gamerDrawsCards(gamer: Gamer): State[Deck, Gamer]
def dealerDrawsCards(dealer: Dealer, gamer: Gamer): State[Deck, Dealer]
def determineWinner(gamer: Gamer, dealer: Dealer): Player
def program(gamerName:String): State[Deck, Player] = for {
gamer <- gamerTakesTwoCards(gamerName)
dealer <- dealerTakesTwoCards
//winner = isBlackjack(gamer, dealer)
gamerFinal <- gamerDrawsCards(gamer)
dealerFinal <- dealerDrawsCards(dealer, gamerFinal)
winnerFinal = determineWinner(gamerFinal, dealerFinal)
} yield winnerFinal
}
两个问题:
我如何获得 gamerTakesTwoCards 生成的牌组并将其传递给 dealerTakesTwoCards?
isBlackjack 可能会导致赢家,在这种情况下我需要停止并且 return 赢家。我怎样才能改变上面的代码来做到这一点?
游戏:
- 玩家和荷官玩
- 他们都抽了两张牌
- 如果没有 21 名获胜者
- 玩家继续抽牌直到 17
- 不超过 21 分的最高玩家获胜!
完整代码在这里:https://bitbucket.org/jameskingconsulting/blackjack-scala/src/master/
编辑:
我已经对理解进行了去糖处理,只是弄清楚发生了什么:
def program(gamerName:String): State[Deck, Player] =
gamerTakesTwoCards(gamerName).flatMap( gamer =>
dealerTakesTwoCards.flatMap(dealer =>
isBlackjack(gamer, dealer).fold(
gamerDrawsCards(gamer).flatMap( gamerFinal =>
dealerDrawsCards(dealer, gamerFinal).map( dealerFinal =>
determineWinner(gamerFinal, dealerFinal)
)
)
)(State.pure[Deck, Player])
))
- 无事可做。这就是重点。
无论
isBlackjack
return是None
或Some
。无论哪种方式,您都必须 return 一个State[Deck, Player]
。例如,您可以通过Option
上的fold
实现它,将 success-case 映射到pure
:def program(gamerName:String): State[Deck, Player] = for { gamer <- gamerTakesTwoCards(gamerName) dealer <- dealerTakesTwoCards winner <- isBlackjack(gamer, dealer).fold(for { gamerFinal <- gamerDrawsCards(gamer) dealerFinal <- dealerDrawsCards(dealer, gamerFinal) winnerFinal = determineWinner(gamerFinal, dealerFinal) } yield winnerFinal)(State.pure[Deck, Player]) } yield winner