home *** CD-ROM | disk | FTP | other *** search
/ linuxmafia.com 2016 / linuxmafia.com.tar / linuxmafia.com / pub / palmos / unlicensed / wabburami.java < prev   
Text File  |  2000-12-01  |  20KB  |  754 lines

  1. //
  2. // Wabburami.java
  3. //
  4.  
  5. import waba.ui.*;
  6. import waba.fx.*;
  7. import waba.sys.*;
  8.  
  9. import extra.ui.*;
  10.  
  11. import wabadma.ui.*;
  12. import wabadma.util.*;
  13.  
  14. /**
  15.  *  The classic game of Hammurabi for the JavaOne 1999 KVM.
  16.  *<P>
  17.  *  Play the part of the ruler of ancient Babylon with this
  18.  *  great-great-great-granddaddy of empire building games.   
  19.  *<P> 
  20.  *  The foundation of this Spotlet is Sun's Rumor game that was 
  21.  *  distributed at the 1999 JavaOne developer conference; all the event
  22.  *  and text handling comes directly from that code.  Everything else
  23.  *  was converted from the C version of the game (see below).  I won't
  24.  *  claim that the coding is incredibly clean or well-implemented, but this
  25.  *  is more a demonstration that an ordinary Java engineer can write a 
  26.  *  functional KVM application than anything else (although there's no
  27.  *  data access of any kind).  
  28.  *<P>
  29.  *  Based on C code from the Open License Software Supplement (Skunkware)
  30.  *  that I found at ftp.sco.com/skunkware/ and seemed to me to be close enough
  31.  *  to the original version (in BASIC?) to use as the basis for this code.  : )
  32.  *<P>
  33.  *  TODO:
  34.  *<LI> Add saving of high scores and perhaps game state in a .pdb file.
  35.  *<P>
  36.  *
  37.  *  @author Jim Lesko  --  Jim@MartianWind.com *  @version 0.9
  38.  *
  39.  *  version 0.9w:  07 Nov 2000
  40.  *    modified into waba by dmarcher@pobox.com 
  41.  *
  42.  */
  43.  
  44.  
  45. public class Wabburami extends ExtraMainWindow {
  46.     static String TITLE="Wabburami";
  47.     static String VERSION="0.9w(b10)";
  48.     static String VERSIONDATE="2000 Nov 07";
  49.    
  50.     static DLWRandom r;
  51.     // UI objects:
  52.     MenuBar mb;
  53.     //static Button newButton;    // unused
  54.        static Button exitButton;    // exit the game
  55.        static Button doneButton;    // done with turn
  56.     static Button buyButton;    // buy acres
  57.     static Button sellButton;    // sell acres
  58.     static Button plantMaxButton;    // plant Max. acres
  59.     static Button feedNeededButton;    // feed Min. Needed bushels
  60.     static Button plantRbButton;    // plant using Remaining bushels
  61.     static Button feedRbButton;    // feed Remaining bushels    
  62.     static Button bsPlusButton;    // increase buy/sell #
  63.     static Button bsMinusButton;    // decrease buy/sell #
  64.     static Button feedAcresButton;    // feed min. bushels to tend acres
  65.     static Button plantAvgButton;    // plant min. so avg. yields feeds all
  66.     static NumericEdit buysellEdit;    // # of acres to buy or sell
  67.     static NumericEdit feedEdit;    // # of bushels to feed people
  68.     static NumericEdit plantEdit;    // # of acres to plant
  69.     static OutputBox out;
  70.     static Label statusLabel;
  71.  
  72.        // UI state:
  73.        static int lineAscent;
  74.     static int lineHeight;
  75.     FontMetrics fm;
  76.    
  77.        // Game variables:
  78.        static boolean playing;
  79.     static boolean hard;    // hard difficulty (otherwise it's easy)
  80.    
  81.     static int year;    // Turn number
  82.     static int acres;     // Acres owned
  83.     static int bushels;     // Bushels in storage
  84.     static int pop;        // Population of city
  85.     static int immigrants;    // How many folks immigrated
  86.     static int starved;    // How many died of starvation
  87.     static int rats;    // How many bushels rats destroyed 
  88.     static int harvest;    // Size of last year's harvest
  89.     static int acreCost;    // Cost of an acre in bushels
  90.    
  91.     static boolean plague;     // Plagues struck this turn.
  92.     static int plagueCount; // How many died of plague
  93.  
  94.  
  95.     // Game finals: (some of these will probably change to vars. when
  96.     //    easy/hard difficulty is added.)
  97.     private final static int PLANT_MAX_PER_PERSON = 10;
  98.     private final static int PLANT_ACRES_PER_BUSHEL = 2;
  99.     private final static int BUSHELS_NEEDED_PER_PERSON = 20;
  100.     private final static int MAX_RAT_PCT = 60;
  101.     private final static int PLAGUE_PCT = 10;
  102.     private final static int MAX_IMMIGRANTS = 50;
  103.     private final static int AVG_YIELD = 3;
  104.  
  105.     // finals locating ui objects:
  106.     private final static int W=160;    // Width
  107.     private final static int H=160; // Height
  108.     private final static int L=0;     // Left edge
  109.     private final static int R=159; // Right edge
  110.     private final static int T=0;     // Top edge
  111.     private final static int B=159; // Bottom edge
  112.     private final static int G_H=15;// generic height used by many objects
  113.     private final static int YEAR_X=120;
  114.     private final static int YEAR_Y=2;
  115.     private final static int YEAR_W=W-YEAR_X+1;
  116.     
  117.     private final static int OUT_H=78;
  118.     
  119.     private final static int[] LINES_A = {94,95};
  120.  
  121.     private final static int OUT_Y=16;  
  122.     private final static int STATUS_Y=98;
  123.     private final static int BUYSELL_Y=112;
  124.     private final static int FEED_Y=128;
  125.     private final static int PLANT_Y=144;
  126.     private final static int EXIT_Y=128;
  127.     private final static int DONE_Y=144;
  128.  
  129.     private final static int[][] LABEL_LOCS = 
  130.         {
  131.             {0, BUYSELL_Y, 70, G_H},
  132.             {0, FEED_Y, 55, G_H},
  133.             {0, PLANT_Y, 55, G_H}
  134.         };
  135.  
  136.     private final static String[] LABEL_TXTS =
  137.         {
  138.             "Trade Acres:",
  139.             "Feed Bushels:",
  140.             "Plant Acres:"
  141.         };
  142.  
  143.     private final static int E_X=55;    // x of *Edit
  144.     private final static int E_W=25;    // w of *Edit
  145.     private final static int ED_B_W=29;    // w of Exit & Done Buttons
  146.     private final static int BS_B_W=22;    // w of Buy & Sell Buttons
  147.  
  148.     /*
  149.      * X Layouts:    (button widths: Buy&Sell 24, Exit&Done 32, others 15)
  150.      *
  151.       * Buy/Sell Acres:  
  152.      *   [Label 0..69] [Edit 55..79] [- 83] [+ 99] [Buy 115] [Sell 138]
  153.      *
  154.      * Feed:
  155.      *   [Label 0..54] [Edit 55..79] [ 83] [R 99] [! 115] [Exit 131]
  156.      * 
  157.      * Plant:
  158.      *   [Label 0..54] [Edit 55..79] [ 83] [R 99] [> 115] [Done 131]
  159.      *
  160.      */
  161.  
  162.     private final static int BS_M_X=83;    // x of Minus Button
  163.     private final static int BS_P_X=99;    // x of Plus Button
  164.     private final static int BUY_X=115;    // x of Buy Button
  165.     private final static int SELL_X=138;    // x of Sell Button
  166.  
  167.     private final static int PF_A_X=83;    // x of A Buttons
  168.     private final static int RB_X=99;    // x of *RbButton
  169.  
  170.     private final static int PLANT_MAX_X=115;  // x of Plant Max Button
  171.     private final static int FEED_NEEDED_X=115;// x of Feed Needed Button
  172.     private final static int ED_B_X=131;    // x of Edit & Done Buttons
  173.  
  174.  
  175.     private final static String aboutText =
  176.  
  177.         TITLE + "\n" + VERSION + "\n" + VERSIONDATE;
  178.  
  179.     //"Greetings, Wabburami.";
  180.  
  181.     private final static String helpText1 = 
  182.  
  183.     "You have"+
  184.     " inherited control of Babylon and are charged with"+
  185.     " growing it into a great nation.  You must utilize careful"+
  186.     " land management, distribute food to your subjects, and permit"+
  187.     " those subjects to tend to your crops.  Rats, starvation, and"+
  188.     " plague are the enemies which you must fight.";
  189.  
  190.     //"against every step of the way.";
  191.         
  192.     private final static String helpText2 =
  193.  
  194.     "Each year you must decide whether to buy or sell land, how much grain"+
  195.     " to feed the people, and how many acres to plant.  Once you've"+
  196.     " allocated your resources by entering the appropriate amounts and"+
  197.     " tapping the 'Done' button, you will be told of the"+
  198.     " results of your decisions.";
  199.     
  200.     //"The game ends only when you sell all"+
  201.     //" your land or tap the 'Exit' button.";
  202.             
  203.     //"Go now -- Babylon awaits your enlightened rule.";
  204.  
  205.     private final static String historyText =    
  206.  
  207.     "Wabburami is a Waba version of the classic Hammurabi game.  Its"+
  208.     " implementation is based on the following versions:\n"+ 
  209.  
  210.     "Focal version by ? DEC programmer\n"+
  211.     "Basic version by David H. Ahl\n"+
  212.     "C version by ? SCO contributer\n"+
  213.     "Java KVM version by Jim Lesko\n"+  //JavaOne 1999
  214.     "Waba (this) version by Dave Archer";
  215.          
  216.  
  217.     private final static String keyText1 = 
  218.  
  219.     "To save time writing digits in the 3 numeric fields, you may also"+
  220.     " use the following buttons as shortcuts.\n"+
  221.     "\nTrading Buttons:\n"+
  222.     " [-] decreases acres to trade\n"+
  223.     " [+] increases acres to trade\n"+
  224.     " [Buy] buys # of acres displayed\n"+
  225.     " [Sell] sells # of acres displayed";
  226.  
  227.     private final static String keyText2 =
  228.     "Feed Buttons:\n"+
  229.     " [A] feed enough people to tend crops\n"+
  230.     " [R] feed with remaining bushels\n"+
  231.     " [!] feed enough for all people\n"+
  232.     "Plant Buttons:\n"+
  233.     " [A] plant enough for average yield\n"+
  234.     " [R] plant with remaining bushels\n"+
  235.     " [>] plant as many acres as possible";
  236.     
  237.  
  238.     /** 
  239.      *  App starts here.  Need to check for saved game and/or prompt
  240.      *  for new game.  
  241.      *
  242.      *  Currently just starts a new game.
  243.      */ 
  244.     public Wabburami() {
  245.         super(TITLE); // adding ,true double-buffers but is slow
  246.         r=new DLWRandom();
  247.         fm=getFontMetrics(defaultFont);
  248.         lineAscent=fm.getAscent();
  249.         lineHeight=fm.getHeight();
  250.  
  251.         String[] mls1={"File","New","Quit"};
  252.         String[] mls2={"Options","Help1","Help2","Key1","Key2","History","About"};
  253.         mb = new MenuBar();
  254.         mb.add(new Menu(mls1));
  255.         mb.add(new Menu(mls2));
  256.         setMenuBar(mb);
  257.  
  258.         InitNewGame(false); // init easy game
  259.         StartGame();
  260.     }
  261.  
  262.         
  263.     /**
  264.      *  Initialize variables for a new game.
  265.      *
  266.      */
  267.     private void InitNewGame(boolean hard) {
  268.         this.hard = hard;
  269.           year     = 1;   
  270.         acres     = 1000;
  271.         bushels = 2800; 
  272.         pop     = 100;  
  273.         starved    = 0;
  274.         rats    = 200;
  275.         harvest = 3000; 
  276.         acreCost= 0; 
  277.         immigrants = 5;
  278.         plague     = false;
  279.         plagueCount=0;
  280.     }
  281.  
  282.  
  283.     /**
  284.      *  Game (new or saved) starts here.  Create UI structures, 
  285.      *  display beginning info, and begin allowing UI events.
  286.      */
  287.     private void StartGame() {
  288.         CreateUI();
  289.         // show first (or last)  turn
  290.         showReport();
  291.  
  292.         playing = true;
  293.         this.repaint();
  294.     }
  295.  
  296.     
  297.     /**
  298.      *  Generic Button setup.
  299.      *
  300.      */
  301.     private Button addNewButton(String s, int x, int y, int w, int h) {
  302.         Button b = new Button(s);
  303.         b.setRect(x,y,w,h);
  304.         add(b);
  305.         return b;
  306.     }
  307.  
  308.         
  309.     /**
  310.      *  Create UI structures.
  311.      *
  312.      */
  313.     private void CreateUI() {
  314.         // add buttons
  315.         exitButton = addNewButton("Exit", ED_B_X, EXIT_Y, ED_B_W, G_H);
  316.         doneButton = addNewButton("Done", ED_B_X, DONE_Y, ED_B_W, G_H);
  317.         buyButton = addNewButton("Buy", BUY_X, BUYSELL_Y, BS_B_W, G_H);
  318.         sellButton = addNewButton("Sell", SELL_X, BUYSELL_Y, BS_B_W, G_H);
  319.         feedNeededButton = addNewButton("!", FEED_NEEDED_X, FEED_Y, G_H, G_H);
  320.         plantMaxButton = addNewButton(">", PLANT_MAX_X, PLANT_Y, G_H, G_H);
  321.         feedRbButton = addNewButton("R", RB_X, FEED_Y, G_H, G_H);
  322.         plantRbButton = addNewButton("R", RB_X, PLANT_Y, G_H, G_H);
  323.         bsMinusButton = addNewButton("-", BS_M_X, BUYSELL_Y, G_H, G_H);
  324.         bsPlusButton = addNewButton("+", BS_P_X, BUYSELL_Y, G_H, G_H);
  325.         feedAcresButton = addNewButton("A", PF_A_X, FEED_Y, G_H, G_H);
  326.         plantAvgButton = addNewButton("A", PF_A_X, PLANT_Y, G_H, G_H);
  327.  
  328.  
  329.  
  330.         // create a place to output text
  331.         out = new OutputBox(0,OUT_Y,W,OUT_H);
  332.         add(out);
  333.  
  334.         // add static labels
  335.         for(int i=0;i<LABEL_TXTS.length;i++) {
  336.             //System.err.println("Label "+LABEL_TXTS[i]);
  337.             Label l = new Label(LABEL_TXTS[i]);
  338.             l.setRect(LABEL_LOCS[i][0],LABEL_LOCS[i][1],LABEL_LOCS[i][2],LABEL_LOCS[i][3]);
  339.             add(l);
  340.         }
  341.  
  342.         // add status label
  343.         statusLabel = new Label("");
  344.         statusLabel.setRect(0, STATUS_Y, W, lineHeight);
  345.         add(statusLabel);
  346.  
  347.  
  348.         // add edit controls
  349.         buysellEdit = new NumericEdit();
  350.         buysellEdit.setRect(E_X, BUYSELL_Y, E_W, G_H);    
  351.         buysellEdit.setInt(5);
  352.         add(buysellEdit);
  353.         
  354.         feedEdit = new NumericEdit();
  355.         feedEdit.setRect(E_X,FEED_Y,E_W,G_H);
  356.         feedEdit.setInt(2000);
  357.         add(feedEdit);
  358.  
  359.                 plantEdit = new NumericEdit();
  360.                 plantEdit.setRect(E_X,PLANT_Y,E_W,G_H);
  361.                 plantEdit.setInt(1000);
  362.                 add(plantEdit);
  363.     }
  364.  
  365.  
  366.     public void clearRect(Graphics g, int x, int y, int w, int h) {
  367.         g.setColor(255,255,255);
  368.         g.fillRect(x,y,w,h);
  369.         g.setColor(0,0,0);
  370.     }
  371.  
  372.  
  373.     public void onPaint(Graphics g) {
  374.         //System.err.println("onPaint");
  375.  
  376.         // Year display is next to Title, not in out box
  377.         clearRect(g,YEAR_X,YEAR_Y,YEAR_W,lineAscent);
  378.         g.drawText("Year "+year,YEAR_X,YEAR_Y);
  379.  
  380.         // Draw lines as per LINES_A
  381.         for(int i=0;i<LINES_A.length;i++)
  382.             g.drawLine(T,LINES_A[i],R,LINES_A[i]);
  383.      }
  384.  
  385.  
  386.     /**
  387.      * Update info. in status line.
  388.      */
  389.     private void updateStatus() {
  390.         int surplus = calcSurplus();
  391.         statusLabel.setText("B: "+bushels+"  P: "+pop+"  A: "+acres+"  Surplus: "+surplus);
  392.         statusLabel.repaint();
  393.     }
  394.  
  395.  
  396.     /**
  397.      *  Refresh screen with this turn's info. 
  398.      */
  399.     private void showReport() {
  400.  
  401.         // draw the border between the top text and the input area
  402.         //g.drawLine(0,14,159,14);
  403.  
  404.         out.clear();
  405.  
  406.         // Tell user how this turn went
  407.         if (plague) {
  408.             plagueCount = pop;
  409.             pop /= 2;
  410.             plagueCount -= pop;
  411.             out.println("Plague! "+plagueCount+ ((plagueCount == 1) ?
  412.                     " person" : " people") +" died, "+starved+" starved,");
  413.               } else
  414.                  out.println("Last year "+starved+((starved == 1) ?
  415.                     " person" : " people") + " starved");
  416.       
  417.             out.println("and "+immigrants+((immigrants == 1) ?
  418.                      " person" : " people") + " entered the city.");
  419.       
  420.           out.println("The population is now "+pop+".");
  421.       
  422.               out.println("We harvested "+harvest+" bushels at "+
  423.                  acreCost+" BPA.");
  424.       
  425.               out.println("Rats ate "+rats+" bushels, leaving "+
  426.                  bushels+".");
  427.       
  428.               out.println("The city owns "+acres+" acres of land.");
  429.       
  430.         acreCost = r.random(6) + 22;
  431.       
  432.               out.println("Land is worth "+acreCost+" an acre.");
  433.       
  434.         updateStatus();
  435.         this.repaint();
  436.     }
  437.  
  438.     /**
  439.      *  Events only checked while playing.
  440.      *  (Presumably none of these events will get hit when not 
  441.      *  playing because the objects won't exist, but this also
  442.      *  makes onEvent look a bit neater.)
  443.      *
  444.      */
  445.     private void playingEvent(Event e) {
  446.               if (e.type == ControlEvent.PRESSED) {
  447.             if (e.target instanceof Button) {    
  448.                 // pressed buttons
  449.                 if (e.target == exitButton)
  450.                              endGame();
  451.                 else if (e.target == doneButton)
  452.                             processTurn();
  453.                 else if (e.target == buyButton)
  454.                     buyAcres();
  455.                 else if (e.target == sellButton)
  456.                     sellAcres();
  457.                 else if (e.target == plantMaxButton)
  458.                     plantMax();
  459.                 else if (e.target == feedNeededButton)
  460.                     feedNeeded();
  461.                 else if (e.target == plantRbButton)
  462.                     plantRb();
  463.                 else if (e.target == feedRbButton)
  464.                     feedRb();
  465.                 else if (e.target == bsMinusButton)
  466.                     modifyBs(-1);
  467.                 else if (e.target == bsPlusButton)
  468.                     modifyBs(1);
  469.                 else if (e.target == feedAcresButton)
  470.                     feedAcres();
  471.                 else if (e.target == plantAvgButton)
  472.                     plantAvg();
  473.  
  474.             }
  475.         }
  476.     }
  477.     
  478.     /**  
  479.          *  Checks for events.  Responsible for updating state of the
  480.          *  game, exiting, acknowledging errors, etc.
  481.           */
  482.     public void onEvent(Event e) {
  483.         if (playing)
  484.             playingEvent(e);  // check playing events
  485.  
  486.               if (e.type == ControlEvent.PRESSED) {
  487.             // check menu items being selected
  488.             if (e.target instanceof Menu) {
  489.                 String sel=((Menu)e.target).getSelected();
  490.                 if (sel.equals("Quit"))    {
  491.                     endGame();
  492.                 } else if (sel.equals("About")) {
  493.                     Dialog id = new Dialog("About",0,80,160,80);
  494.                     id.out.printlnCentered(aboutText);
  495.                     add(id);
  496.                     return;
  497.                 } else if (sel.equals("History")) {
  498.                     Dialog h = new Dialog("History",0,16,160,height-16,historyText);
  499.                     add(h);
  500.                     return;
  501.                 } else if (sel.equals("Help1")) {
  502.                     Dialog h = new Dialog("Help1",0,16,160,height-16,helpText1);
  503.                     add(h);
  504.                     return;
  505.                 } else if (sel.equals("Help2")) {
  506.                     Dialog h = new Dialog("Help2",0,16,160,height-16,helpText2);
  507.                     add(h);
  508.                     return;
  509.                 } else if (sel.equals("Key1")) 
  510.                     add(new Dialog("Key1",0,16,160,height-16,keyText1));
  511.                 else if (sel.equals("Key2"))
  512.                     add(new Dialog("Key2",0,16,160,height-16,keyText2));
  513.                 
  514.             }
  515.         }                
  516.        }
  517.  
  518.  
  519.     /**
  520.      * modify buy/sell acres by i
  521.      *
  522.      */
  523.     private void modifyBs(int i) {
  524.         int v = buysellEdit.getInt();
  525.  
  526.         v += i;
  527.         if (v < 0)
  528.             v = 0;
  529.  
  530.         buysellEdit.setInt(v);
  531.     }
  532.  
  533.     
  534.     /**
  535.      * buy some acres
  536.      *
  537.      */
  538.     private void buyAcres() {
  539.         int value = buysellEdit.getInt();
  540.         if ((value*acreCost) > bushels) 
  541.             showError();
  542.         else {
  543.             bushels -= value*acreCost;
  544.             acres += value;
  545.         }
  546.         updateStatus();
  547.     }
  548.  
  549.  
  550.     /**
  551.      * sell some acres
  552.      *
  553.      */
  554.     private void sellAcres() {
  555.         int value = buysellEdit.getInt();
  556.         if (value > acres)
  557.             showError();
  558.         else {
  559.             bushels += value*acreCost;
  560.             acres -= value;
  561.         }
  562.         // be nice and reduce acres being planted if needed
  563.  
  564.         if (acres < plantEdit.getInt())
  565.             plantEdit.setInt(acres);
  566.         updateStatus();
  567.     }
  568.         
  569.  
  570.     /**
  571.      * plant maximum possible acres
  572.      *
  573.      */
  574.     private void plantMax() {
  575.         int m;
  576.  
  577.         m=pop * PLANT_MAX_PER_PERSON;
  578.  
  579.         if (m>acres)
  580.             m=acres;
  581.  
  582.         plantEdit.setInt(m);
  583.         plantEdit.repaint();
  584.         updateStatus();
  585.     }
  586.         
  587.  
  588.     /**
  589.      * try to feed everybody just enough
  590.      *
  591.      */
  592.     private void feedNeeded() {
  593.         int m;
  594.  
  595.         m = pop * BUSHELS_NEEDED_PER_PERSON;
  596.  
  597.         if (m > bushels)
  598.             m = bushels;
  599.  
  600.         feedEdit.setInt(m);
  601.         feedEdit.repaint();
  602.         updateStatus();
  603.     }
  604.  
  605.  
  606.     /**
  607.      * plant remaining bushels (after bushels used feeding people)
  608.      *
  609.      */
  610.     private void plantRb() {
  611.         int m = ( bushels-feedEdit.getInt() ) * PLANT_ACRES_PER_BUSHEL;
  612.         if (m < 0 )
  613.             m = 0;
  614.         plantEdit.setInt(m);
  615.         plantEdit.repaint();
  616.         updateStatus();
  617.     }
  618.  
  619.         
  620.     /**
  621.      * feed remaining bushels (after bushels used for planting)
  622.      *
  623.      */
  624.     private void feedRb() {
  625.         int m = bushels-(plantEdit.getInt()/PLANT_ACRES_PER_BUSHEL);
  626.  
  627.         if (m < 0 )
  628.             m = 0;
  629.         feedEdit.setInt(m);
  630.         feedEdit.repaint();
  631.         updateStatus();
  632.     }
  633.  
  634.     
  635.     /**
  636.      * feed just enough people to tend all fields
  637.      *
  638.      */
  639.     private void feedAcres() {
  640.         feedEdit.setInt(acres/PLANT_MAX_PER_PERSON*BUSHELS_NEEDED_PER_PERSON);
  641.         feedEdit.repaint();
  642.         updateStatus();
  643.     }
  644.  
  645.  
  646.     /**
  647.      * plant just enough to feed everyone with an avg. yield
  648.      *
  649.      */
  650.     private void plantAvg() {
  651.         plantEdit.setInt((pop*BUSHELS_NEEDED_PER_PERSON)/AVG_YIELD);
  652.         plantEdit.repaint();
  653.         updateStatus();
  654.     }
  655.  
  656.  
  657.     private int calcSurplus() {
  658.         int feed = feedEdit.getInt();
  659.         int plant = plantEdit.getInt();
  660.  
  661.         return bushels-feed-(plant/PLANT_ACRES_PER_BUSHEL);
  662.     }
  663.  
  664.     private void processTurn() {
  665.         int feed = feedEdit.getInt();
  666.         int plant = plantEdit.getInt();
  667.  
  668.                 if (feed > bushels) {
  669.             // trying to feed more bushels than we have
  670.             showError();
  671.             return;
  672.                 }
  673.  
  674.         if (plant > acres   || 
  675.                 plant / PLANT_ACRES_PER_BUSHEL > (bushels-feed) ||
  676.                 plant     > pop * PLANT_MAX_PER_PERSON) {
  677.             // trying to plant more acres than we have, or
  678.             // trying to plant more bushels than we have, or
  679.             // trying to plant more than the population can
  680.             showError();
  681.             return;
  682.         }
  683.             
  684.         
  685.         bushels -= feed;
  686.         starved = pop - feed / BUSHELS_NEEDED_PER_PERSON;
  687.         immigrants = 0;
  688.              
  689.         if (starved < 0) {
  690.             immigrants = -1 * (starved / 2);
  691.             starved = 0;
  692.         }
  693.  
  694.                    // Essentially, the turn's over; update state &
  695.                    // figure out random events (plague): 
  696.             bushels -= plant / PLANT_ACRES_PER_BUSHEL;
  697.                acreCost = r.random(5) + 1;
  698.             harvest = acreCost * plant;
  699.         int p = r.random(MAX_RAT_PCT*10);
  700.                    //ratPop = r.random(600); 
  701.                    //rats = (ratPop * (bushels + harvest)) / 1000; 
  702.         if (hard)
  703.             rats = p * (bushels + harvest) / 1000;
  704.         else
  705.             rats = p * bushels / 1000;
  706.             bushels = bushels - rats + harvest;
  707.                
  708.         //plague = (r.random(10) == 0);
  709.         plague = (r.random(100) < PLAGUE_PCT);
  710.                    immigrants += (5 - acreCost) * bushels / 600 + 1;
  711.                    immigrants = (immigrants > MAX_IMMIGRANTS) ? MAX_IMMIGRANTS : immigrants;
  712.                    immigrants = (immigrants < 0)  ? 0  : immigrants;
  713.                    pop += immigrants - starved;
  714.       
  715.         year ++;
  716.         showReport();
  717.         this.repaint();
  718.        }
  719.        
  720.  
  721.     /**
  722.      *  Game has ended either by user request or naturally.
  723.      *
  724.      *  This is a good place to add final score, saving stats,
  725.      *  that sort of thing.  (But not a saved game.)
  726.      */
  727.     public void endGame () {
  728.         playing = false;
  729.         exit(0);
  730.     }
  731.  
  732.     /**
  733.      *  Exit caught by VM.  This is called after exit(0) in endGame,
  734.      *  so when we get here, we should check the value of playing to
  735.      *  see if we need to save the game.
  736.      *
  737.      */
  738.     public void onExit() {
  739.         if (playing)
  740.             ; // save game
  741.         else
  742.             ; // remove old saved game
  743.     }
  744.  
  745.    /**
  746.     *  Let the player know that something isn't right.  
  747.     */
  748.    private void showError() {
  749.     add(new Dialog("Wabburami, Think Again",0,80,160,80,
  750.         "You do not have enough bushels, acres, or people to do "+
  751.         "as you request."));
  752.    }
  753. }
  754.