Partial class for the DesertPumpGame that manages worker hiring and levels. It stores per-worker levels, computes costs and outputs, totals crew production, tracks hired count, and provides BuyWorker to pay, promote, play sound, invoke a Hired event and save.
namespace DesertPump;
/// <summary>
/// The hired help. Workers add litres per second on top of the pump, and unlike the
/// pump they keep working while you're doing something else entirely.
/// </summary>
public sealed partial class DesertPumpGame
{
readonly int[] workerLevels = new int[WorkerType.Count];
public int WorkerLevel( WorkerType worker ) => workerLevels[worker.Index];
public bool IsHired( WorkerType worker ) => WorkerLevel( worker ) > 0;
public bool IsWorkerMaxed( WorkerType worker ) => WorkerLevel( worker ) >= WorkerType.MaxLevel;
/// <summary>Cost of the next level, or infinity when they've nothing left to learn.</summary>
public double WorkerCost( WorkerType worker ) => IsWorkerMaxed( worker )
? double.PositiveInfinity
: worker.CostAt( WorkerLevel( worker ) );
public bool CanHire( WorkerType worker ) => !IsWorkerMaxed( worker ) && Coins >= WorkerCost( worker );
/// <summary>What one worker is currently producing.</summary>
public double WorkerOutput( WorkerType worker ) => worker.OutputAt( WorkerLevel( worker ) );
/// <summary>Everything the crew makes between them, litres per second.</summary>
public double WorkerWaterPerSecond
{
get
{
double total = 0;
foreach ( var worker in WorkerType.All )
{
total += WorkerOutput( worker );
}
return total;
}
}
/// <summary>How many of the fifteen are on the payroll.</summary>
public int HiredCount
{
get
{
var count = 0;
foreach ( var worker in WorkerType.All )
{
if ( IsHired( worker ) ) count++;
}
return count;
}
}
/// <summary>The pump and the crew together - what the tank actually fills at.</summary>
public double TotalWaterPerSecond => CurrentPump.PerSecond + WorkerWaterPerSecond;
/// <summary>Fired after hiring or promoting someone.</summary>
public Action<WorkerType> Hired { get; set; }
/// <summary>Hire a worker, or promote one you already have.</summary>
public bool BuyWorker( WorkerType worker )
{
if ( IsWorkerMaxed( worker ) )
{
Refuse( $"{worker.Name} can't be promoted any further" );
return false;
}
var cost = WorkerCost( worker );
if ( Coins < cost )
{
Refuse( $"Need {Numbers.Short( cost - Coins )} more coins" );
return false;
}
Coins -= cost;
workerLevels[worker.Index]++;
Play( UpgradeSound );
Hired?.Invoke( worker );
Save();
return true;
}
}