Передача результата монады State из одного шага в другой в программе + ранняя остановка - PullRequest
3 голосов
/ 12 июня 2019

У меня есть следующие шаги:

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, и передать ее дилеру TakesTwoCards?

  • isBlackjack может привести к победителю, и в этом случае мне нужно остановиться и вернуть победителя.Как я могу изменить приведенный выше код, чтобы сделать это?

Игра:

  • геймер и дилер играют
  • ониобе вытягивают две карты
  • , если нет 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])
        ))

1 Ответ

2 голосов
/ 12 июня 2019
  1. Ничего не поделаешь. Вот и весь смысл.
  2. Вы должны вернуть победителя в обоих случаях , независимо от того, возвращает ли isBlackjack None или Some. В любом случае, вы должны вернуть State[Deck, Player]. Например, вы можете достичь этого с помощью fold на Option, отображая прецедент с помощью 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
    
...