User:Ais523/jumble1.pl

From BlogNomic Wiki
Jump to navigation Jump to search
use warnings;
use strict;

$|=1;

our %assets;
our $silent = 0;

# Machine name format: Name* [Widget] (Storage)
# Heats the given machine. Returns a reference to its name.
sub heat_machine {
    my $looking_for = shift;
    $looking_for =~ /['*]/ and die "When heating a machine, you should specify the cold form";
    for my $i (0..$assets{machine}->$#*) {
        my $machine = \$assets{machine}[$i];
        my $cold_machine = $$machine;
        $cold_machine =~ s/[']//g;
        $cold_machine eq $looking_for or next;

        $$machine =~ s/'/*/ and return $machine;
        $$machine =~ s/ \[Cooling Widget\]/' [Cooling Widget]/ and return $machine;
        $$machine =~ s/ \(/* (/ and return $machine;
        $$machine =~ s/$/*/ and return $machine;
    }
    die "Did not have a Cold/Warm $looking_for to heat";
}

# Removes all of the given Thing. Returns the number removed.
sub consume_all_things {
    my $target = shift;
    my @new_thing_array;
    my $removed_count;
    for my $thing ($assets{thing}->@*) {
        if ($thing eq $target) {
            ++$removed_count;
        } else {
            push @new_thing_array, $thing;
        }
    }
    $assets{thing} = \@new_thing_array;
    $removed_count
}

# A pure function. Determines whether the given machine/widget is High Tech.
sub is_high_tech {
    my $m_or_w = shift;
    $m_or_w =~ /^Chime\b/ and return 1;
    return;
}

# Determines whether the given machine/widget is unavailable due to being High Tech.
sub is_unavailable_tech {
    my $m_or_w = shift;
    return unless is_high_tech $m_or_w;
    return if grep ($m_or_w =~ /^\Q$_\E\b/), $assets{tech}->@*;
    return 1;
}

# A pure function. Outputs the cost of the machine or widget.
sub machine_or_widget_cost {
    my $m_or_w = shift;
    my $param = shift;

    $m_or_w =~ /^Axe\b/ and return [box => $param * 2];
    $m_or_w =~ /^Baker\b/ and return [cog => 1];
    if ($m_or_w =~ /^Chime\b/) {
        10 == scalar @$param or die "A Chime costs 10 Things";
        my %seen;
        $seen{$_}++ and die "A Chime costs 10 different Things (duplicated Thing: $_)" for @$param;
        return [map ((thing => $_), @$param)];
    }    
    $m_or_w =~ /^Clink\b/ and return [box => $param];
    if ($m_or_w =~ /^Compactor\b/) {
        scalar @$param or die "You cannot compact 0 Things";
        return [map ((thing => $_), @$param)];
    }
    $m_or_w =~ /^Crusher\b/ and return [energy => 1, machine => $param];
    $m_or_w =~ /^Dustsheet\b/ and die "Dustsheet unimplemented, because its buy cost and use cost are different";
    $m_or_w =~ /^Glue Gun\b/ and return [box => $param->[0], box => $param->[1]];
    $m_or_w =~ /^Greenhouse\b/ and return [energy => 1, thing => "$param Seed"];
    $m_or_w =~ /^Harvester\b/ and return [cog => 2];
    $m_or_w =~ /^Mill\b/ and return [cog => 1];
    $m_or_w =~ /^Press\b/ and return [energy => 1];
    $m_or_w =~ /^Printer\b/ and return [box => $param];
    if ($m_or_w =~ /^Prototyper\b/) {
        $param > $assets{proto} or die "With $assets{proto} Prototypes, a $param box is too small to pay the Prototyper's cost";
        return [cog => $assets{proto}, box => $param];
    }
    $m_or_w =~ /^Seeder\b/ and return [cog => 1];
    $m_or_w =~ /^Spin\b/ and return [energy => 1];
    $m_or_w =~ /^Storage\b/ and return [box => $param];
    $m_or_w =~ /^Sugarcuber\b/ and return [cog => 1];
    $m_or_w =~ /^Wastebin\b/ and return [energy => 1];

    $m_or_w eq 'Cooling Widget' and return [cog => 10];
    $m_or_w eq 'Boxing Widget' and return [cog => 5];

    die "Unrecognised machine/widget '$m_or_w'";
}

# Outputs the items produced by the machine. May have side effects (e.g. consuming Sugar for a Sugarcuber).
# The machine should be heated before calling this function – its name may be overwritten via $$_[0].
sub machine_effect {
    my $mref = shift;
    my $machine = $$mref;
    my $param = shift;

    $machine =~ /^Axe\b/ and return [box => $param, box => $param];
    $machine =~ /^Baker\b/ and return [map ((thing => 'Bread'), 1..consume_all_things('Flour'))];
    if ($machine =~ /^Chime\b/) {
        $assets{proto} < 11 and return [proto => 2];
        return [victory => 1];
    }
    $machine =~ /^Clink\b/ and return [cog => $param];
    $machine =~ /^Compactor\b/ and return [box => scalar @$param];
    $machine =~ /^Crusher\b/ and die "Crusher usage unimplemented, due to difficulty in calculating the minimum cost";
    $machine =~ /^Glue Gun\b/ and return [box => $param->[0] + $param->[1]];
    $machine =~ /^Greenhouse(['*])(?: \(.*\))?(.*)$/ and $$mref = "Greenhouse$1 ($param)$2" and return [];
    if ($machine =~ /^Harvester\b/) {
        my @output;
        for my $other_machine ($assets{machine}->@*) {
            $other_machine =~ /^Greenhouse\* \((.*?)\)/ and push @output, thing => $1, thing => "$1 Seed";
        }
        return \@output;
    }
    $machine =~ /^Mill\b/ and return [map ((thing => 'Flour'), 1..consume_all_things('Wheat'))];
    if ($machine =~ /^Press\b/) {
        $param >= 1 && $param <= 5 or die "You can only Press a box in the 1..5 range";
        return [box => $param];
    }
    $machine =~ /^Printer\b/ and return [map ((thing => 'Paper'), 1..((($param&1)+$param)/2))];
    $machine =~ /^Prototyper\b/ and return [proto => 1];
    $machine =~ /^Seeder\b/ and return [thing => "$param Seed"];
    $machine =~ /^Spin\b/ and die "Spin usage unimplemented, because it has random effects";
    $machine =~ /^Storage(['*]) \((\d+)\)(.*)$/ and $$mref = "Storage$1 ($param)$3" and return [box => $2];
    $machine =~ /^Sugarcuber\b/ and return [map ((thing => 'Sugarcube'), 1..consume_all_things('Sugar'))];
    $machine =~ /^Wastebin\b/ and die "Wastebin usage unimplemented, because it has random effects";
    die "Unrecognised warm/hot machine '$machine'";
}

# A pure function. Gives a text representation of an action parameter.
sub param_as_text {
    my $machine = shift;
    my $param = shift;
    local $" = ", ";

    $machine =~ /^Axe\b/ and return "(using a ".($param*2)."-Box)";
    $machine =~ /^Chime\b/ and return "(spending @$param)";
    $machine =~ /^Clink\b/ and return "(using a $param-Box)";
    $machine =~ /^Compactor\b/ and return "(spending @$param)";
    $machine =~ /^Crusher\b/ and return "(spending a $param)";
    $machine =~ /^Glue Gun\b/ and return "(using a ".$param->[0]."-Box and a ".$param->[1]."-Box)";
    $machine =~ /^Greenhouse\b/ and return "(using a $param Seed)";
    $machine =~ /^Press\b/ and return "(making a $param-Box)";
    $machine =~ /^Printer\b/ and return "(using a $param-Box)";
    $machine =~ /^Prototyper\b/ and return "(spending a $param-Box)";
    $machine =~ /^Seeder\b/ and return "(producing a $param Seed)";
    $machine =~ /^Storage\b/ and return "(using a $param-Box)";
    die "Unexpected parameter for action involving machine '$machine'";
}

sub spend_assets {
    my @to_spend = shift->@*;
    while (@to_spend) {
        my $asset_type = shift @to_spend;
        my $what = shift @to_spend;
        if (ref $assets{$asset_type}) {
            my $found = 0;
            my @new_list;
            for my $asset ($assets{$asset_type}->@*) {
                if (!$found && $asset eq $what) {
                    $found = 1;
                } else {
                    push @new_list, $asset;
                }
            }
            $found or die "Trying to spend nonexistent $asset_type $what";
            $assets{$asset_type} = \@new_list;
        } else {
            $assets{$asset_type} >= $what or die "Trying to spend $asset_type x $what, but only $assets{$asset_type} are available";
            $what > 0 or die "Trying to spend a negative amount $what of $asset_type";
            $assets{$asset_type} -= $what;
        }
    }
}

sub gain_assets {
    my @to_gain = shift->@*;
    while (@to_gain) {
        my $asset_type = shift @to_gain;
        my $what = shift @to_gain;
        if (ref $assets{$asset_type}) {
            push $assets{$asset_type}->@*, $what;
        } else {
            $what > 0 or die "Trying to gain a negative amount $what of $asset_type";
            $assets{$asset_type} += $what;
        }
    }
    
    scalar $assets{machine}->@* > 6 and die "There is a limit of 6 Machines on the Line";
    scalar $assets{thing}->@* > 10 and die "There is a limit of 10 Things (explicitly specify which new Things to keep)";
}

$\ = $/;
print '{| class="wikitable"';
print "! Boxes || Energy || Cogs || Proto || Machines || Things || Tech || Action";

# XSS warning: the argument is wikitext, not plain text.
sub print_comment_wikitext {
    my $comment_wikitext = shift;
    $silent or print "|-";
    $silent or print "| colspan = 8 | $comment_wikitext";
}

sub print_assets {
    my $action = shift;
    my $machine = shift;
    my $param = shift;
    my $keeping = shift;

    my @sorted_things = sort $assets{thing}->@*;
    my @grouped_things;
    for my $thing (@sorted_things) {
        if (@grouped_things && $grouped_things[-1] =~ /^\Q$thing\E(?: x (\d+))?$/) {
            my $quan = $1 || 1;
            $quan++;
            $grouped_things[-1] = "$thing x $quan";
        } else {
            push @grouped_things, $thing;
        }
    }

    my @machines = $assets{machine}->@*;
    my @grouped_machines;
    for my $machine (@machines) {
        if (@grouped_machines && $grouped_machines[-1] =~ /^\Q$machine\E(?: x (\d+))?$/) {
            my $quan = $1 || 1;
            $quan++;
            $grouped_machines[-1] = "$machine x $quan";
        } else {
            push @grouped_machines, $machine;
        }
    }
    
    local $" = ", ";
    my $boxes = $assets{box}->@* ? "@{$assets{box}}" : "none";
    defined $param and $action .= " " . param_as_text($machine, $param);
    defined $keeping and $action .= " (Thing limit reached: keeping @$keeping)";
    $silent or print "|-";
    $silent or print "| $boxes || $assets{energy} || $assets{cog} || $assets{proto} || @grouped_machines || @grouped_things || @{$assets{tech}} || $action";
    $assets{victory} and print_comment_wikitext "VICTORY!" and $assets{victory} = 0;
}

our $action_count = 0;

sub cycle {
    $assets{box} = [];
    $assets{energy} = 2 if $assets{energy} < 2;
    s/['*]// for $assets{machine}->@*;

    $silent or print_comment_wikitext "End of cycle. Number of dynastic actions performed today: $action_count.";
    print_assets "Cycle Action";
    $action_count = 0;
}

sub buy {
    my $machine = shift;
    my $param = shift;

    die "Cannot buy High Tech $machine that isn't on the tech list" if is_unavailable_tech $machine;

    spend_assets(machine_or_widget_cost($machine, $param));

    gain_assets([machine => ($machine eq 'Storage' ? "$machine ($param)" : $machine)]);
    
    print_assets "Buy $machine", $machine, $param;
    ++$action_count;
}

sub demolish {
    my $machine = shift;
    $machine =~ /['*]/ and die "Only Cold Machines can be Demolished (trying to demolish $machine)";
    spend_assets([machine => $machine]);
    print_assets "Demolish $machine";
    ++$action_count;
}

sub activate {
    my $machine = shift;
    my $param = shift;
    my $keeping = shift;
    
    spend_assets(machine_or_widget_cost($machine, $param));

    die "Cannot activate High Tech $machine that isn't on the tech list" if is_unavailable_tech $machine;
    
    my $mref = heat_machine $machine;
    my $outputs = machine_effect $mref, $param;

    if ($keeping) {
        # Check that the things we're keeping were actually generated.
        my @keeping = @$keeping;
        my @orig_outputs = @$outputs;
        my @kept_outputs;

        while (@orig_outputs) {
            my $asset_type = shift @orig_outputs;
            my $what = shift @orig_outputs;

            if ($asset_type ne 'thing') {
                push @kept_outputs, $asset_type, $what;
                next;
            }

            my @new_keeping;
            while (@keeping) {
                my $kept_thing = shift @keeping;
                if ($kept_thing eq $what) {
                    push @kept_outputs, thing => $kept_thing;
                    last;
                }
                push @new_keeping, $kept_thing;
            }
            push @keeping, @new_keeping;
        }

        local $" = ", ";
        @keeping and die "Trying to keep @keeping which is/are not in the outout";
        $outputs = \@kept_outputs;
    }
    
    gain_assets $outputs;
    $keeping and 10 != scalar $assets{thing}->@*
        and die "When keeping only a subset, you must have exactly 10 Things";

    print_assets "Activate $machine", $machine, $param, $keeping;
    ++$action_count;
}

sub spend {
    my $thing = shift;
    my $param = shift;
    spend_assets([thing => $thing]);

    if ($thing eq 'Sugarcube') {
        $param < 1 || $param > 7 and die "A Sugarcube can only generate a box with value 1..7";
        gain_assets([box => $param]);
        print_assets "Spend $thing (making a $param-Box)";
        return;
    } elsif ($thing eq 'Bread') {
        gain_assets([energy => 1]);
    } elsif ($thing eq 'Corn') {
        gain_assets([cog => 2]);
    } else {
        die "Unrecognised or unspendable thing $thing";
    }

    print_assets "Spend $thing";
    ++$action_count;
}

sub attach {
    my $machine = shift;
    my $widget = shift;

    die "Cannot buy High Tech $widget that isn't on the tech list" if is_unavailable_tech $widget;

    spend_assets(machine_or_widget_cost $widget);
    
    for my $i (0..$assets{machine}->$#*) {
        if ($assets{machine}[$i] eq $machine) {
            $assets{machine}[$i] =~ s/ \[.*?\]//;
            $assets{machine}[$i] =~ /^(.*?)((?: \(.*\))?)$/;
            $assets{machine}[$i] = "$1 [$widget]$2";

            print_assets "Attach $widget to $machine";
            ++$action_count;
            return;
        }
    }
    die "Could not find a $machine to attach a $widget to";
}

sub buy_tech {
    my $m_or_w = shift;
    my $param = shift;
    die "Cannot buy Low Tech $m_or_w for the tech list, only High Tech machines/widgets can be there"
        unless is_high_tech $m_or_w;

    spend_assets(machine_or_widget_cost $m_or_w, $param);

    push $assets{tech}->@*, $m_or_w;
    die "You cannot have more Tech ([@{$assets{tech}}]) than Prototypes ($assets{proto})"
        unless $assets{proto} >= scalar $assets{tech}->@*;

    print_assets "Buy Tech $m_or_w";
    ++$action_count;
}

# %assets = (
#     box => [],
#     energy => 2,
#     cog => 16,
#     proto => 2,
#     machine => ['Clink', 'Harvester [Cooling Widget]', 'Seeder', 'Seeder', 'Greenhouse', 'Greenhouse'],
#     thing => ['Sugarcube', 'Sugar Seed', 'Sugar Seed', 'Wheat', 'Wheat', 'Wheat', 'Wheat', 'Wheat Seed', 'Corn Seed'],
#     tech => [],
#     victory => 0,
# );
# print_assets "Initial state";

# demolish "Seeder";
# demolish "Seeder";
# activate "Greenhouse", "Wheat";
# activate "Greenhouse", "Corn";
# spend "Sugarcube", 7;
# activate "Clink", 7;
# activate "Harvester [Cooling Widget]";
# spend "Corn";
# buy "Compactor", ["Sugar Seed", "Corn Seed"];
# demolish "Compactor";
# activate "Harvester [Cooling Widget]", undef,
#     ["Wheat Seed", "Corn Seed", "Wheat"];
# buy "Mill";
# activate "Mill";
# buy "Baker";
# activate "Baker";

# cycle;

%assets = (
    box => [],
    energy => 2,
    cog => 17,
    proto => 2,
    machine => ['Clink', 'Harvester [Cooling Widget]', 'Greenhouse (Wheat)', 'Greenhouse (Corn)', 'Mill', 'Baker'],
    thing => ['Sugar Seed', 'Bread', 'Bread', 'Bread', 'Bread', 'Bread', 'Bread', 'Wheat Seed', 'Wheat Seed', 'Corn Seed'],
    tech => [],
    victory => 0,
);
print_assets "Initial state";

demolish "Clink";
demolish "Mill";
demolish "Baker";
spend "Bread" for 1..6;
buy "Greenhouse", "Sugar";
activate "Greenhouse (Wheat)", "Wheat";
activate "Greenhouse (Corn)", "Wheat";
activate "Greenhouse", "Corn";
activate "Harvester [Cooling Widget]";
buy "Greenhouse", "Wheat";
activate "Greenhouse", "Corn";
spend "Corn";
activate "Harvester [Cooling Widget]", undef,
    ["Wheat Seed", "Wheat", "Wheat", "Corn Seed", "Corn Seed", "Corn", "Corn"];
spend "Corn" for 1..2;
buy "Compactor", ["Wheat Seed", "Wheat Seed", "Corn Seed", "Corn Seed"];
demolish "Compactor";
buy "Crusher", "Harvester* [Cooling Widget]";
demolish "Crusher";
buy "Harvester";
attach "Harvester", "Cooling Widget";
activate "Harvester [Cooling Widget]", undef,
    ["Wheat Seed", "Corn Seed", "Wheat", "Wheat", "Corn", "Corn"];
spend "Corn" for 1..2;
buy "Compactor", ["Wheat Seed", "Corn Seed"];
demolish "Compactor";
activate "Harvester [Cooling Widget]", undef,
    ["Wheat", "Wheat", "Corn", "Corn"];
spend "Corn" for 1..2;
buy "Crusher", "Harvester* [Cooling Widget]";
demolish "Crusher";
buy "Mill";
activate "Mill";
buy "Baker";
activate "Baker";
spend "Bread" for 1..8;
buy "Crusher", "Mill*";
demolish "Crusher";
buy "Crusher", "Baker*";
demolish "Crusher";
buy "Harvester";
activate "Harvester";
spend "Corn" for 1..2;
buy "Crusher", "Harvester*";
demolish "Crusher";
buy "Compactor", ["Wheat Seed", "Wheat Seed"];
demolish "Compactor";
buy "Greenhouse", "Corn";
activate "Greenhouse", "Corn";

sub cog_generation_loop {
    buy "Harvester";
    activate "Harvester", undef,
        ["Wheat Seed", "Wheat Seed", "Wheat", "Wheat", "Corn Seed", "Corn", "Corn", "Corn"];
    spend "Corn" for 1..3;
    buy "Crusher", "Harvester*";
    demolish "Crusher";
    buy "Compactor", ["Wheat Seed", "Wheat Seed", "Corn Seed"];
    demolish "Compactor";
    buy "Harvester";
    activate "Harvester", undef,
        ["Wheat", "Wheat", "Corn Seed", "Corn", "Corn", "Corn"];
    spend "Corn" for 1..3;
    buy "Crusher", "Harvester*";
    demolish "Crusher";
    buy "Compactor", ["Corn Seed"];
    demolish "Compactor";    
    buy "Mill";
    activate "Mill";
    buy "Crusher", "Mill*";
    demolish "Crusher";
    buy "Baker";
    activate "Baker";
    spend "Bread" for 1..6;
    buy "Crusher", "Baker*";
    demolish "Crusher";
    buy "Harvester";
    activate "Harvester";
    spend "Corn" for 1..3;
    buy "Crusher", "Harvester*";
    demolish "Crusher";
    buy "Compactor", ["Wheat Seed", "Wheat Seed", "Corn Seed", "Corn Seed", "Corn Seed"];
    demolish "Compactor";    
}

print_comment_wikitext "Main loop starts here.";
cog_generation_loop;
print_comment_wikitext "I'm now back where I was at the start of the main loop, but with 2 more Cogs and 1 more Energy. So I can do the loop again:";
cog_generation_loop;

my $extra_main_loop_iterations = 150;
print_comment_wikitext "This loop can be repeated arbitrarily many times to generate arbitrary amounts of Cogs and Energy. $extra_main_loop_iterations more iterations of the loop have been elided.";
{
    local $silent = 1;
    cog_generation_loop for 1..$extra_main_loop_iterations;
}
print_assets "State after another $extra_main_loop_iterations main loop iterations";

buy "Seeder";
attach "Seeder", "Cooling Widget";
activate "Seeder [Cooling Widget]", "Sugar";
activate "Seeder [Cooling Widget]", "Sugar";
buy "Crusher", "Seeder* [Cooling Widget]";
demolish "Crusher";
buy "Crusher", "Greenhouse* (Wheat)";
demolish "Crusher";
buy "Crusher", "Greenhouse* (Corn)";
demolish "Crusher";
buy "Crusher", "Greenhouse* (Corn)";
demolish "Crusher";
buy "Greenhouse", "Sugar";
activate "Greenhouse", "Sugar";
buy "Compactor", ["Wheat", "Wheat"];
demolish "Compactor";

sub box_generation_loop {
    buy "Harvester";
    activate "Harvester";
    buy "Crusher", "Harvester*";
    demolish "Crusher";
    buy "Compactor", ["Sugar Seed"];
    spend "Corn";
    buy "Harvester";
    activate "Harvester";
    buy "Crusher", "Harvester*";
    demolish "Crusher";
    activate "Compactor", ["Wheat", "Wheat", "Corn", "Sugar", "Sugar", "Corn Seed", "Corn Seed", "Wheat Seed", "Wheat Seed", "Sugar Seed"];
    buy "Crusher", "Compactor*";
    demolish "Crusher";
    buy "Press";
    activate "Press", 5;
    buy "Crusher", "Press*";
    demolish "Crusher";
    buy "Press";
    activate "Press", 5;
    buy "Crusher", "Press*";
    demolish "Crusher";
}

print_comment_wikitext "Box generation loop starts here.";
box_generation_loop;
print_comment_wikitext "I'm now back where I was at the start of the box generation loop, with 6 fewer Cogs, 9 less Energy, one more 10-box and 2 more 5-boxes. I can afford to do the loop again:";
box_generation_loop;
my $extra_box_loop_iterations = 5;
print_comment_wikitext "This loop could be repeated until I run out of Cogs or Energy. I do it $extra_box_loop_iterations more times (these loop iterations have been elided).";
{
    local $silent = 1;
    box_generation_loop for 1..$extra_box_loop_iterations;
}
print_assets "State after another $extra_box_loop_iterations box generation loop iterations";

buy "Prototyper", 5;
attach "Prototyper", "Cooling Widget";
activate "Prototyper [Cooling Widget]", 5;
activate "Prototyper [Cooling Widget]", 5;
buy "Crusher", "Prototyper* [Cooling Widget]";
demolish "Crusher";
buy "Prototyper", 5 for 1..3;
attach "Prototyper", "Cooling Widget" for 1..3;
activate "Prototyper [Cooling Widget]", 5;
activate "Prototyper [Cooling Widget]", 10 for 1..4;
buy "Crusher", "Prototyper* [Cooling Widget]";
demolish "Crusher";
buy "Prototyper", 10;
activate "Prototyper [Cooling Widget]", 10;
buy "Crusher", "Prototyper* [Cooling Widget]" for 1..2;
demolish "Crusher" for 1..2;
buy "Glue Gun", [5, 5];
activate "Glue Gun", [5, 10];
activate "Prototyper", 15;
buy "Crusher", "Prototyper*";
buy "Crusher", "Glue Gun*";
demolish "Crusher" for 1..2;

sub make_10_things {
    buy "Harvester";
    activate "Harvester";
    buy "Crusher", "Harvester*";
    demolish "Crusher";
    buy "Mill";
    attach "Mill", "Cooling Widget";
    activate "Mill [Cooling Widget]";
    buy "Baker";
    activate "Baker";
    buy "Crusher", "Baker*";
    demolish "Crusher";
    buy "Sugarcuber";
    activate "Sugarcuber";
    buy "Crusher", "Sugarcuber*";
    demolish "Crusher";
    buy "Harvester";
    attach "Harvester", "Cooling Widget";
    activate "Harvester [Cooling Widget]", undef,
        ["Wheat", "Corn", "Sugar", "Wheat Seed"];
    activate "Mill [Cooling Widget]";
    buy "Crusher", "Mill* [Cooling Widget]";
    demolish "Crusher";
    spend "Corn" for 1..2;
    buy "Compactor", ["Sugar", "Corn Seed", "Sugar Seed", "Wheat Seed", "Wheat Seed"];
    demolish "Compactor";
    activate "Harvester [Cooling Widget]";
    buy "Printer", 5;
    activate "Printer", 5,
        ["Paper"];
    buy "Crusher", "Printer*";
    buy "Crusher", "Harvester* [Cooling Widget]";
    demolish "Crusher" for 1..2;
}
my @ten_things = ("Bread", "Corn", "Corn Seed", "Flour", "Paper", "Sugar", "Sugar Seed", "Sugarcube", "Wheat", "Wheat Seed");

make_10_things;
buy_tech "Chime", [@ten_things];
make_10_things;

buy "Press";
activate "Press", 5;
buy "Crusher", "Press*";
demolish "Crusher";
buy "Press";
activate "Press", 5;
buy "Crusher", "Press*";
demolish "Crusher";

buy "Chime", [@ten_things];
make_10_things;

print_comment_wikitext "$action_count dynastic actions performed this cycle. One more, and I can achieve victory.";
print "|}";

activate "Chime", [@ten_things];