# Game description (from Bell's Board & Table Games from Many Civilizations):
# "Any number of players may play and each throws the die in turn.
# The player with the lowest throw begins the game and the one with
# the highest plays last. The opening player throws the die as many
# times as he wishes, each time adding the number on the upper face
# of the die to his score. If he throws an ace, however, he loses all the
# points for that turn, and has to pass the die on to the next player.
# He may stop throwing at any time and hand the die on, when he
# keeps the points scored in that turn and adds it to his total score.
# The first player to reach 100 points wins. In succeeding games the
# advantage of an early throw is decided afresh by each player casting
# the die, lowest starting and the highest being last."
verbose = true
function pig(players)
n = length(players)
scores = zeros(Int, n)
while true
for i in 1:n
j = 1
score = 0
while true
if scores[i] + score >= 100 || !players[i](scores, i, j, score)
verbose && println("Player $i passes")
break
end
k = rand(1:6)
verbose && println("Player $i throws $k")
if k == 1
score = 0
verbose && println("=> Zero!")
break
end
score += k
j += 1
end
scores[i] += score
verbose && score != 0 && println(" Earned $score points => $(scores[i])")
if scores[i] >= 100
verbose && println("Final scores: $scores - Player $i wins")
return i
end
end
end
end
function test_players(players, iterations)
global verbose
old_verbose = verbose
verbose = false
scores = zeros(length(players))
for i in 1:iterations
j = pig(players)
scores[j] += 1
end
verbose = true
scores /= iterations
end
# player(scores, i, j, current)
# - scores : an array of the total scores of all players
# - i : the index of this player
# - j : the number of this throw (in the current turn)
# - current: the accumulated score in the current turn
fivetimes(scores, i, j, current) = j <= 5
sixtimes(scores, i, j, current) = j <= 6
twentier(scores, i, j, current) = current < 20
twentyfourer(scores, i, j, current) = current < 24
function fighter(scores, i, j, current)
for k in 1:length(scores)
k != i && scores[k] > 75 && return j < 10
end
current < 24
end