program main c*********************************************************************72 c cc duel_simulation() simulates a duel. c c Discussion: c c Player 1 fires at player 2, and hits with a probability of P(1). c If Player 2 misses, then Player 2 fires at Player 1, hitting with c a probability of P(2). c c The duel continues with alternating shots until only one player c survives. c c The simulation is intended to estimate the probabilities that a c player will survive, and the number of turns required. c c The exact probability that player 1 will survive is c c P(1) / ( P(1) + P(2) - P(1) * P(2) ) c c Player 2's chance is c c P(2) * ( 1 - P(1) ) / ( P(1) + P(2) - P(1) * P(2) ) c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 17 September 2012 c c Author: c c John Burkardt c c Reference: c c Paul Nahin, c Duelling Idiots and Other Probability Puzzlers, c Princeton University Press, 2000, c ISBN13: 978-0691009797, c LC: QA273.N29. c c Martin Shubik, c "Does the Fittest Necessarily Survive?", c in Readings in Game Theory and Political Behavior, c edited by Martin Shubik, c Doubleday, 1954, c LC: H61.S53. c c Parameters: c c Input, double precision A_ACCURACY, B_ACCURACY, the probabilities that c players A and B will hit their opponent in a single shot. c c Input, integer DUEL_NUM, the number of duels to run. c c Output, double precision A_PROB, B_PROB, the estimated probablities that c players A and B will survive. c c Output, double precision TURN_AVERAGE, the average number of turns c required to complete the duel. c implicit none double precision a_accuracy double precision a_prob integer a_wins double precision b_accuracy double precision b_prob integer b_wins integer duel integer duel_num integer winner call timestamp ( ) write ( *, '(a)' ) '' write ( *, '(a)' ) 'duel_simulation():' write ( *, '(a)' ) ' FORTRAN77 version' write ( *, '(a)' ) ' Enter number of duels to run:' read ( *, * ) duel_num write ( *, '(a)' ) & ' Enter player A''s accuracy between 0.0 and 1.0:' read ( *, * ) a_accuracy write ( *, '(a)' ) & ' Enter player B''s accuracy between 0.0 and 1.0:' read ( *, * ) b_accuracy a_wins = 0 b_wins = 0 do duel = 1, duel_num call duel_result ( a_accuracy, b_accuracy, winner ) if ( winner .eq. 1 ) then a_wins = a_wins + 1 else b_wins = b_wins + 1 end if end do a_prob = dble ( a_wins ) / dble ( duel_num ) b_prob = dble ( b_wins ) / dble ( duel_num ) write ( *, '(a)' ) '' write ( *, '(a,g14.6)' ) & ' Player A wins with probability ', a_prob write ( *, '(a,g14.6)' ) & ' Player B wins with probability ', b_prob write ( *, '(a)' ) '' write ( *, '(a)' ) 'duel_simulation():' write ( *, '(a)' ) ' Normal end of execution.' write ( *, '(a)' ) '' call timestamp ( ) stop end subroutine duel_result ( a_accuracy, b_accuracy, winner ) c*********************************************************************72 c cc DUEL_RESULT returns the outcome of a single duel. c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 04 September 2012 c c Author: c c John Burkardt c c Reference: c c Martin Shubik, c “Does the Fittest Necessarily Survive?”, c in Readings in Game Theory and Political Behavior, c edited by Martin Shubik, c Doubleday, 1954, c LC: H61.S53. c c Parameters: c c Input, double precision A_ACCURACY, B_ACCURACY, the probabilities that c player A and B will hit their opponent in a single shot. c c Output, integer WINNER, the survivor of the duel. c implicit none double precision a_accuracy double precision b_accuracy double precision r integer winner 10 continue call random_number ( harvest = r ) if ( r .le. a_accuracy ) then winner = 1 go to 20 end if call random_number ( harvest = r ) if ( r .le. b_accuracy ) then winner = 2 go to 20 end if go to 10 20 continue return end subroutine timestamp ( ) c*********************************************************************72 c cc timestamp() prints the YMDHMS date as a timestamp. c c Licensing: c c This code is distributed under the MIT license. c c Modified: c c 12 June 2014 c c Author: c c John Burkardt c implicit none character * ( 8 ) ampm integer d character * ( 8 ) date integer h integer m integer mm character * ( 9 ) month(12) integer n integer s character * ( 10 ) time integer y save month data month / & 'January ', 'February ', 'March ', 'April ', & 'May ', 'June ', 'July ', 'August ', & 'September', 'October ', 'November ', 'December ' / call date_and_time ( date, time ) read ( date, '(i4,i2,i2)' ) y, m, d read ( time, '(i2,i2,i2,1x,i3)' ) h, n, s, mm if ( h .lt. 12 ) then ampm = 'AM' else if ( h .eq. 12 ) then if ( n .eq. 0 .and. s .eq. 0 ) then ampm = 'Noon' else ampm = 'PM' end if else h = h - 12 if ( h .lt. 12 ) then ampm = 'PM' else if ( h .eq. 12 ) then if ( n .eq. 0 .and. s .eq. 0 ) then ampm = 'Midnight' else ampm = 'AM' end if end if end if write ( *, & '(i2,1x,a,1x,i4,2x,i2,a1,i2.2,a1,i2.2,a1,i3.3,1x,a)' ) & d, trim ( month(m) ), y, h, ':', n, ':', s, '.', mm, & trim ( ampm ) return end