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 :)