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