pig_the_dice_game_player.sf 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #!/usr/bin/ruby
  2. var (games=100) = ARGV.map{.to_i}...;
  3. define DIE = 1..6;
  4. define GOAL = 100;
  5. class Player(score=0, ante=0, rolls=0, strategy={false}) {
  6. method turn {
  7. rolls = 0;
  8. ante = 0;
  9. loop {
  10. rolls++;
  11. given (var roll = DIE.rand) {
  12. when (1) {
  13. ante = 0;
  14. break;
  15. }
  16. case (roll > 1) {
  17. ante += roll;
  18. }
  19. }
  20. ((score + ante >= GOAL) || strategy()) && break;
  21. }
  22. score += ante;
  23. }
  24. }
  25. var players = [];
  26. # default, go-for-broke, always roll again
  27. players[0] = Player.new;
  28. # try to roll 5 times but no more per turn
  29. players[1] = Player.new( strategy: { players[1].rolls >= 5 } );
  30. # try to accumulate at least 20 points per turn
  31. players[2] = Player.new( strategy: { players[2].ante > 20 } );
  32. # random but 90% chance of rolling again
  33. players[3] = Player.new( strategy: { 1.rand < 0.1 } );
  34. # random but more conservative as approaches goal
  35. players[4] = Player.new( strategy: { 1.rand < ((GOAL - players[4].score) * 0.6 / GOAL) } );
  36. var wins = [0]*players.len;
  37. games.times {
  38. var player = -1;
  39. loop {
  40. player++;
  41. var p = players[player % players.len];
  42. p.turn;
  43. p.score >= GOAL && break;
  44. }
  45. wins[player % players.len]++;
  46. players.map{.score}.join("\t").say;
  47. players.each { |p| p.score = 0 };
  48. }
  49. "\nSCORES: for #{games} games".say;
  50. wins.join("\t").say;