有没有更好的方法在步骤之间传递状态。

例如,每次从牌组中取出一张牌时,我们都必须创建一个新牌组并将其归还,以便下一步可以使用它等

例如,有没有更好的方法来使用 Cats 来做到这一点?

trait BlackjackSteps {
    def gamerTakesTwoCards(deck: Deck): (Gamer, Deck)
    def dealerTakesTwoCards(deck: Deck): (Dealer, Deck)
    def isBlackjack(gamer: Gamer, dealer: Dealer): Option[Player]
    def gamerToDrawCards(gamer: Gamer, deck: Deck): Gamer
    def dealerToDrawCards(dealer: Dealer, deck: Deck, gamer: Gamer): Dealer
    def determineWinner(gamer: Gamer, dealer: Dealer): Player
  }

游戏:
  • 玩家和庄家玩
  • 他们都抽了两张牌
  • 如果没有 21 获胜者
  • 玩家继续抽牌直到 17
  • 最高得分不超过 21 分的玩家获胜

  • 编辑 - - -

    感谢您的回复。我只是想看看人们对这种方法的看法?

    这个怎么样?
    trait CardPicker {
        def pick(numberCards:Int): List[Card]
      }
    
      abstract class BlackjackSteps(cardPicker: CardPicker) {
        def gamerTakesTwoCards(gamer: Gamer): Gamer = {
          gamer.copy(cards = cardPicker.pick(2))
        }
        def dealerTakesTwoCards(dealer: Dealer): Dealer = {
          dealer.copy(cards = cardPicker.pick(2))
        }
        def isBlackjack(gamer: Gamer, dealer: Dealer): Option[Player] = {
         if(gamer.isBlackjack) Some(gamer)
         else if(dealer.isBlackjack) Some(dealer)
         else None
        }
        def gamerToDrawCards(gamer: Gamer): Gamer = {
          def drawCards(gamerPickingCards: Gamer): Gamer = gamer match {
            case _ if(gamerPickingCards.points < drawThreshold) =>
              drawCards(Gamer(gamerPickingCards.name, gamerPickingCards.cards ++ cardPicker.pick(1)))
            case _ => gamerPickingCards
          }
          drawCards(gamer)
        }
        def dealerToDrawCards(dealer: Dealer, gamer: Gamer): Dealer = {
          def drawCards(dealerPickingCards: Dealer): Dealer = dealer match {
            case _ if(dealerPickingCards.points < gamer.points) =>
              drawCards(Dealer(dealerPickingCards.name, dealerPickingCards.cards ++ cardPicker.pick(1)))
            case _ => dealerPickingCards
          }
          drawCards(dealer)
        }
        def determineWinner(gamer: Gamer, dealer: Dealer): Player = {
          if(gamer.points == dealer.points || gamer.points > dealer.points) gamer
          else dealer
        }
      }
    

    这里 CardPicker 有副作用,我们可以延迟到世界末日。

    这也太疯狂了吧?

    最佳答案

    这听起来像是 State monad 的一个很好的用例。以下内容可以帮助您入门:

    trait BlackjackSteps {
      def gamerTakesTwoCards: State[Deck, Gamer]
      def dealerTakesTwoCards: State[Deck, Dealer]
      def isBlackjack(gamer: Gamer, dealer: Dealer): State[Deck, Option[Player]]
      def gamerToDrawCards(gamer: Gamer): State[Deck, Gamer]
      def dealerToDrawCards(dealer: Dealer, gamer: Gamer): State[Deck, Dealer]
      def determineWinner(gamer: Gamer, dealer: Dealer): State[Deck, Player]
    }
    
    def gamerTakesTwoCards: State[Deck, Gamer] =
      State { oldDeck =>
        val gamer = f(oldDeck)
        val newDeck = g(oldDeck)
        (newDeck, gamer)
      }
    

    您可以查看官方 Cats 文档以了解更多信息:
    https://typelevel.org/cats/datatypes/state.html

    关于scala - 在 Scala 中的功能步骤之间传递状态,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56549522/

    10-12 02:51