Example #1
0
        // Adds a MovementSegment to all the proper cells in the grid to account for the creature's size by wrapping it
        // with a SegmentWrapper and adding the wrapper to the proper cells. When we calculate a creature's movement we have
        // to mark all the cells in a square around the center that their size covers as occupied.  This function reserves
        // all the cells that a given segment would cover for a creature.
        internal void AddSegment(MovementSegment segment)
        {
            // Figure out how many cells on either side of the center we need to reserve
            var cellRadius = segment.State.CellRadius;

            if (segment.Previous == null)
            {
                // Beginning of a segment
                // We should have never started in a position where the radius of the organism
                // went outside the bounds of the universe
                Debug.Assert(segment.GridX >= 0 && segment.GridY >= 0 &&
                             segment.GridX - cellRadius >= 0 &&
                             segment.GridY - cellRadius >= 0 &&
                             segment.GridX + cellRadius < GameEngine.Current.GridWidth &&
                             segment.GridY + cellRadius < GameEngine.Current.GridHeight);

                Debug.Assert(segment.EntryTime == 0);
                StartSegments.Add(segment);
            }
            else
            {
                Debug.Assert(segment.EntryTime != 0);
                // If this segment pushes the organisms radius outside the bounds of the universe, clip it now
                // and don't bother evaluating it later
                if (segment.GridX < 0 || segment.GridY < 0 ||
                    segment.GridX - cellRadius < 0 ||
                    segment.GridY - cellRadius < 0 ||
                    segment.GridX + cellRadius > GameEngine.Current.GridWidth - 1 ||
                    segment.GridY + cellRadius > GameEngine.Current.GridHeight - 1)
                {
                    segment.Previous.Next = null;
                    return;
                }
            }

            // Do the top and bottom rows
            ArrayList list;
            SegmentWrapper wrapper;
            for (var x = segment.GridX - cellRadius; x <= segment.GridX + cellRadius; x++)
            {
                // *** Top row of square ***
                // Make a unique hash for every square in the grid
                var hash = (x << 16) | (segment.GridY - cellRadius);

                // retrieve the set of SegmentWrappers that are already in the cell of the grid
                list = (ArrayList) _gridSquares[hash];
                if (list == null)
                {
                    // None exist yet, create an ArrayList to hold them
                    list = new ArrayList();
                    _gridSquares[hash] = list;
                }

                // Make sure two organisms didn't start in the same place
                Debug.Assert(segment.EntryTime != 0 || !HasStartingSegments(list));

                // Create a wrapper for this segment, give it a backpointer to the arraylist that contains
                // all the segments in this cell
                wrapper = new SegmentWrapper(segment, list);

                // Add the SegmentWrapper itself to the list of segments in this cell
                list.Add(wrapper);

                // Now add the SegmentWrapper to our master sorted list of all SegmentWrappers anywhere
                _sortedList.Add(wrapper);

                // CellsLeftToResolve is there to recognize the fact that an animal overlaps many squares.
                // Until you know that it can occupy all of the squares it moves into, it can't move into
                // any of them.  This property keeps track of whether we have resolved them all or not.
                // Here, we are adding one to it for every cell we occupy with this segment.
                segment.CellsLeftToResolve++;

                // *** Bottom row of square ***
                hash = (x << 16) | (segment.GridY + cellRadius);
                list = (ArrayList) _gridSquares[hash];
                if (list == null)
                {
                    list = new ArrayList();
                    _gridSquares[hash] = list;
                }

                // Make sure two organisms didn't start in the same place
                Debug.Assert(segment.EntryTime != 0 || !HasStartingSegments(list));
                wrapper = new SegmentWrapper(segment, list);
                list.Add(wrapper);
                _sortedList.Add(wrapper);
                segment.CellsLeftToResolve++;
            }

            // Do left and right columns
            for (var y = segment.GridY - cellRadius + 1; y <= segment.GridY + cellRadius - 1; y++)
            {
                // Make a unique hash for every square in the grid
                var hash = ((segment.GridX - cellRadius) << 16) | y;
                list = (ArrayList) _gridSquares[hash];
                if (list == null)
                {
                    list = new ArrayList();
                    _gridSquares[hash] = list;
                }
                // Make sure two organisms didn't start in the same place
                Debug.Assert(segment.EntryTime != 0 || !HasStartingSegments(list));
                wrapper = new SegmentWrapper(segment, list);
                list.Add(wrapper);
                _sortedList.Add(wrapper);
                segment.CellsLeftToResolve++;

                hash = ((segment.GridX + cellRadius) << 16) | y;
                list = (ArrayList) _gridSquares[hash];
                if (list == null)
                {
                    list = new ArrayList();
                    _gridSquares[hash] = list;
                }
                // Make sure two organisms didn't start in the same place
                Debug.Assert(segment.EntryTime != 0 || !HasStartingSegments(list));
                wrapper = new SegmentWrapper(segment, list);
                list.Add(wrapper);
                _sortedList.Add(wrapper);
                segment.CellsLeftToResolve++;
            }
        }
Example #2
0
        // Adds a MovementSegment to all the proper cells in the grid to account for the creature's size by wrapping it
        // with a SegmentWrapper and adding the wrapper to the proper cells. When we calculate a creature's movement we have
        // to mark all the cells in a square around the center that their size covers as occupied.  This function reserves
        // all the cells that a given segment would cover for a creature.
        internal void AddSegment(MovementSegment segment)
        {
            // Figure out how many cells on either side of the center we need to reserve
            var cellRadius = segment.State.CellRadius;

            if (segment.Previous == null)
            {
                // Beginning of a segment
                // We should have never started in a position where the radius of the organism
                // went outside the bounds of the universe
                Debug.Assert(segment.GridX >= 0 && segment.GridY >= 0 &&
                             segment.GridX - cellRadius >= 0 &&
                             segment.GridY - cellRadius >= 0 &&
                             segment.GridX + cellRadius < GameEngine.Current.GridWidth &&
                             segment.GridY + cellRadius < GameEngine.Current.GridHeight);

                Debug.Assert(segment.EntryTime == 0);
                StartSegments.Add(segment);
            }
            else
            {
                Debug.Assert(segment.EntryTime != 0);
                // If this segment pushes the organisms radius outside the bounds of the universe, clip it now
                // and don't bother evaluating it later
                if (segment.GridX < 0 || segment.GridY < 0 ||
                    segment.GridX - cellRadius < 0 ||
                    segment.GridY - cellRadius < 0 ||
                    segment.GridX + cellRadius > GameEngine.Current.GridWidth - 1 ||
                    segment.GridY + cellRadius > GameEngine.Current.GridHeight - 1)
                {
                    segment.Previous.Next = null;
                    return;
                }
            }

            // Do the top and bottom rows
            ArrayList      list;
            SegmentWrapper wrapper;

            for (var x = segment.GridX - cellRadius; x <= segment.GridX + cellRadius; x++)
            {
                // *** Top row of square ***
                // Make a unique hash for every square in the grid
                var hash = (x << 16) | (segment.GridY - cellRadius);

                // retrieve the set of SegmentWrappers that are already in the cell of the grid
                list = (ArrayList)_gridSquares[hash];
                if (list == null)
                {
                    // None exist yet, create an ArrayList to hold them
                    list = new ArrayList();
                    _gridSquares[hash] = list;
                }

                // Make sure two organisms didn't start in the same place
                Debug.Assert(segment.EntryTime != 0 || !HasStartingSegments(list));

                // Create a wrapper for this segment, give it a backpointer to the arraylist that contains
                // all the segments in this cell
                wrapper = new SegmentWrapper(segment, list);

                // Add the SegmentWrapper itself to the list of segments in this cell
                list.Add(wrapper);

                // Now add the SegmentWrapper to our master sorted list of all SegmentWrappers anywhere
                _sortedList.Add(wrapper);

                // CellsLeftToResolve is there to recognize the fact that an animal overlaps many squares.
                // Until you know that it can occupy all of the squares it moves into, it can't move into
                // any of them.  This property keeps track of whether we have resolved them all or not.
                // Here, we are adding one to it for every cell we occupy with this segment.
                segment.CellsLeftToResolve++;

                // *** Bottom row of square ***
                hash = (x << 16) | (segment.GridY + cellRadius);
                list = (ArrayList)_gridSquares[hash];
                if (list == null)
                {
                    list = new ArrayList();
                    _gridSquares[hash] = list;
                }

                // Make sure two organisms didn't start in the same place
                Debug.Assert(segment.EntryTime != 0 || !HasStartingSegments(list));
                wrapper = new SegmentWrapper(segment, list);
                list.Add(wrapper);
                _sortedList.Add(wrapper);
                segment.CellsLeftToResolve++;
            }

            // Do left and right columns
            for (var y = segment.GridY - cellRadius + 1; y <= segment.GridY + cellRadius - 1; y++)
            {
                // Make a unique hash for every square in the grid
                var hash = ((segment.GridX - cellRadius) << 16) | y;
                list = (ArrayList)_gridSquares[hash];
                if (list == null)
                {
                    list = new ArrayList();
                    _gridSquares[hash] = list;
                }
                // Make sure two organisms didn't start in the same place
                Debug.Assert(segment.EntryTime != 0 || !HasStartingSegments(list));
                wrapper = new SegmentWrapper(segment, list);
                list.Add(wrapper);
                _sortedList.Add(wrapper);
                segment.CellsLeftToResolve++;

                hash = ((segment.GridX + cellRadius) << 16) | y;
                list = (ArrayList)_gridSquares[hash];
                if (list == null)
                {
                    list = new ArrayList();
                    _gridSquares[hash] = list;
                }
                // Make sure two organisms didn't start in the same place
                Debug.Assert(segment.EntryTime != 0 || !HasStartingSegments(list));
                wrapper = new SegmentWrapper(segment, list);
                list.Add(wrapper);
                _sortedList.Add(wrapper);
                segment.CellsLeftToResolve++;
            }
        }