Code: Select all
! Programme that calculates the probabilities of reach certain scores when given some input data.
program Trinomial_distribution_probabilities
implicit none
integer, parameter :: dbl = selected_real_kind(15,307)
character(len=*), parameter :: F0 = '(A,I4,A)'
character(len=*), parameter :: F1 = '(A,F7.4,A)'
character(len=*), parameter :: F2 = '(A,F6.1,A,I4)'
character(len=*), parameter :: F3 = '(A,I4,A,I4,A,I4)'
character(len=*), parameter :: F4 = '(A,F6.1,A)'
character(len=*), parameter :: F5 = '(I4,A,F7.4,A)'
character(len=*), parameter :: F6 = '(F8.4,A)'
character(len=*), parameter :: F7 = '(F6.1,A,F7.4)'
integer :: games, i, j, k, i_max
integer :: n = 1000 ! Maximum number of games supported.
integer, allocatable :: wins(:,:), draws(:,:), loses(:,:), relative_frequency(:)
real(dbl), allocatable :: points(:), P(:,:), sum_P(:)
real(dbl), allocatable :: fact(:)
real(dbl) :: f_winsij, f_drawsij, f_losesij
real(dbl) :: delta, x, D, D_max, W_minus_L, W, L, overall_1, overall_2
real(dbl) :: f_games ! f_* = factorials.
real(dbl) :: max_frequency, prob_player_1_wins_the_match, prob_of_a_tied_match, prob_player_2_wins_the_match
real(dbl) :: half_time, time_of_calculations, elapsed_time
real :: time0, time
write(*,*)
write(*,'(A)') 'Probabilities_in_a_trinomial_distribution, ? 2013.'
write(*,*)
write(*,'(A)') '--------------------------------------------------------------------'
write(*,'(A)') 'Probabilities of all possible scores in a match between two engines.'
write(*,'(A)') '--------------------------------------------------------------------'
write(*,*)
write(*,F0) 'Write down the number of games of the match (minimum 2):'
write(*,*)
read(*,*) games
write(*,*)
if (games < 2) then
write(*,'(A)') 'The number of games must be greater than 1.'
write(*,*)
write(*,'(A)') 'Please close and try again. Press Enter to exit.'
read(*,'()')
stop
end if
n = games
allocate(wins(0:2*n,0:2*n))
allocate(draws(0:2*n,0:2*n))
allocate(loses(0:2*n,0:2*n))
allocate(relative_frequency(0:2*n))
allocate(points(0:2*n))
allocate(P(0:2*n,0:n))
allocate(sum_P(0:2*n))
allocate(fact(0:n))
fact(0) = 1.
fact(1) = 1.
do k=2, n
fact(k) = k*fact(k-1)
end do
write(*,'(A)') 'Write down the engines rating difference (between -800 Elo and 800 Elo).'
write(*,'(A)') 'Elo(first player) - Elo(second player):'
write(*,*)
read(*,*) delta
write(*,*)
if (abs(delta) > 8d2) then
write(*,'(A)') 'The engines rating difference must be between -800 Elo and 800 Elo.'
write(*,*)
write(*,'(A)') 'Please close and try again. Press Enter to exit.'
read(*,'()')
stop
end if
x = 1d1**(2.5d-3*delta) ! x = 10^(delta/400)
W_minus_L = (x - 1d0)/(x + 1d0) ! delta = 400*log{[1 + (W - L)]/[1 - (W - L)]}
D_max = 1d0 - abs(W_minus_L) - 1d-6 ! Supposing (W = W_max, L = 0) or (W = 0, L = L_max.); -1d-6 avoids D = 1 when x = 1.
write(*,F1) 'Write down the probability of a draw (%) between 0.0001 % and ', 1d-4*int(1d6*D_max), ' %'
! Using int() avoid cases where, for example:
! D_max = 84.21776...%, cmd prints 84.2178% (if nint() is used), the user writes 84.2178% and of course 84.2178 > 84.21776...
write(*,*)
read(*,*) D
write(*,*)
if ((D < 1d-4) .or. (D > 1d-4*int(1d6*D_max))) then
write(*,'(A)') 'Incorrect probability of a draw.'
write(*,*)
write(*,'(A)') 'Please close and try again. Press Enter to exit.'
read(*,'()')
stop
end if
D = 1d-2*D ! D = probability of a draw.
write(*,'(A)') 'Calculating, please wait.'
write(*,*)
call cpu_time(time0)
! W + D + L = 1 by definition; 1 - D = W + L.
W = 5d-1*(1d0 - D + W_minus_L) ! W = probability of a win.
L = 5d-1*(1d0 - D - W_minus_L) ! L = probability of a lose.
i_max = games + games ! i_max = 2*(games - 0)
wins(0,0) = games
draws(0,0) = 0
loses(0,0) = 0
points(0) = games
P(0,draws(0,0)) = W**wins(0,0) ! i = 0; (i,j) = (0,0).
sum_P(0) = P(0,draws(0,0))
if (wins(0,0) >= 2) f_games = fact(wins(0, 0))
do i = 1, i_max/2
points(i) = games - 5d-1*i ! Continue at points = games - 0.5, then decrease by 0.5 points each time.
sum_P(i) = 0d0 ! Initialization of the value.
do j = 0, int(i/2)
wins(i,j) = games - (i - j) ! It goes from the minimum number of wins (games - i) up to the maximum number of wins.
draws(i,j) = i - j - j ! draws(i,j) = games - [wins(i,j) + loses(i,j)] = games - {[(games - (i - j)] + j} = i - 2*j.
loses(i,j) = j ! It goes from the minimum number of loses (0) up to the maximum number of loses.
! wins(i,j) - loses(i,j) = games - i = constant for each i (it does not depend on j).
! Start of the calculation of factorials:
f_winsij = fact(wins(i,j))
f_drawsij = fact(draws(i,j))
f_losesij = fact(loses(i,j))
! Finish of the calculation of factorials.
P(i,draws(i,j)) = (f_games/(f_winsij*f_drawsij*f_losesij))*(W**wins(i,j))*(D**draws(i,j))*(L**loses(i,j))
! P(i,draws(i,j)): probability of points = points(i) with draws = draws(i,j).
sum_P(i) = sum_P(i) + P(i,draws(i,j))
end do
end do
call cpu_time(time)
half_time = time - time0
write(*,'(A,F6.2,A)') '50% of the calculations are done; approximated elapsed time: ', 1d-2*nint(1d2*half_time), ' seconds.' ! Rounded up to 0.01 seconds.
write(*,*)
do i = i_max/2+1, i_max-1
points(i) = games - 5d-1*i
sum_P(i) = 0d0 ! Initialization of the value.
do j = i-1, i-(1+int(0.5*(i_max-i))), -1
! Taking advantage of simmetry:
wins(i,j) = loses(i_max-i,i-j-1)
draws(i,j) = draws(i_max-i,i-j-1)
loses(i,j) = wins(i_max-i,i-j-1)
! Start of the calculation of factorials:
f_winsij = fact(wins(i, j))
f_drawsij = fact(draws(i, j))
f_losesij = fact(loses(i, j))
! Finish of the calculation of factorials.
P(i,draws(i,j)) = (f_games/(f_winsij*f_drawsij*f_losesij))*(W**wins(i,j))*(D**draws(i,j))*(L**loses(i,j))
sum_P(i) = sum_P(i) + P(i,draws(i,j))
end do
end do
wins (i_max,i_max) = 0
draws(i_max,i_max) = 0
loses(i_max,i_max) = games ! Finish at points = 0.
points(i_max) = 0d0
P(i_max,draws(i_max,i_max)) = L**loses(i_max,i_max)
sum_P(i_max) = P(i_max,draws(i_max,i_max))
prob_player_1_wins_the_match = sum(sum_P(1:i_max/2 - 1))
prob_of_a_tied_match = sum_P(i_max/2)
prob_player_2_wins_the_match = sum(sum_P(i_max/2 + 1:i_max))
overall_1 = prob_player_1_wins_the_match + 5d-1*prob_of_a_tied_match
overall_2 = 1d0 - overall_1
max_frequency = maxval(sum_P) ! The mode of the trinomial distribution.
do i = 0, i_max
relative_frequency(i) = nint(8d1*sum_P(i)/max_frequency)
! It pretends an approximated graphical representation: the mode is rescaled to 80 hyphens and the whole distribution is resized according to that.
end do
call cpu_time(time)
time_of_calculations = time - time0
write(*,'(A)') 'End of the calculations.'
write(*,'(A,F6.2,A)') 'Approximated time spent in calculations: ', 1d-2*nint(1d2*time_of_calculations), ' seconds.' ! Rounded up to 0.01 seconds.
write(*,*)
write(*,'(A)') 'The results will be saved into two different Notepads, at the same path of this programme.'
write(*,*)
open(unit=11,file='Probabilities.txt', status='unknown', action='write')
write(11,F0) 'Probabilities for a match of ', games, ' games (rounded up to 0.0001 %):'
write(11,'(A)')
write(11,'(A,F7.2,A)') 'Rating difference (rounded up to 0.01 Elo): ', 1d-2*nint(1d2*delta), ' Elo.'
write(11,'(A)')
write(11,F1) 'Probability of a win = W ~ ', 1d-4*nint(1d6*W), ' %'
write(11,F1) 'Probability of a draw = D ~ ', 1d-4*nint(1d6*D), ' %'
write(11,F1) 'Probability of a lose = L ~ ', 1d-4*nint(1d6*L), ' %'
write(11,'(A)')
write(11,'(A)') '======================================================='
write(11,'(A)')
write(11,F2) 'Points: ', points(0), '/', games
write(11,'(A)')
write(11,F3) '+', wins(0,0), ' =', draws(0,0), ' -', loses(0,0)
write(11,F1) 'P ~ ', 1d-4*nint(1d6*P(0,draws(0,0))),' %'
write(11,'(A)')
write(11,F4,advance='no') 'Probability of win ', points(0), ' points out of '
write(11,F5) games, ': ', 1d-4*nint(1d6*sum_P(0)), ' %'
write(11,'(A)')
write(11,'(A)') '-------------------------------------------------------'
write(11,'(A)')
do i = 1, i_max/2
write(11,F2) 'Points: ', points(i), '/', games
write(11,'(A)')
do j = 0, int(i/2)
write(11,F3) '+', wins(i,j), ' =', draws(i,j), ' -', loses(i,j)
write(11,F1) 'P ~ ', 1d-4*nint(1d6*P(i,draws(i,j))),' %'
write(11,'(A)')
end do
write(11,F4,advance='no') 'Probability of win ', points(i), ' points out of '
write(11,F5) games, ': ', 1d-4*nint(1d6*sum_P(i)), ' %'
write(11,'(A)')
write(11,'(A)') '-------------------------------------------------------'
write(11,'(A)')
end do
do i = i_max/2+1, i_max-1
write(11,F2) 'Points: ', points(i), '/', games
write(11,'(A)')
do j = i-1, i-(1+int(0.5*(i_max-i))), -1
write(11,F3) '+', wins(i,j), ' =', draws(i,j), ' -', loses(i,j)
write(11,F1) 'P ~ ', 1d-4*nint(1d6*P(i,draws(i,j))),' %'
write(11,'(A)')
end do
write(11,F4,advance='no') 'Probability of win ', points(i), ' points out of '
write(11,F5) games, ': ', 1d-4*nint(1d6*sum_P(i)), ' %'
write(11,'(A)')
write(11,'(A)') '-------------------------------------------------------'
write(11,'(A)')
end do
write(11,F2) 'Points: ', points(i_max), '/', games
write(11,'(A)')
write(11,F3) '+', wins(i_max,i_max), ' =', draws(i_max,i_max), ' -', loses(i_max,i_max)
write(11,F1) 'P ~ ', 1d-4*nint(1d6*P(i_max,draws(i_max,i_max))),' %'
write(11,'(A)')
write(11,F4,advance='no') 'Probability of win ', points(i_max), ' points out of '
write(11,F5) games, ': ', 1d-4*nint(1d6*sum_P(i_max)), ' %'
write(11,'(A)')
write(11,'(A)') '=============================================================='
write(11,'(A)')
write(11,'(A)') ' SUMMARY:'
write(11,'(A)')
write(11,'(A)',advance='no') ' Probability that the first player wins the match ~ '
write(11,F6) 1d-4*nint(1d6*prob_player_1_wins_the_match), ' %'
write(11,'(A)',advance='no') ' Probability of a tied match ~ '
write(11,F6) 1d-4*nint(1d6*prob_of_a_tied_match), ' %'
write(11,'(A)',advance='no') 'Probability that the second player wins the match ~ '
write(11,F6) 1d-4*nint(1d6*prob_player_2_wins_the_match), ' %'
write(11,'(A)')
write(11,'(A)') '--------------------------------------------------------------'
write(11,'(A)')
write(11,'(A,F8.4,A)') ' Prob.(first player wins) + 0.5*Prob.(tied match) ~ ', 1d-4*nint(1d6*overall_1), ' %'
write(11,'(A,F8.4,A)',advance='no') 'Prob.(second player wins) + 0.5*Prob.(tied match) ~ ', 1d-4*nint(1d6*overall_2), ' %'
close(11)
open(unit=10,file='Summary_of_probabilities.txt', status='unknown', action='write')
write(10,F0) 'Probabilities for a match of ', games, ' games (rounded up to 0.0001 %):'
write(10,'(A)')
write(10,'(A,F7.2,A)') 'Rating difference (rounded up to 0.01 Elo): ', 1d-2*nint(1d2*delta), ' Elo.'
write(10,'(A)')
write(10,F1) 'Probability of a win = W ~ ', 1d-4*nint(1d6*W), ' %'
write(10,F1) 'Probability of a draw = D ~ ', 1d-4*nint(1d6*D), ' %'
write(10,F1) 'Probability of a lose = L ~ ', 1d-4*nint(1d6*L), ' %'
write(10,'(A)')
write(10,'(A)') '=============================================================================================='
write(10,'(A)')
write(10,'(A)') 'Points: Probabilities (%): Approximated graphical representation:'
write(10,'(A)')
do i = i_max, 0, -1
write(10,F7,advance='no') points(i), ' ', 1d-4*nint(1d6*sum_P(i))
if (relative_frequency(i) == 0) then
write(10,'(A)')
else if (relative_frequency(i) == 1) then
write(10,'(A)') ' -'
else if (relative_frequency(i) == 2) then
write(10,'(A)') ' --'
else if (relative_frequency(i) == 3) then
write(10,'(A)') ' ---'
else if (relative_frequency(i) == 4) then
write(10,'(A)') ' ----'
else if (relative_frequency(i) == 5) then
write(10,'(A)') ' -----'
else if (relative_frequency(i) == 6) then
write(10,'(A)') ' ------'
else if (relative_frequency(i) == 7) then
write(10,'(A)') ' -------'
else if (relative_frequency(i) == 8) then
write(10,'(A)') ' --------'
else if (relative_frequency(i) == 9) then
write(10,'(A)') ' ---------'
else if (relative_frequency(i) == 10) then
write(10,'(A)') ' ----------'
else if (relative_frequency(i) == 11) then
write(10,'(A)') ' -----------'
else if (relative_frequency(i) == 12) then
write(10,'(A)') ' ------------'
else if (relative_frequency(i) == 13) then
write(10,'(A)') ' -------------'
else if (relative_frequency(i) == 14) then
write(10,'(A)') ' --------------'
else if (relative_frequency(i) == 15) then
write(10,'(A)') ' ---------------'
else if (relative_frequency(i) == 16) then
write(10,'(A)') ' ----------------'
else if (relative_frequency(i) == 17) then
write(10,'(A)') ' -----------------'
else if (relative_frequency(i) == 18) then
write(10,'(A)') ' ------------------'
else if (relative_frequency(i) == 19) then
write(10,'(A)') ' -------------------'
else if (relative_frequency(i) == 20) then
write(10,'(A)') ' --------------------'
else if (relative_frequency(i) == 21) then
write(10,'(A)') ' ---------------------'
else if (relative_frequency(i) == 22) then
write(10,'(A)') ' ----------------------'
else if (relative_frequency(i) == 23) then
write(10,'(A)') ' -----------------------'
else if (relative_frequency(i) == 24) then
write(10,'(A)') ' ------------------------'
else if (relative_frequency(i) == 25) then
write(10,'(A)') ' -------------------------'
else if (relative_frequency(i) == 26) then
write(10,'(A)') ' --------------------------'
else if (relative_frequency(i) == 27) then
write(10,'(A)') ' ---------------------------'
else if (relative_frequency(i) == 28) then
write(10,'(A)') ' ----------------------------'
else if (relative_frequency(i) == 29) then
write(10,'(A)') ' -----------------------------'
else if (relative_frequency(i) == 30) then
write(10,'(A)') ' ------------------------------'
else if (relative_frequency(i) == 31) then
write(10,'(A)') ' -------------------------------'
else if (relative_frequency(i) == 32) then
write(10,'(A)') ' --------------------------------'
else if (relative_frequency(i) == 33) then
write(10,'(A)') ' ---------------------------------'
else if (relative_frequency(i) == 34) then
write(10,'(A)') ' ----------------------------------'
else if (relative_frequency(i) == 35) then
write(10,'(A)') ' -----------------------------------'
else if (relative_frequency(i) == 36) then
write(10,'(A)') ' ------------------------------------'
else if (relative_frequency(i) == 37) then
write(10,'(A)') ' -------------------------------------'
else if (relative_frequency(i) == 38) then
write(10,'(A)') ' --------------------------------------'
else if (relative_frequency(i) == 39) then
write(10,'(A)') ' ---------------------------------------'
else if (relative_frequency(i) == 40) then
write(10,'(A)') ' ----------------------------------------'
else if (relative_frequency(i) == 41) then
write(10,'(A)') ' -----------------------------------------'
else if (relative_frequency(i) == 42) then
write(10,'(A)') ' ------------------------------------------'
else if (relative_frequency(i) == 43) then
write(10,'(A)') ' -------------------------------------------'
else if (relative_frequency(i) == 44) then
write(10,'(A)') ' --------------------------------------------'
else if (relative_frequency(i) == 45) then
write(10,'(A)') ' ---------------------------------------------'
else if (relative_frequency(i) == 46) then
write(10,'(A)') ' ----------------------------------------------'
else if (relative_frequency(i) == 47) then
write(10,'(A)') ' -----------------------------------------------'
else if (relative_frequency(i) == 48) then
write(10,'(A)') ' ------------------------------------------------'
else if (relative_frequency(i) == 49) then
write(10,'(A)') ' -------------------------------------------------'
else if (relative_frequency(i) == 50) then
write(10,'(A)') ' --------------------------------------------------'
else if (relative_frequency(i) == 51) then
write(10,'(A)') ' ---------------------------------------------------'
else if (relative_frequency(i) == 52) then
write(10,'(A)') ' ----------------------------------------------------'
else if (relative_frequency(i) == 53) then
write(10,'(A)') ' -----------------------------------------------------'
else if (relative_frequency(i) == 54) then
write(10,'(A)') ' ------------------------------------------------------'
else if (relative_frequency(i) == 55) then
write(10,'(A)') ' -------------------------------------------------------'
else if (relative_frequency(i) == 56) then
write(10,'(A)') ' --------------------------------------------------------'
else if (relative_frequency(i) == 57) then
write(10,'(A)') ' ---------------------------------------------------------'
else if (relative_frequency(i) == 58) then
write(10,'(A)') ' ----------------------------------------------------------'
else if (relative_frequency(i) == 59) then
write(10,'(A)') ' -----------------------------------------------------------'
else if (relative_frequency(i) == 60) then
write(10,'(A)') ' ------------------------------------------------------------'
else if (relative_frequency(i) == 61) then
write(10,'(A)') ' -------------------------------------------------------------'
else if (relative_frequency(i) == 62) then
write(10,'(A)') ' --------------------------------------------------------------'
else if (relative_frequency(i) == 63) then
write(10,'(A)') ' ---------------------------------------------------------------'
else if (relative_frequency(i) == 64) then
write(10,'(A)') ' ----------------------------------------------------------------'
else if (relative_frequency(i) == 65) then
write(10,'(A)') ' -----------------------------------------------------------------'
else if (relative_frequency(i) == 66) then
write(10,'(A)') ' ------------------------------------------------------------------'
else if (relative_frequency(i) == 67) then
write(10,'(A)') ' -------------------------------------------------------------------'
else if (relative_frequency(i) == 68) then
write(10,'(A)') ' --------------------------------------------------------------------'
else if (relative_frequency(i) == 69) then
write(10,'(A)') ' ---------------------------------------------------------------------'
else if (relative_frequency(i) == 70) then
write(10,'(A)') ' ----------------------------------------------------------------------'
else if (relative_frequency(i) == 71) then
write(10,'(A)') ' -----------------------------------------------------------------------'
else if (relative_frequency(i) == 72) then
write(10,'(A)') ' ------------------------------------------------------------------------'
else if (relative_frequency(i) == 73) then
write(10,'(A)') ' -------------------------------------------------------------------------'
else if (relative_frequency(i) == 74) then
write(10,'(A)') ' --------------------------------------------------------------------------'
else if (relative_frequency(i) == 75) then
write(10,'(A)') ' ---------------------------------------------------------------------------'
else if (relative_frequency(i) == 76) then
write(10,'(A)') ' ----------------------------------------------------------------------------'
else if (relative_frequency(i) == 77) then
write(10,'(A)') ' -----------------------------------------------------------------------------'
else if (relative_frequency(i) == 78) then
write(10,'(A)') ' ------------------------------------------------------------------------------'
else if (relative_frequency(i) == 79) then
write(10,'(A)') ' -------------------------------------------------------------------------------'
else if (relative_frequency(i) == 80) then
write(10,'(A)') ' --------------------------------------------------------------------------------'
end if
end do
write(10,'(A)')
write(10,'(A)') '=============================================================='
write(10,'(A)')
write(10,'(A)') ' SUMMARY:'
write(10,'(A)')
write(10,'(A)',advance='no') ' Probability that the first player wins the match ~ '
write(10,F6) 1d-4*nint(1d6*prob_player_1_wins_the_match), ' %'
write(10,'(A)',advance='no') ' Probability of a tied match ~ '
write(10,F6) 1d-4*nint(1d6*prob_of_a_tied_match), ' %'
write(10,'(A)',advance='no') 'Probability that the second player wins the match ~ '
write(10,F6) 1d-4*nint(1d6*prob_player_2_wins_the_match), ' %'
write(10,'(A)')
write(10,'(A)') '--------------------------------------------------------------'
write(10,'(A)')
write(10,'(A,F8.4,A)') ' Prob.(first player wins) + 0.5*Prob.(tied match) ~ ', 1d-4*nint(1d6*overall_1), ' %'
write(10,'(A,F8.4,A)',advance='no') 'Prob.(second player wins) + 0.5*Prob.(tied match) ~ ', 1d-4*nint(1d6*overall_2), ' %'
close(10)
call cpu_time(time)
elapsed_time = time - time0
write(*,'(A)') 'The results have been successfully saved into two files:'
write(*,*)
write(*,'(A)') ' Probabilities.txt'
write(*,'(A)') ' Summary_of_probabilities.txt'
write(*,*)
write(*,'(A,F6.2,A)') 'Approximated total elapsed time: ', 1d-2*nint(1d2*elapsed_time), ' seconds.' ! Rounded up to 0.01 seconds.
write(*,*)
write(*,'(A)') 'Thanks for using Probabilities_in_a_trinomial_distribution. Press Enter to exit.'
read(*,'()')
end program Trinomial_distribution_probabilities
The main simplification I did is to replace
Code: Select all
if (condition) then
stuff
goto number
end if
more stuff
number
Code: Select all
if (condition) then
stuff
else
more stuff
end if
Code: Select all
more stuff