#!/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;