123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- #!/usr/bin/ruby
- var (games=100) = ARGV.map{.to_i}...;
- define DIE = 1..6;
- define GOAL = 100;
- class Player(score=0, ante=0, rolls=0, strategy={false}) {
- method turn {
- rolls = 0;
- ante = 0;
- loop {
- rolls++;
- given (var roll = DIE.rand) {
- when (1) {
- ante = 0;
- break;
- }
- case (roll > 1) {
- ante += roll;
- }
- }
- ((score + ante >= GOAL) || strategy()) && break;
- }
- score += ante;
- }
- }
- var players = [];
- # default, go-for-broke, always roll again
- players[0] = Player.new;
- # try to roll 5 times but no more per turn
- players[1] = Player.new( strategy: { players[1].rolls >= 5 } );
- # try to accumulate at least 20 points per turn
- players[2] = Player.new( strategy: { players[2].ante > 20 } );
- # random but 90% chance of rolling again
- players[3] = Player.new( strategy: { 1.rand < 0.1 } );
- # random but more conservative as approaches goal
- players[4] = Player.new( strategy: { 1.rand < ((GOAL - players[4].score) * 0.6 / GOAL) } );
- var wins = [0]*players.len;
- games.times {
- var player = -1;
- loop {
- player++;
- var p = players[player % players.len];
- p.turn;
- p.score >= GOAL && break;
- }
- wins[player % players.len]++;
- players.map{.score}.join("\t").say;
- players.each { |p| p.score = 0 };
- }
- "\nSCORES: for #{games} games".say;
- wins.join("\t").say;
|