private void AnalyseCell(GridCellMembership me, int x, int y, ref int totalNeighbourCount, ref int newSourceDistance, ref GridCellMembership support, ref int occupyCount, ref GridCellMembership attack)
        {
            if (wrapMode == GameWrapMode.Donut)
            {
                x = (x + tileCountX) % tileCountX;
                y = (y + tileCountY) % tileCountY;
            }

            totalNeighbourCount++;

            if (me.Fraction != null && _grid[x, y].Fraction == me.Fraction && _grid[x, y].SourceDistance + 1 < newSourceDistance)
            {
                newSourceDistance = _grid[x, y].SourceDistance + 1;
            }

            if (_grid[x, y].Fraction != null && me.Fraction == _grid[x, y].Fraction && _grid[x, y].SourceDistance <SRC_DIST_INF && _grid[x, y].PowerCurr> MIN_TRANSFER_POWER && (support == null || support.SourceDistance > _grid[x, y].SourceDistance))
            {
                support = _grid[x, y];
            }

            if (_grid[x, y].Fraction != null && !_grid[x, y].Fraction.IsNeutral)
            {
                occupyCount++;
            }

            if (_grid[x, y].Fraction != null && me.Fraction != _grid[x, y].Fraction && _grid[x, y].SourceDistance <SRC_DIST_INF && _grid[x, y].PowerCurr> MIN_TRANSFER_POWER && (attack == null || attack.SourceDistance > _grid[x, y].SourceDistance))
            {
                attack = _grid[x, y];
            }
        }
        private void Initialize()
        {
            for (int x = 0; x < tileCountX; x++)
            {
                for (int y = 0; y < tileCountY; y++)
                {
                    _grid[x, y] = new GridCellMembership();
                    _grid[x, y].DifficultyMod = 1 + FloatMath.Sin(FloatMath.GetRandom() * FloatMath.RAD_POS_360) * RANDOM_MOD_FACTOR;

                    if (wrapMode != GameWrapMode.Donut)
                    {
                        if (x == 0)
                        {
                            _grid[x, y].BlockWest = true;
                        }
                        if (y == 0)
                        {
                            _grid[x, y].BlockNorth = true;
                        }
                        if (x == tileCountX - 1)
                        {
                            _grid[x, y].BlockEast = true;
                        }
                        if (y == tileCountY - 1)
                        {
                            _grid[x, y].BlockSouth = true;
                        }
                    }
                }
            }
        }
        private void UpdateCell(int x, int y, SAMTime gameTime)
        {
            GridCellMembership me = _grid[x, y];

            int totalNeighbourCount = 0;
            int newSourceDistance   = SRC_DIST_INF;

            int occupyCount            = 0;
            GridCellMembership support = null;
            GridCellMembership attack  = null;

            if (!_grid[x, y].BlockNorth)
            {
                AnalyseCell(me, x + 0, y - 1, ref totalNeighbourCount, ref newSourceDistance, ref support, ref occupyCount, ref attack);
            }
            if (!_grid[x, y].BlockEast)
            {
                AnalyseCell(me, x + 1, y + 0, ref totalNeighbourCount, ref newSourceDistance, ref support, ref occupyCount, ref attack);
            }
            if (!_grid[x, y].BlockSouth)
            {
                AnalyseCell(me, x + 0, y + 1, ref totalNeighbourCount, ref newSourceDistance, ref support, ref occupyCount, ref attack);
            }
            if (!_grid[x, y].BlockWest)
            {
                AnalyseCell(me, x - 1, y + 0, ref totalNeighbourCount, ref newSourceDistance, ref support, ref occupyCount, ref attack);
            }

            if (totalNeighbourCount == 0)
            {
                // pathological Case
                me.SourceDistance = SRC_DIST_INF;
                me.Fraction       = null;
                me.PowerNext      = 0f;
                return;
            }

            // [1] update SourceDistance

            if (newSourceDistance <= _grid[x, y].SourceDistance)
            {
                _grid[x, y].SourceDistance = newSourceDistance;
            }
            else
            {
                _grid[x, y].SourceDistance = SRC_DIST_INF;
            }


            // [2] update Power

            if (support == null && attack == null)
            {
                if (occupyCount < totalNeighbourCount)
                {
                    // border of unsupported island
                    DrainPower(x, y, gameTime.ElapsedSeconds * CELL_DECAY_SPEED);
                }
                else
                {
                    // center of unsupported island
                }
            }
            else if (support != null && attack == null)
            {
                //improv agains none
                GainPower(support.Fraction, x, y, gameTime.ElapsedSeconds * CELL_OCCUPY_SPEED);
            }
            else if (support != null && attack != null && attack.SourceDistance > support.SourceDistance)
            {
                //improv against enemy
                GainPower(support.Fraction, x, y, gameTime.ElapsedSeconds * CELL_ATTACK_SPEED);
            }
            else if (support == null && attack != null)
            {
                //loose with no support
                GainPower(attack.Fraction, x, y, gameTime.ElapsedSeconds * CELL_DECAY_SPEED);
            }
            else if (support != null && attack != null && attack.SourceDistance < support.SourceDistance)
            {
                //loose with against enemy
                GainPower(attack.Fraction, x, y, gameTime.ElapsedSeconds * CELL_ATTACK_SPEED);
            }
            else if (support != null && attack != null && attack.SourceDistance == support.SourceDistance)
            {
                //contested cell
                if (_grid[x, y].PowerCurr > MIN_NEUTRALIZE_POWER || _grid[x, y].IsNeutralDraining)
                {
                    // drain
                    _grid[x, y].IsNeutralDraining = true;
                    GainPower(attack.Fraction, x, y, gameTime.ElapsedSeconds * CELL_NEUTRALIZE_SPEED);
                }
                else
                {
                    //gain
                    GainPower(support.Fraction, x, y, gameTime.ElapsedSeconds * CELL_NEUTRALIZE_SPEED);
                }
            }
        }