Почему переменная newP2Points вычисляется иначе, чем newP1Points? - PullRequest
0 голосов
/ 03 ноября 2019

Я пытаюсь понять идею этого кода. Кодекс разрабатывает модель тенниса для моделирования отдельных точек в качестве ралли.

Матч по теннису состоит из нескольких сетов, каждый из которых состоит из множества игр. Первый игрок, выигравший два сета, выигрывает матч. Первый игрок, выигравший шесть игр, выигрывает сет. Первый игрок, получивший четыре очка, выигрывает игру, если оба игрока не наберут по три очка. В этом случае первый игрок, опередивший своего соперника на два очка, выигрывает игру.

Я понимаю функции Фигаро, но некоторые строки кода сбивают с толку.

object TennisGame{
 def tennis( probP1ServeWin: Double, probP1Winner: Double, probP1Error: 
             Double,probP2ServeWin: Double, probP2Winner: Double, 
             probP2Error: Double): Element[Boolean] = {

  def rally(firstShot: Boolean, player1: Boolean): Element[Boolean] = {
     val pWinner = 
      if(firstShot && player1) probP1ServeWin //pWinner will be equal 
                                                //with probP1ServeWinif is 
                                                //the first shot for 
                                                //player1

      else if (firstShot && !player1) probP2ServeWin  
      else if (player1) probP1Winner 
      else probP2Winner
      val pError =if (player1) probP1Error else probP2Error
      val winner = Flip(pWinner)  //winner will be true with a 
                                   //probability equals with pWinner and 
                                  //false with a probability 1- pWinner

      val error = Flip(pError) 

         //With the probability = winner, Constant(player1) is chosen, 
        //producing  player1 with probability 1.0, while with probability
       //1 - winner, If(error, Constant(!player1), rally(false, !player1)) 
      //is chosen

  If(winner, Constant(player1), If(error, Constant(!player1),
  rally(false,!player1)))

    }


 def game(p1Serves: Boolean, p1Points: Element[Int], p2Points: 
          Element[Int]): Element[Boolean] = {

   val p1WinsPoint = rally(true, p1Serves)

    //Apply takes two arguments  p1WinsPoint and p1Points, the Apply’s 
   //function argument takes one Boolean and one integer named wins and 
   //points and calculate the score for player 1
   val newP1Points = Apply(p1WinsPoint, p1Points, (wins: Boolean, points: 
                           Int) => if(wins) points + 1 else points)
   val newP2Points = Apply(p1WinsPoint, p2Points, (wins: Boolean, points: 
                           Int) =>if(wins) points else points + 1)
   val p1WinsGame = Apply(newP1Points, newP2Points, (p1: Int, p2: Int) => 
                          p1 >= 4 && p1- p2 >=2)
   val p2WinsGame = Apply(newP2Points, newP1Points, (p2: Int, p1: Int) => 
                          p2 >= 4 && p2- p1 >=2)
   val gameOver = p1WinsGame || p2WinsGame

  If(gameOver, p1WinsGame, game(p1Serves, newP1Points, newP2Points))
 }

def play(p1Serves: Boolean, p1Sets: Element[Int], p2Sets: Element[Int], 
         p1Games: Element[Int], p2Games: Element[Int]):Element[Boolean] ={

 val p1WinsGame = game( p1Serves, Constant (0), Constant(0))
 val newP1Games = Apply(p1WinsGame, p1Games, p2Games, (wins: Boolean, 
                         p1:Int, p2: Int) =>                                
                         if(wins){
                                  if(p1 >= 5) 0 else p1 + 1 
                            }else
                            {
                                if(p2 >=5) 0 else p1
                            })
val newP2Games = Apply(p1WinsGame, p1Games, p2Games, (wins: Boolean, p1: 
                        Int, p2: Int) =>
                            if(wins){
                               if(p1 >= 5) 0 else p2
                            }else
                            {
                                if(p2 >=5) 0 else p2 + 1
                            })
val newP1Sets = Apply(p1WinsGame, p1Games, p1Sets, (wins: Boolean, games: 
                       Int, sets: Int) =>
                       if(wins && games == 5) sets + 1 else sets)

val newP2Sets = Apply(p1WinsGame, p2Games, p2Sets, (wins: Boolean, games: 
                      Int, sets: Int) =>
                     if(!wins && games == 5) sets + 1 else sets)

val matchOver = Apply(newP1Sets, newP2Sets, (p1: Int, p2: Int) => 
                     p1 >= 2 | p2 >= 2)
 If(matchOver, Apply(newP1Sets, (sets: Int) => sets >= 2), play(!p1Serves, 
    newP1Sets, newP2Sets,newP1Games, newP2Games))
   }   
   play(true, Constant(0), Constant(0), Constant(0), Constant(0)) 
 }

 def main(args: Array[String]){}
}
...