For a bit of fun last night I coded the beer game in J5:
package beergame;
import java.util.*;
import java.util.concurrent.*;
import static java.lang.System.*;
import static java.lang.Math.*;
/**
* MIT Beer Game simulation. Rules from:
* <blockquote>
* http://www.solonline.org/repository/download/instr.html?item_id=456354
* </blockquote>
* <p>
* Except:
* <ul>
* <li>I assumed: order delay = shipping delay = production delay = 1 week,
* the above site doesn't state the delays!
* <li>The customer buys a random number of cases, between 1 and 10, each week
* <li>Rest as suggested at above reference
* </ul>
* <p>
* Note: <em>I have never played the game!</em>. Therefore my interpretation
* of the rules may be wrong!
*
* @author Howard Lovatt
*/
public class Play {
static final int maxOrder = 10; // the maximum order a cistomer can place
static final int week = 100; // ms, i.e. 1 week takes 0.1 seconds to simulate
static double runningTotal = 0; // the total cost incurred to date
static final ExecutorService pool = Executors.newCachedThreadPool();
public static void main( final String[] notUsed ) throws InterruptedException {
final Order initialOrder = new Order( maxOrder / 2 ); // establish the initial state
Queues.rWOrders.put( initialOrder );
Queues.wDOrders.put( initialOrder );
Queues.dFOrders.put( initialOrder );
Production.BEER.orders.put( initialOrder );
final Beer initialBeer = new Beer( maxOrder / 2 );
Queues.wRBeers.put( initialBeer );
Queues.dWBeers.put( initialBeer );
Queues.fDBeers.put( initialBeer );
Production.BEER.beers.put( initialBeer );
Production.BEER.production.put( initialBeer );
Thread.sleep( week ); // wait a week to allow orders/beers to progress in their queues
pool.execute( Customer.DEMAND ); // start the game
pool.execute( Player.RETAILER );
pool.execute( Player.WHOLESALER );
pool.execute( Player.DISTRIBUTOR );
pool.execute( Player.FACTORY );
pool.execute( Production.BEER );
Thread.sleep( 3000 ); // game lasts no longer than 3 seconds, to keep output short - but test new strategies for much longer, e.g. 20 seconds, to demonstrate stability!
pool.shutdownNow();
}
private interface Queues { // These static fields are put in an interface so that they are initalized before the static field enums in the Player enum (pain with enums!)
BlockingQueue< Order > rWOrders = new DelayQueue< Order >();
BlockingQueue< Order > wDOrders = new DelayQueue< Order >();
BlockingQueue< Order > dFOrders = new DelayQueue< Order >();
BlockingQueue< Beer > wRBeers = new DelayQueue< Beer >();
BlockingQueue< Beer > dWBeers = new DelayQueue< Beer >();
BlockingQueue< Beer > fDBeers = new DelayQueue< Beer >();
}
private static enum Player implements Runnable, Queues {
RETAILER( Customer.DEMAND.orders, rWOrders, wRBeers, Customer.DEMAND.blackHole ),
WHOLESALER( rWOrders, wDOrders, dWBeers, wRBeers ),
DISTRIBUTOR( wDOrders, dFOrders, fDBeers, dWBeers ),
FACTORY( dFOrders, Production.BEER.orders, Production.BEER.beers, fDBeers );
static final int targetInventory = 5 * maxOrder; // paramaters for decision method, inventory needs to be large for stability, e.g. 5 * maxOrder, for the simple controller given
static final float pGain = 1F; // you can play with this! 0 is too low and 2 is too high (the term pGain is from control theory - this is the proportional gain of the controller)
final BlockingQueue< Order > inOrders; // queues
final BlockingQueue< Order > outOrders;
final BlockingQueue< Beer > inBeers;
final BlockingQueue< Beer > outBeers;
int backOrder = 0; // start with no backlog
int inventory = targetInventory; // start with target inventory
Player( final BlockingQueue< Order > inOrders, final BlockingQueue< Order > outOrders,
final BlockingQueue< Beer > inBeers, final BlockingQueue< Beer > outBeers ) {
this.inOrders = inOrders;
this.outOrders = outOrders;
this.inBeers = inBeers;
this.outBeers = outBeers;
}
public void run() {
try {
while ( true ) {
final int inOrder = inOrders.take().value;
final int inBeer = inBeers.take().value; // get beer delivery
inventory += inBeer; // add to inventory
final int beerRequired = inOrder + backOrder;
final int outBeer;
if ( inventory >= beerRequired ) {
outBeer = beerRequired;
backOrder = 0;
inventory -= beerRequired;
} else {
outBeer = inventory;
backOrder += beerRequired - inventory;
inventory = 0;
}
outBeers.put( new Beer( outBeer ) );
final int inventoryError = targetInventory - inventory + backOrder;
final int outOrder = max( 0, round( controller( inventoryError ) ) ); // integer and can't have negative orders
outOrders.put( new Order( outOrder ) );
out.println( "inOrder = " + inOrder + ", outOrder = " + outOrder + ", inBeer = " + inBeer + ", outBeer = " + outBeer + ", inventory = " + inventory + ", backOrder = " + backOrder + " for " + this);
}
} catch ( InterruptedException notUsed ) { /* OK to quit */ }
}
float controller( final int error ) { // you can play with different strategies for this simple P controller by setting targetInventory and pGain
return pGain * error;
}
public String toString() { return super.toString() + ":$" + getCost(); }
double getCost() { return backOrder + 0.5 * inventory; }
}
private static enum Customer implements Runnable {
DEMAND;
static final Random rand = new Random( 47 );
static final BlockingQueue< Beer > blackHole = new LinkedBlockingQueue< Beer >() { // disgard beer! - output not needed in simulation
static final long serialVersionUID = 200509150908; // just in case it is serialized
public void put( final Beer notUsed ) { /* disgard input - this is a black hole */ }
};
final BlockingQueue< Order > orders = new ArrayBlockingQueue< Order >( 1 ); // use a buffer of length 1 so that this task gives way to others - ensures orderly execution
int weekNumber = 0;
public void run() {
try {
while ( true ) {
for ( Player player : Player.values() ) runningTotal += player.getCost(); // Output status
out.println( "Week " + (weekNumber++) + ": " + " Running Total = $" + runningTotal + ' ' + Arrays.toString( Player.values() ) );
orders.put( new Order( rand.nextInt( maxOrder ) ) ); // place a random order of up to maxOrder beers
Thread.sleep( week ); // place next order in a weeks time - lazy programming a scheduled executor would be better!
}
} catch ( InterruptedException notUsed ) { /* OK to quit */ }
}
}
private static enum Production implements Runnable {
BEER;
final BlockingQueue< Order > orders = new DelayQueue< Order >();
final BlockingQueue< Beer > production = new DelayQueue< Beer >(); // making beer takes a week
final BlockingQueue< Beer > beers = new DelayQueue< Beer >();
public void run() {
try {
while ( true ) {
final int order = orders.take().value; // get order
production.put( new Beer( order ) ); // make beer - it takes a week
final int beer = production.take().value; // beer I made earlier
beers.put( new Beer( beer ) ); // ship beer
}
} catch ( InterruptedException notUsed ) { /* OK to quit */ }
}
}
private static class Order implements Delayed {
final int value;
final long endTime = currentTimeMillis() + week; // 1 week delay
Order( final int value ) {
if ( value < 0 ) {
pool.shutdownNow(); // terminate game - numeric overflow!
throw new IllegalArgumentException( "Negative order or beer - probably a numeric overflow");
}
this.value = value;
}
public long getDelay( final TimeUnit unit ) { return unit.convert( endTime - currentTimeMillis(), TimeUnit.MILLISECONDS ); }
public int compareTo( final Delayed notUsed ) { return 0; }
public String toString() { return Integer.toString( value ); }
}
private static class Beer extends Order { // alias for Order, i.e. shipping delay = ordering delay and number of beers >= 0
Beer( final int value ) { super( value ); }
}
}
The output is:
Week 0: Running Total = $100.0 [RETAILER:$25.0, WHOLESALER:$25.0, DISTRIBUTOR:$25.0, FACTORY:$25.0]
inOrder = 8, outOrder = 3, inBeer = 5, outBeer = 8, inventory = 47, backOrder = 0 for RETAILER:$23.5
inOrder = 5, outOrder = 0, inBeer = 5, outBeer = 5, inventory = 50, backOrder = 0 for WHOLESALER:$25.0
inOrder = 5, outOrder = 0, inBeer = 5, outBeer = 5, inventory = 50, backOrder = 0 for DISTRIBUTOR:$25.0
inOrder = 5, outOrder = 0, inBeer = 5, outBeer = 5, inventory = 50, backOrder = 0 for FACTORY:$25.0
Week 1: Running Total = $198.5 [RETAILER:$23.5, WHOLESALER:$25.0, DISTRIBUTOR:$25.0, FACTORY:$25.0]
inOrder = 5, outOrder = 3, inBeer = 5, outBeer = 5, inventory = 47, backOrder = 0 for RETAILER:$23.5
inOrder = 3, outOrder = 0, inBeer = 5, outBeer = 3, inventory = 52, backOrder = 0 for WHOLESALER:$26.0
inOrder = 0, outOrder = 0, inBeer = 5, outBeer = 0, inventory = 55, backOrder = 0 for DISTRIBUTOR:$27.5
inOrder = 0, outOrder = 0, inBeer = 5, outBeer = 0, inventory = 55, backOrder = 0 for FACTORY:$27.5
Week 2: Running Total = $303.0 [RETAILER:$23.5, WHOLESALER:$26.0, DISTRIBUTOR:$27.5, FACTORY:$27.5]
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 55, backOrder = 0 for DISTRIBUTOR:$27.5
inOrder = 0, outOrder = 0, inBeer = 5, outBeer = 0, inventory = 60, backOrder = 0 for FACTORY:$30.0
inOrder = 3, outOrder = 1, inBeer = 0, outBeer = 3, inventory = 49, backOrder = 0 for WHOLESALER:$24.5
inOrder = 3, outOrder = 3, inBeer = 3, outBeer = 3, inventory = 47, backOrder = 0 for RETAILER:$23.5
Week 3: Running Total = $408.5 [RETAILER:$23.5, WHOLESALER:$24.5, DISTRIBUTOR:$27.5, FACTORY:$30.0]
inOrder = 3, outOrder = 4, inBeer = 0, outBeer = 3, inventory = 46, backOrder = 0 for WHOLESALER:$23.0
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 60, backOrder = 0 for FACTORY:$30.0
inOrder = 1, outOrder = 0, inBeer = 0, outBeer = 1, inventory = 54, backOrder = 0 for DISTRIBUTOR:$27.0
inOrder = 1, outOrder = 1, inBeer = 3, outBeer = 1, inventory = 49, backOrder = 0 for RETAILER:$24.5
Week 4: Running Total = $513.0 [RETAILER:$24.5, WHOLESALER:$23.0, DISTRIBUTOR:$27.0, FACTORY:$30.0]
inOrder = 1, outOrder = 0, inBeer = 3, outBeer = 1, inventory = 51, backOrder = 0 for RETAILER:$25.5
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 60, backOrder = 0 for FACTORY:$30.0
inOrder = 4, outOrder = 0, inBeer = 0, outBeer = 4, inventory = 50, backOrder = 0 for DISTRIBUTOR:$25.0
inOrder = 1, outOrder = 4, inBeer = 1, outBeer = 1, inventory = 46, backOrder = 0 for WHOLESALER:$23.0
Week 5: Running Total = $616.5 [RETAILER:$25.5, WHOLESALER:$23.0, DISTRIBUTOR:$25.0, FACTORY:$30.0]
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 60, backOrder = 0 for FACTORY:$30.0
inOrder = 4, outOrder = 4, inBeer = 0, outBeer = 4, inventory = 46, backOrder = 0 for DISTRIBUTOR:$23.0
inOrder = 0, outOrder = 0, inBeer = 4, outBeer = 0, inventory = 50, backOrder = 0 for WHOLESALER:$25.0
inOrder = 9, outOrder = 7, inBeer = 1, outBeer = 9, inventory = 43, backOrder = 0 for RETAILER:$21.5
Week 6: Running Total = $716.0 [RETAILER:$21.5, WHOLESALER:$25.0, DISTRIBUTOR:$23.0, FACTORY:$30.0]
inOrder = 4, outOrder = 0, inBeer = 0, outBeer = 4, inventory = 56, backOrder = 0 for FACTORY:$28.0
inOrder = 0, outOrder = 4, inBeer = 0, outBeer = 0, inventory = 46, backOrder = 0 for DISTRIBUTOR:$23.0
inOrder = 7, outOrder = 3, inBeer = 4, outBeer = 7, inventory = 47, backOrder = 0 for WHOLESALER:$23.5
inOrder = 8, outOrder = 15, inBeer = 0, outBeer = 8, inventory = 35, backOrder = 0 for RETAILER:$17.5
Week 7: Running Total = $808.0 [RETAILER:$17.5, WHOLESALER:$23.5, DISTRIBUTOR:$23.0, FACTORY:$28.0]
inOrder = 3, outOrder = 3, inBeer = 4, outBeer = 3, inventory = 47, backOrder = 0 for DISTRIBUTOR:$23.5
inOrder = 15, outOrder = 18, inBeer = 0, outBeer = 15, inventory = 32, backOrder = 0 for WHOLESALER:$16.0
inOrder = 0, outOrder = 8, inBeer = 7, outBeer = 0, inventory = 42, backOrder = 0 for RETAILER:$21.0
inOrder = 4, outOrder = 0, inBeer = 0, outBeer = 4, inventory = 52, backOrder = 0 for FACTORY:$26.0
Week 8: Running Total = $894.5 [RETAILER:$21.0, WHOLESALER:$16.0, DISTRIBUTOR:$23.5, FACTORY:$26.0]
inOrder = 18, outOrder = 17, inBeer = 4, outBeer = 18, inventory = 33, backOrder = 0 for DISTRIBUTOR:$16.5
inOrder = 8, outOrder = 23, inBeer = 3, outBeer = 8, inventory = 27, backOrder = 0 for WHOLESALER:$13.5
inOrder = 3, outOrder = 1, inBeer = 0, outBeer = 3, inventory = 49, backOrder = 0 for FACTORY:$24.5
inOrder = 2, outOrder = 0, inBeer = 15, outBeer = 2, inventory = 55, backOrder = 0 for RETAILER:$27.5
Week 9: Running Total = $976.5 [RETAILER:$27.5, WHOLESALER:$13.5, DISTRIBUTOR:$16.5, FACTORY:$24.5]
inOrder = 23, outOrder = 37, inBeer = 3, outBeer = 23, inventory = 13, backOrder = 0 for DISTRIBUTOR:$6.5
inOrder = 17, outOrder = 18, inBeer = 0, outBeer = 17, inventory = 32, backOrder = 0 for FACTORY:$16.0
inOrder = 0, outOrder = 5, inBeer = 18, outBeer = 0, inventory = 45, backOrder = 0 for WHOLESALER:$22.5
inOrder = 7, outOrder = 0, inBeer = 8, outBeer = 7, inventory = 56, backOrder = 0 for RETAILER:$28.0
Week 10: Running Total = $1049.5 [RETAILER:$28.0, WHOLESALER:$22.5, DISTRIBUTOR:$6.5, FACTORY:$16.0]
inOrder = 5, outOrder = 25, inBeer = 17, outBeer = 5, inventory = 25, backOrder = 0 for DISTRIBUTOR:$12.5
inOrder = 37, outOrder = 55, inBeer = 0, outBeer = 32, inventory = 0, backOrder = 5 for FACTORY:$5.0
inOrder = 0, outOrder = 0, inBeer = 23, outBeer = 0, inventory = 68, backOrder = 0 for WHOLESALER:$34.0
inOrder = 8, outOrder = 2, inBeer = 0, outBeer = 8, inventory = 48, backOrder = 0 for RETAILER:$24.0
Week 11: Running Total = $1125.0 [RETAILER:$24.0, WHOLESALER:$34.0, DISTRIBUTOR:$12.5, FACTORY:$5.0]
inOrder = 0, outOrder = 0, inBeer = 32, outBeer = 0, inventory = 57, backOrder = 0 for DISTRIBUTOR:$28.5
inOrder = 25, outOrder = 84, inBeer = 1, outBeer = 1, inventory = 0, backOrder = 34 for FACTORY:$34.0
inOrder = 2, outOrder = 0, inBeer = 5, outBeer = 2, inventory = 71, backOrder = 0 for WHOLESALER:$35.5
inOrder = 8, outOrder = 10, inBeer = 0, outBeer = 8, inventory = 40, backOrder = 0 for RETAILER:$20.0
Week 12: Running Total = $1243.0 [RETAILER:$20.0, WHOLESALER:$35.5, DISTRIBUTOR:$28.5, FACTORY:$34.0]
Week 13: Running Total = $1361.0 [RETAILER:$20.0, WHOLESALER:$35.5, DISTRIBUTOR:$28.5, FACTORY:$34.0]
inOrder = 0, outOrder = 0, inBeer = 1, outBeer = 0, inventory = 58, backOrder = 0 for DISTRIBUTOR:$29.0
inOrder = 0, outOrder = 100, inBeer = 18, outBeer = 18, inventory = 0, backOrder = 50 for FACTORY:$50.0
inOrder = 10, outOrder = 0, inBeer = 0, outBeer = 10, inventory = 61, backOrder = 0 for WHOLESALER:$30.5
inOrder = 1, outOrder = 9, inBeer = 2, outBeer = 1, inventory = 41, backOrder = 0 for RETAILER:$20.5
Week 14: Running Total = $1491.0 [RETAILER:$20.5, WHOLESALER:$30.5, DISTRIBUTOR:$29.0, FACTORY:$50.0]
inOrder = 0, outOrder = 0, inBeer = 18, outBeer = 0, inventory = 76, backOrder = 0 for DISTRIBUTOR:$38.0
inOrder = 0, outOrder = 45, inBeer = 55, outBeer = 50, inventory = 5, backOrder = 0 for FACTORY:$2.5
inOrder = 9, outOrder = 0, inBeer = 0, outBeer = 9, inventory = 52, backOrder = 0 for WHOLESALER:$26.0
inOrder = 9, outOrder = 8, inBeer = 10, outBeer = 9, inventory = 42, backOrder = 0 for RETAILER:$21.0
Week 15: Running Total = $1578.5 [RETAILER:$21.0, WHOLESALER:$26.0, DISTRIBUTOR:$38.0, FACTORY:$2.5]
inOrder = 0, outOrder = 0, inBeer = 50, outBeer = 0, inventory = 126, backOrder = 0 for DISTRIBUTOR:$63.0
inOrder = 0, outOrder = 0, inBeer = 84, outBeer = 0, inventory = 89, backOrder = 0 for FACTORY:$44.5
inOrder = 8, outOrder = 6, inBeer = 0, outBeer = 8, inventory = 44, backOrder = 0 for WHOLESALER:$22.0
inOrder = 9, outOrder = 8, inBeer = 9, outBeer = 9, inventory = 42, backOrder = 0 for RETAILER:$21.0
Week 16: Running Total = $1729.0 [RETAILER:$21.0, WHOLESALER:$22.0, DISTRIBUTOR:$63.0, FACTORY:$44.5]
inOrder = 6, outOrder = 0, inBeer = 0, outBeer = 6, inventory = 120, backOrder = 0 for DISTRIBUTOR:$60.0
inOrder = 0, outOrder = 0, inBeer = 100, outBeer = 0, inventory = 189, backOrder = 0 for FACTORY:$94.5
inOrder = 8, outOrder = 14, inBeer = 0, outBeer = 8, inventory = 36, backOrder = 0 for WHOLESALER:$18.0
inOrder = 8, outOrder = 8, inBeer = 8, outBeer = 8, inventory = 42, backOrder = 0 for RETAILER:$21.0
Week 17: Running Total = $1922.5 [RETAILER:$21.0, WHOLESALER:$18.0, DISTRIBUTOR:$60.0, FACTORY:$94.5]
inOrder = 14, outOrder = 0, inBeer = 0, outBeer = 14, inventory = 106, backOrder = 0 for DISTRIBUTOR:$53.0
inOrder = 0, outOrder = 0, inBeer = 45, outBeer = 0, inventory = 234, backOrder = 0 for FACTORY:$117.0
inOrder = 8, outOrder = 16, inBeer = 6, outBeer = 8, inventory = 34, backOrder = 0 for WHOLESALER:$17.0
inOrder = 8, outOrder = 8, inBeer = 8, outBeer = 8, inventory = 42, backOrder = 0 for RETAILER:$21.0
Week 18: Running Total = $2130.5 [RETAILER:$21.0, WHOLESALER:$17.0, DISTRIBUTOR:$53.0, FACTORY:$117.0]
inOrder = 16, outOrder = 0, inBeer = 0, outBeer = 16, inventory = 90, backOrder = 0 for DISTRIBUTOR:$45.0
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 234, backOrder = 0 for FACTORY:$117.0
inOrder = 8, outOrder = 10, inBeer = 14, outBeer = 8, inventory = 40, backOrder = 0 for WHOLESALER:$20.0
inOrder = 1, outOrder = 1, inBeer = 8, outBeer = 1, inventory = 49, backOrder = 0 for RETAILER:$24.5
Week 19: Running Total = $2337.0 [RETAILER:$24.5, WHOLESALER:$20.0, DISTRIBUTOR:$45.0, FACTORY:$117.0]
inOrder = 10, outOrder = 0, inBeer = 0, outBeer = 10, inventory = 80, backOrder = 0 for DISTRIBUTOR:$40.0
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 234, backOrder = 0 for FACTORY:$117.0
inOrder = 1, outOrder = 0, inBeer = 16, outBeer = 1, inventory = 55, backOrder = 0 for WHOLESALER:$27.5
inOrder = 0, outOrder = 0, inBeer = 8, outBeer = 0, inventory = 57, backOrder = 0 for RETAILER:$28.5
Week 20: Running Total = $2550.0 [RETAILER:$28.5, WHOLESALER:$27.5, DISTRIBUTOR:$40.0, FACTORY:$117.0]
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 234, backOrder = 0 for FACTORY:$117.0
inOrder = 0, outOrder = 0, inBeer = 10, outBeer = 0, inventory = 65, backOrder = 0 for WHOLESALER:$32.5
inOrder = 8, outOrder = 0, inBeer = 1, outBeer = 8, inventory = 50, backOrder = 0 for RETAILER:$25.0
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 80, backOrder = 0 for DISTRIBUTOR:$40.0
Week 21: Running Total = $2764.5 [RETAILER:$25.0, WHOLESALER:$32.5, DISTRIBUTOR:$40.0, FACTORY:$117.0]
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 65, backOrder = 0 for WHOLESALER:$32.5
inOrder = 6, outOrder = 6, inBeer = 0, outBeer = 6, inventory = 44, backOrder = 0 for RETAILER:$22.0
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 234, backOrder = 0 for FACTORY:$117.0
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 80, backOrder = 0 for DISTRIBUTOR:$40.0
Week 22: Running Total = $2976.0 [RETAILER:$22.0, WHOLESALER:$32.5, DISTRIBUTOR:$40.0, FACTORY:$117.0]
Week 23: Running Total = $3187.5 [RETAILER:$22.0, WHOLESALER:$32.5, DISTRIBUTOR:$40.0, FACTORY:$117.0]
inOrder = 6, outOrder = 0, inBeer = 0, outBeer = 6, inventory = 59, backOrder = 0 for WHOLESALER:$29.5
inOrder = 0, outOrder = 6, inBeer = 0, outBeer = 0, inventory = 44, backOrder = 0 for RETAILER:$22.0
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 234, backOrder = 0 for FACTORY:$117.0
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 80, backOrder = 0 for DISTRIBUTOR:$40.0
Week 24: Running Total = $3396.0 [RETAILER:$22.0, WHOLESALER:$29.5, DISTRIBUTOR:$40.0, FACTORY:$117.0]
inOrder = 6, outOrder = 0, inBeer = 0, outBeer = 6, inventory = 53, backOrder = 0 for WHOLESALER:$26.5
inOrder = 1, outOrder = 1, inBeer = 6, outBeer = 1, inventory = 49, backOrder = 0 for RETAILER:$24.5
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 234, backOrder = 0 for FACTORY:$117.0
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 80, backOrder = 0 for DISTRIBUTOR:$40.0
Week 25: Running Total = $3604.0 [RETAILER:$24.5, WHOLESALER:$26.5, DISTRIBUTOR:$40.0, FACTORY:$117.0]
inOrder = 1, outOrder = 0, inBeer = 0, outBeer = 1, inventory = 52, backOrder = 0 for WHOLESALER:$26.0
inOrder = 2, outOrder = 0, inBeer = 6, outBeer = 2, inventory = 53, backOrder = 0 for RETAILER:$26.5
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 234, backOrder = 0 for FACTORY:$117.0
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 80, backOrder = 0 for DISTRIBUTOR:$40.0
Week 26: Running Total = $3813.5 [RETAILER:$26.5, WHOLESALER:$26.0, DISTRIBUTOR:$40.0, FACTORY:$117.0]
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 52, backOrder = 0 for WHOLESALER:$26.0
inOrder = 4, outOrder = 0, inBeer = 1, outBeer = 4, inventory = 50, backOrder = 0 for RETAILER:$25.0
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 234, backOrder = 0 for FACTORY:$117.0
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 80, backOrder = 0 for DISTRIBUTOR:$40.0
Week 27: Running Total = $4021.5 [RETAILER:$25.0, WHOLESALER:$26.0, DISTRIBUTOR:$40.0, FACTORY:$117.0]
inOrder = 3, outOrder = 3, inBeer = 0, outBeer = 3, inventory = 47, backOrder = 0 for RETAILER:$23.5
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 234, backOrder = 0 for FACTORY:$117.0
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 80, backOrder = 0 for DISTRIBUTOR:$40.0
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 52, backOrder = 0 for WHOLESALER:$26.0
Week 28: Running Total = $4228.0 [RETAILER:$23.5, WHOLESALER:$26.0, DISTRIBUTOR:$40.0, FACTORY:$117.0]
inOrder = 3, outOrder = 1, inBeer = 0, outBeer = 3, inventory = 49, backOrder = 0 for WHOLESALER:$24.5
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 234, backOrder = 0 for FACTORY:$117.0
inOrder = 6, outOrder = 9, inBeer = 0, outBeer = 6, inventory = 41, backOrder = 0 for RETAILER:$20.5
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 80, backOrder = 0 for DISTRIBUTOR:$40.0
Week 29: Running Total = $4430.0 [RETAILER:$20.5, WHOLESALER:$24.5, DISTRIBUTOR:$40.0, FACTORY:$117.0]
inOrder = 0, outOrder = 0, inBeer = 0, outBeer = 0, inventory = 234, backOrder = 0 for FACTORY:$117.0
inOrder = 5, outOrder = 11, inBeer = 3, outBeer = 5, inventory = 39, backOrder = 0 for RETAILER:$19.5
inOrder = 1, outOrder = 0, inBeer = 0, outBeer = 1, inventory = 79, backOrder = 0 for DISTRIBUTOR:$39.5
inOrder = 9, outOrder = 10, inBeer = 0, outBeer = 9, inventory = 40, backOrder = 0 for WHOLESALER:$20.0
What do you think? - other than that I should have something better to do with my evenings :)