Я пытаюсь понять идею этого кода. Кодекс разрабатывает модель тенниса для моделирования отдельных точек в качестве ралли.
Матч по теннису состоит из нескольких сетов, каждый из которых состоит из множества игр. Первый игрок, выигравший два сета, выигрывает матч. Первый игрок, выигравший шесть игр, выигрывает сет. Первый игрок, получивший четыре очка, выигрывает игру, если оба игрока не наберут по три очка. В этом случае первый игрок, опередивший своего соперника на два очка, выигрывает игру.
Я понимаю функции Фигаро, но некоторые строки кода сбивают с толку.
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]){}
}