Ejemplo n.º 1
0
        internal int CompareTo(LifeRow rowTarget
                               , int ixBegin, int ixEnd)
        {
            //	Overloaded version.  Specifies a
            //		begin and end for the range of
            //		cells to compare.

            if (rowTarget == null)
            {
                return(1);
            }

            for (int j = ixBegin; j <= ixEnd; j++)
            {
                if (cellsRow[j] == rowTarget.cellsRow[j])
                {
                    continue;
                }
                if (cellsRow[j] < rowTarget.cellsRow[j])
                {
                    return(-1);
                }
                if (cellsRow[j] > rowTarget.cellsRow[j])
                {
                    return(+1);
                }
            }
            return(0);
        }
Ejemplo n.º 2
0
        internal int CompareTo(LifeRow rowTarget)
        {
            //	CompareTo tradionally returns three
            //		possible values, 0 (==), -1 (<)
            //		and +1 (>); and we wish to
            //		maintain that convention.  But,
            //		for a row, only "==" and "!="
            //		is meaningful.  So the definition
            //		of "<" and ">" is somewhat arbitrary
            //		here.
            //	The definition of "<" and ">" in
            //		this code sequence is optimized
            //		for performance, given that
            //		most CompareTo calls will be
            //		comparing the Nth row of one
            //		generation to the Nth row of
            //		an adjacent generation.
            //	"Equal" means identical values in
            //		cells of equal index values for
            //		all possible index values.

            if (rowTarget == null)
            {
                return(1);
            }

            if (this.noofLive == 0 && rowTarget.noofLive == 0)
            {
                return(0);
            }

            if (this.noofLive < rowTarget.noofLive)
            {
                return(-1);
            }
            if (this.noofLive > rowTarget.noofLive)
            {
                return(1);
            }

            for (int j = lo; j <= hi; j++)
            {
                if (cellsRow[j] == rowTarget.cellsRow[j])
                {
                    continue;
                }
                if (cellsRow[j] < rowTarget.cellsRow[j])
                {
                    return(-1);
                }
                if (cellsRow[j] > rowTarget.cellsRow[j])
                {
                    return(+1);
                }
            }
            return(0);
        }
Ejemplo n.º 3
0
 internal void Clear()
 {
     //	Clear this generation.
     for (int j = lo; j <= hi; j++)
     {
         Rows[j] = new LifeRow();
     }
     countGeneration = 0;
 }
Ejemplo n.º 4
0
        internal void CopyTo(LifeRow rowTarget)
        {
            //	Check for null reference.
            if (rowTarget == null)
            {
                return;
            }

            //	Copy the relevant info from row to row.
            this.cellsRow.CopyTo(rowTarget.cellsRow, 0);
            rowTarget.noofLive = this.noofLive;
        }
Ejemplo n.º 5
0
        // Constructor.
        internal LifeGeneration()
        {
            //	Set the convenience fields.
            lo     = Rows.GetLowerBound(0);
            hi     = Rows.GetUpperBound(0);
            middle = lo + ((hi - lo) / 2);

            //	Create the rows.
            for (int j = lo; j <= hi; j++)
            {
                Rows[j] = new LifeRow();
            }
        }
Ejemplo n.º 6
0
        internal LifeRow CalcNextGen(LifeRow rowAbove, LifeRow rowBelow)
        {
            //	Create an empty row.
            LifeRow rowNextGen = new LifeRow();

            //	If this row and the row above
            //		and the row below are all
            //		empty, then the next generation
            //		will be an empty row.
            if (this.noofLive == 0 && rowAbove.noofLive == 0 && rowBelow.noofLive == 0)
            {
                return(rowNextGen);
            }

            //	For each cell in the row:
            //		(Leave the end cells blank.)
            int workSum;

            for (int j = lo + 1; j <= hi - 1; j++)
            {
                //	Sum the number of adjacent live cells.
                workSum =
                    +cellsRow[j - 1]
                    + cellsRow[j + 1]
                    + rowAbove.cellsRow[j - 1]
                    + rowAbove.cellsRow[j]
                    + rowAbove.cellsRow[j + 1]
                    + rowBelow.cellsRow[j - 1]
                    + rowBelow.cellsRow[j]
                    + rowBelow.cellsRow[j + 1];

                //	Any cell with three live neighbors
                //		will become/remain a live cell.
                //		Any live	cell with two live
                //		neighbors will remain a live cell.
                rowNextGen.cellsRow[j] = (byte)
                                         ((workSum == 3 ||
                                           (cellsRow[j] == 1 && workSum == 2))
               ? 1 : 0);

                // Increment the live cell count,
                //		as appropriate.
                rowNextGen.noofLive += rowNextGen.cellsRow[j];
            }
            return(rowNextGen);
        }
Ejemplo n.º 7
0
        // Draw the current row.
        internal void DrawRow(
            LifeRow rowCurr,
            LifeRow rowPrev,
            int ixRow,
            Graphics graphLifeGame)
        {
            // Calculate the range of rows to display.
            int displaySpan = LifeMain.noofDisplay;
            int displayLo   = rowCurr.middle - ((displaySpan - 1) / 2);
            int displayHi   = displayLo + (displaySpan - 1);

            // Drawing tools
            int xUnit =
                (int)(this.ClientRectangle.Width / displaySpan);
            int yUnit =
                (int)(this.ClientRectangle.Height / displaySpan);
            SolidBrush brshLive = new SolidBrush(Color.Black);
            SolidBrush brshDead = new SolidBrush(Color.Tan);

            // This routine attemps to optimize the
            //    drawing of rows.  Rows are drawn
            //    using FillRect.  The three primary
            //    optimizations are:
            // 1.   Do not erase the background.
            // 2.   Draw contiguous cells of the same
            //      state (color) in a single FillRect
            //      call.
            // 3.   Do not call FillRect if the rectangle
            //      specified is already the correct
            //      color.  That is, if there is no
            //      change in the range of cells since
            //      the previous generation.

            int ixStart      = displayLo  // The left cell of the rect.
            , ixEnd          = displayHi  // The right cell of the rect.
            , j              = displayLo; // The current cell.
            byte byteCurrent = rowCurr.cellsRow[displayLo];

            // Force the last cell of a row to end a rectangle.
            byte cellTemp = rowCurr.cellsRow[displayHi];

            rowCurr.cellsRow[displayHi] = 2;

            // Scan from the end of the previous rectangle until
            //    a change in cell value occurs, indicating the
            //    need for a new rectangle.
            for (j = displayLo; j <= displayHi; j++)
            {
                if (rowCurr.cellsRow[j] != byteCurrent)
                {
                    // Note the end of the rectangle.
                    ixEnd = j - 1;

                    // Only call FillRect if nexessary.
                    if (LifeMain.boolPaintAll ||
                        rowCurr.CompareTo(rowPrev, ixStart, ixEnd) != 0)
                    {
                        graphLifeGame.FillRectangle(
                            byteCurrent == 1 ? brshLive : brshDead,
                            (ixStart - displayLo) * xUnit,
                            (ixRow - displayLo) * yUnit,
                            ((ixEnd - ixStart) + 1) * xUnit,
                            1 * yUnit);
                    }

                    // Note the start of the next rectangle.
                    ixStart = j;
                    // Note the value of the new rectangle's
                    //    starting cell.
                    byteCurrent = rowCurr.cellsRow[j];
                }
            }

            // Restore the last cell to its origional value.
            rowCurr.cellsRow[displayHi] = cellTemp;
        }