fork download
  1. #include <string>
  2. #include <iostream>
  3. #include <iomanip>
  4. #include <ctime>
  5. #include <cstdlib>
  6.  
  7. struct shooter
  8. {
  9. std::string name ;
  10. double accuracy ;
  11. bool alive ;
  12. };
  13.  
  14. void shoot(const shooter& source, shooter& target) ;
  15. void resurrect(shooter[], unsigned) ;
  16. unsigned duel(shooter[], unsigned) ;
  17.  
  18. int main()
  19. {
  20. std::srand(static_cast<unsigned>(std::time(0))) ;
  21. const unsigned trials = 100000 ;
  22.  
  23. // The order of shooters is important. It determines the sequence of attempts at shooting.
  24. // lowest index goes first.
  25. shooter shooters[] =
  26. {
  27. // {"Sue", 0.20, true},
  28. {"Aaron", 0.33, true},
  29. {"Bob", 0.50, true},
  30. {"Charlie", 1.0, true}
  31. };
  32.  
  33. const unsigned nShooters = sizeof(shooters) / sizeof(shooters[0]) ;
  34.  
  35. unsigned wins[nShooters] = {} ;
  36.  
  37. for ( unsigned i=0; i<trials; ++i )
  38. {
  39. resurrect(shooters, nShooters) ;
  40. ++wins[duel(shooters,nShooters)] ;
  41. }
  42.  
  43. for ( unsigned i=0; i<nShooters; ++i )
  44. {
  45. std::cout << std::left << std::setw(10) << shooters[i].name
  46. << std::right << std::setw(6) << wins[i] << " ("
  47. << std::fixed << std::setprecision(1) << std::setw(4)
  48. << (wins[i] / static_cast<double>(trials))*100 << "%)\n" ;
  49. }
  50. }
  51.  
  52. void shoot(const shooter& source, shooter& target)
  53. {
  54. if ( ((std::rand() % 100) * 0.01 ) < source.accuracy )
  55. target.alive = false ;
  56. }
  57.  
  58. void resurrect(shooter shooters[], unsigned size)
  59. {
  60. for ( unsigned i=0; i<size; ++i )
  61. shooters[i].alive = true ;
  62. }
  63.  
  64. bool onlyOneAlive(shooter shooters[], unsigned size)
  65. {
  66. unsigned alive = 0 ;
  67. for ( unsigned i=0; i<size; ++i )
  68. if ( shooters[i].alive )
  69. ++alive ;
  70.  
  71. return alive == 1 ;
  72. }
  73.  
  74. // PRE: size is greater than 0.
  75. // At least two of shooters[i].alive are true.
  76. unsigned findTarget(shooter shooters[], unsigned size, const shooter& source)
  77. {
  78. unsigned index = 0 ;
  79.  
  80. while ( !shooters[index].alive || shooters[index].name == source.name )
  81. ++index ;
  82.  
  83. unsigned target = index ;
  84.  
  85. while ( ++index < size )
  86. {
  87. if ( shooters[index].alive && shooters[index].name != source.name )
  88. if ( shooters[index].accuracy > shooters[target].accuracy )
  89. target = index ;
  90. }
  91.  
  92. return target ;
  93. }
  94.  
  95. // PRE: size is greater than 0.
  96. // Exactly one of shooters[i].alive is true.
  97. unsigned winner(shooter shooters[], unsigned size)
  98. {
  99. for ( unsigned i=0; i<size; ++i )
  100. if ( shooters[i].alive )
  101. return i ;
  102.  
  103. return size ; // to quell a compiler warning.
  104. }
  105.  
  106. // PRE: size is greater than 0.
  107. // At least one of shooters[i].alive is true.
  108. unsigned nextAlive(shooter shooters[], unsigned size, unsigned index)
  109. {
  110. do
  111. {
  112. index = (index+1) % size ;
  113. } while (!shooters[index].alive) ;
  114.  
  115. return index ;
  116. }
  117.  
  118. // PRE: size is greater than 0.
  119. // At least one of shooters[i].alive is true.
  120. unsigned duel(shooter shooters[], unsigned size)
  121. {
  122. unsigned turn = 0 ;
  123. while (!onlyOneAlive(shooters,size))
  124. {
  125. unsigned targetIndex = findTarget(shooters, size, shooters[turn]) ;
  126. shoot(shooters[turn], shooters[targetIndex]) ;
  127.  
  128. turn = nextAlive(shooters, size, turn) ;
  129. }
  130.  
  131. return winner(shooters, size) ;
  132. }
Success #stdin #stdout 0.04s 3032KB
stdin
Standard input is empty
stdout
Aaron      36605 (36.6%)
Bob        41617 (41.6%)
Charlie    21778 (21.8%)