我试图理解这段代码背后的想法。该代码详细说明了网球模型以将各个点建模为集会。
一场网球比赛由多组比赛组成,每组比赛由多场比赛组成。第一个赢得两盘的玩家赢得比赛。第一个赢得六场比赛的球员赢得一盘。第一个得到四分的玩家赢得比赛,除非两个玩家都得到三分。在这种情况下,第一个领先对手两分的玩家获胜。
我了解 Figaro 的功能,但有些代码行令人困惑。
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]){}
}