C:\upload\java\Life\source\java\Initializations.java
/*******************************************************************
    This class is really an "information hiding" module that takes
    a "this" pointer from class < Vars > and does the dirty work
    of initializations, preliminary and periodic changes that must
    happen.
******************************************************************** */
 
import java.awt.*;

final class Initializations implements Constants, Strings
{
    private Vars vars; /*  A global variable: a pointer to class < Vars vars >.
                           This holds variables & things like arrays. We only
                           use a few parameters that live in there.
                    */
    private PopupWindow error;  // For exceptions.

/*******************************************************************
    Constructor follows:
******************************************************************** */

    Initializations(Objects objects)
    {
        String errorString = (objects != null) ? 
                             NULL_STRING : "objects = " + objects;
        if (!errorString.equals(NULL_STRING))
        {
            System.out.println("Error, null pointer, Initializations " + errorString);
            return;
        }
        error = new PopupWindow(objects.GetParentFrame(),             // In case
                                objects.GetScreenLocations(),  // of error.
                                ERROR_WINDOW_NAME);
    }

/*******************************************************************
    The next routine sets default values for game constants.

    Note the parameters < boardWidth > and < boardHeight > absolutely
    must have good values.
******************************************************************** */      

    protected void SetDefaults(Vars vars)
    {
        if ((vars.GetBoardWidth() == GARBAGE_VALUE) ||    // Neither of these
            (vars.GetBoardHeight() == GARBAGE_VALUE))     // can happen.
        {
            error.ShowMessage(BOARD_WIDTH_OR_HEIGHT_IS_GARBAGE + ". " +
                              " < Initializations : SetDefaults() >, " + WE_CANNOT_INTERPRET_THIS + ".",
                              OK);          // Button
        }
        else    // All is well.
        {
            // Next three are "default" values:

            vars.SetPixelsPerCell(DEFAULT_PIXELS_PER_CELL);

            /* Note use of < boardWidth > and < boardHeight > is integral 
               to rest of this routine. Everything blows up if it does not
               have a good value.
            */
            vars.SetColumns(vars.GetBoardWidth() /vars.GetPixelsPerCell());   // Integer division -- 
            vars.SetRows(vars.GetBoardHeight()/vars.GetPixelsPerCell());   // gets rounded down.

            // Now we set max and min values on board size:

            vars.SetMaxNumberOfColumns(vars.GetBoardWidth()  / MIN_PIXELS_PER_CELL);// As big 
            vars.SetMaxNumberOfRows(vars.GetBoardHeight() / MIN_PIXELS_PER_CELL);  // as the
                                                            // board can be.
            int rowMaxPixels = vars.GetBoardHeight() / MIN_ROWS;
            int colMaxPixels = vars.GetBoardWidth()  / MIN_COLS;

            vars.SetMaxPixelsPerCell(Math.min(rowMaxPixels, colMaxPixels));
            vars.SetMinPixelsPerCell(MIN_PIXELS_PER_CELL);

            vars.SetMinNumberOfRows(MIN_ROWS);   // As small as the
            vars.SetMinNumberOfColumns(MIN_COLS);   // board can be.
 
            // Now two parameters, default time & default probability.

            vars.SetTimeBetweenGenerations(HALF_SECOND);
            vars.SetProbability(DEFAULT_PROBABILITY_OF_ALIVE);

            // Set a couple booleans that decide how th game is played:

            vars.SetWaitForTimeDelay(true);    /* Assume the user waits for 
                                                 a time delay to go from one
                                                 generation to the next.
                                              */
            vars.SetClickLiveCellsViaMouse(true);     /* Set board 
                                                probalistically 
                        or by clicking on which cells are alive? 
                        Default to clicking.                           */
        }
    }

/*******************************************************************
    Next small utility routine to set variables to initial
    values and pass information to children.

    It instantiates the boards.
******************************************************************** */

    protected void InitializeEveryone(Vars vars, Objects objects)
    {
        // Get local copies of several parameters we need.

        PaintBoardAndComputeNextGeneration 
                paintBoardAndComputeNextGeneration 
                                                = objects.GetPaintBoardAndComputeNextGeneration();
        GenerationNumberCanvas genNum           = objects.GetGenNum();
        BoardUtilities boardUtilities           = objects.GetBoardUtilities();
        ManageBoardCoordinates boardCoordinates = objects.GetBoardCoordinates();

        // Instantiate the playing boards. Double-check values to be sure.

        if ((vars.GetRows() >= vars.GetMinNumberOfRows())       && 
            (vars.GetRows() <= vars.GetMaxNumberOfRows())       &&
            (vars.GetColumns() >= vars.GetMinNumberOfColumns()) && 
            (vars.GetColumns() <= vars.GetMaxNumberOfColumns()))
        {
            vars.MakeBoards();  // All is well. Make the boards.
        }
        else    // Something horrible has happened.
        {
                String errorStr = BAD_VALUES_FOR_ROWS_OR_COLUMNS + " " +
                                  ROWS + " = " + vars.GetRows() + " " + COLUMNS + " = " +
                                  vars.GetColumns() + MUST_HAVE_COLON + 
                                  vars.GetMinNumberOfRows() + 
                              " <= vars.GetRows() <= " +
                              vars.GetMaxNumberOfRows() + AND + ", " + 
                              vars.GetMinNumberOfColumns() +
                              " <= columns <= " + vars.GetMaxNumberOfColumns() + ".";
                error.ShowMessage(errorStr, OK);
        }

        /* A mess of initializations follow. We have to tell our children
           things like the size of the board.
        */
        try // We instantiated all pointers. But one is always careful.
        {
        /* Send the array we use to paintBoard object, who need a 
           pointer to it as it tells us who is "alive" and "dead."
        */
            // Colors to < paintBoard > object:

            paintBoardAndComputeNextGeneration.setAliveColor(COLOR_ALIVE);
            paintBoardAndComputeNextGeneration.setSoonDeadColor(COLOR_SOON_TO_DIE);
            paintBoardAndComputeNextGeneration.setAboutToComeToLifeColor
                                                            (COLOR_ABOUT_TO_COME_TO_LIFE);

            /* Set all boards to null values. The boards < thisGeneration >
               and < nextGeneration > are initialized to zero ("dead"), 
               and the 3-dimensional array *oldBoards* containing old 
               boards to check if we are in a repeating pattern is 
               initialized to a default of -1. Should a repeating pattern 
               happen, we quit; don't go forever.
            */
            NullOutBoards(vars.GetThisGeneration(), 
                                         vars.GetNextGeneration(), 
                                         vars.GetOldBoards());

        }                                       // End "try" block.
        catch (NullPointerException e)
        {
            String whoFailed;
            whoFailed = "" + ((boardUtilities == null) ? " boardUtilities null " : "") +
                        ((boardCoordinates == null) ? " boardCoordinates null " : "") +
                        ((paintBoardAndComputeNextGeneration == null ) ? 
                                                                  "paintBoard null " : "") +
                        ((genNum == null) ? " genNum null " : "") + ".";

            error.ShowMessage(POINTER_NULL +
                             "<  Initializations() initializeEveryone >?!?! " + 
                             whoFailed, OK);
        }
    }   // End < initializeEveryone>.

/* ******************************************************************
    The next sets the board probalistically.
********************************************************************* */     
    
    protected final void Probalistic(int [][] board,
                                     int p,         // Note this
                                                    // is an int, 
                                                    // 1 -- 100.
                                     int rows, int columns)
    {
        int i = 0;  // Avoid "may not have been initialized"
        int j = 0;  // errors in try-catch clause.
        
        try
        {
            // We pass in bounds as the edges are always zero -- 
            // don't touch them.
            for (i = 1; i <= rows; i++)
            {
                for (j = 1; j <= columns; j++)
                {
                    if (Math.random() <= (float) (p) / 100) // Note cast
                                                        // of int to float.
                    {
                        board[i][j] = 1;
                    }
                    else
                    {
                        board[i][j] = 0;
                    }
                }  
            }
        }
        catch (ArrayIndexOutOfBoundsException e)    // Array index out of bounds!?
        {
            String errorStr = e.getMessage();
            errorStr = errorStr + 
                       ARRAY_BOUNDS_EXCEPTION + " routine Probalistic: " +
                                  " " + ROWS + " = " + rows + 
                                  COLUMNS + " = " + columns +
                                  ", i = " + i + ", and j = " + j;
            error.ShowMessage(errorStr, OK);
        }
    }

/* ******************************************************************
    The next three set boards to default values. 
    
    Note the function is overloaded.

    Notably, this is overloaded because the main code may print out
    examples for the user. We don't care about keeping track of old
    versions in this case.
   ****************************************************************** */
   
   protected final void NullOutOldBoards(Vars vars)
    {
        int [][][] oldBoards = vars.GetOldBoards();

        for (int k = 0; k < oldBoards.length; k++)
        {
            for (int i = 0; i < oldBoards[0].length; i++)
            {
                for (int j = 0; j < oldBoards[0][0].length; j++)
                {
                    oldBoards[k][i][j] = GARBAGE_VALUE;
                }
            }
        }
    }       // End < NullOutOldBoards >.

/* ******************************************************************
    First: only A and B.
   ****************************************************************** */ 

    protected final void NullOutBoards(int[][] A, int [][] B)
    {
        nullBoards(A, B, null);   // No oldBoards. Null.
    }

/* ******************************************************************
    Second: A, B and oldBoards.
********************************************************************* */ 

    protected final void NullOutBoards(int [][] A, int [][] B, 
                                       int [][][] oldBoards)
    {
        nullBoards(A, B, oldBoards);
    }       // End routine < NullOutBoards >.

/* ******************************************************************
    Routine < nullBoards >. This does the real dirty work of nulling
    out the boards, for both constructors.
   ****************************************************************** */ 

    private final void nullBoards(int [][] A, int [][] B,
                                  int [][][] oldBoards)
    {
        int i, j, k;    // Loop variables.
        
        boolean dimensionsMakeSense = ((A.length == B.length) && 
                                       (A[0].length == B[0].length ));

        // This is called from overloaded routines that may feed us a
        // legit parameter of < oldBoards >, or a null value.

        if (oldBoards != null)
        {
            dimensionsMakeSense &= (A.length == oldBoards[0].length) &&
                                    (A[0].length == oldBoards[0][0].length);
        }
        if (!dimensionsMakeSense)   // Big problems. Dimensions don't
                                   // make sense.
        {
            String errorString = "Routine < nullBoards >, class " +
                                 "BoardUtilities.java: " +
                                 DIMENSIONS_OF_BOARD_DO_NOT_MAKE_SENSE +
                                 "A.length = " + A.length + 
                                 "; B.length = " + B.length +
                                 "A[0].length = " + A[0].length + "; B[0].length = " +
                                  B[0].length + ".";
            if (oldBoards != null)
            {
                errorString += AND + "oldBoards[0].length = " + 
                                oldBoards[0].length + 
                               "; oldBoards[0][0].length = " + 
                               oldBoards[0][0].length + ".";
            }
            error.ShowMessage(errorString, OK);
        }
        else    // Dimensions are good.
        {
            for (i = 0; i < A.length; i++)
            {
                for (j = 0; j < A[0].length; j++)
                {
                    A[i][j] = B[i][j] = 0;

                    if (oldBoards != null)  // Look at overloaded routine < NullOutBoards >
                                            // above for wh we do this check.
                    {
                        // Do oldboards in "slices":

                        for (k = 0; k < oldBoards.length; k++)
                        {
                            oldBoards[k][i][j] = GARBAGE_VALUE; 
                        }// End k-loop
                    }    // End "if (oldBoards != null)" clause.
                }        // End j-loop.
            }            // End i-loop.
        }                // End "else" clause.
    }                    // End < private void nullBoards >.
}