Example #1
0
        private Cell[] GetNeighbours(Cell[,] cells, int x, int y, ref int alive) {
            Cell[] neighbours = new Cell[8];

            if (x < FIELD_WIDTH - 1) neighbours[0] = cells[x + 1, y];
            if (y < FIELD_HEIGHT - 1) neighbours[1] = cells[x, y + 1];
            if (x > 0) neighbours[2] = cells[x - 1, y];
            if (y > 0) neighbours[3] = cells[x, y - 1];
            if (x < FIELD_WIDTH - 1 && y < FIELD_HEIGHT - 1) neighbours[4] = cells[x + 1, y + 1];
            if (x > 0 && y > 0) neighbours[5] = cells[x - 1, y - 1];
            if (x < FIELD_WIDTH - 1 && y > 0) neighbours[6] = cells[x + 1, y - 1];
            if (x > 0 && y < FIELD_HEIGHT - 1) neighbours[7] = cells[x - 1, y + 1];

            alive = 0;
            for (int i = 0; i < 8; ++i)
                if (neighbours[i].IsAlive) alive++;

            return neighbours;
        }
Example #2
0
        // Один шаг игры
        private void Step() {
            cells_clone = (Cell[,])cells.Clone();
            Point[] search_p;
            int nalive = 0; // Число активных соседей

            for (int i = 0; i < FIELD_WIDTH; i++)
                for (int c = 0; c < FIELD_HEIGHT; c++) {
                    Cell[] neighbours = GetNeighbours(cells_clone, i, c, ref nalive);

                    if (RegularLife) {
                        if (cells_clone[i, c].IsAlive == false && nalive == 3)
                            cells[i, c].IsAlive = true;
                        else if (cells_clone[i, c].IsAlive && nalive != 2 && nalive != 3)
                            cells[i, c].IsAlive = false;
                    }
                    else {
                        // Если клетка имеет некомфортное число соседей
                        if (cells_clone[i, c].IsAlive && nalive != cells_clone[i, c].PreferedNeighboursNumber &&
                                    nalive != cells_clone[i, c].PreferedNeighboursNumber + 1) {
                            // Координаты окружающих клеток
                            search_p = new Point[] { new Point(i + 1, c),
                                new Point(i - 1, c), new Point(i, c + 1),
                                new Point(i, c - 1), new Point(i + 1, c + 1),
                                new Point(i - 1, c - 1), new Point(i + 1, c - 1),
                                new Point(i - 1, c + 1)};

                            int calive = 0;
                            bool found = false; // Найдена ли подходщая клетка

                            // Просматриваем всех соседей
                            for (int ch = 0; ch < 8; ++ch)
                                try {
                                    // Если любая соседняя клетка имеет допустимое число соседей, перемещаемся в неё
                                    if (cells_clone[search_p[ch].X, search_p[ch].Y].IsAlive == false) {
                                        Cell[] neigh = GetNeighbours(cells_clone, search_p[ch].X, search_p[ch].Y, ref calive);
                                        calive -= 1; // Из соседей убираем текущую клетку
                                        if (calive == cells_clone[i, c].PreferedNeighboursNumber ||
                                            calive == cells_clone[i, c].PreferedNeighboursNumber + 1) {
                                            cells[i, c].IsAlive = false;
                                            cells[search_p[ch].X, search_p[ch].Y] = cells[i, c];
                                            cells[search_p[ch].X, search_p[ch].Y].IsAlive = true;
                                            found = true;
                                            break;
                                        }
                                    }
                                }
                                catch { /* Выход за пределы массива. */ }

                            // Процент смертности
                            int death_percent = (int)deathTrackBar.Value;
                            if (found == false && rnd.Next(0, 101) < death_percent) cells[i, c].IsAlive = false;
                        }
                        else if (cells_clone[i, c].IsAlive == false) {
                            // Процент рождаемости
                            int born_percent = (int)bornTrackBar.Value;

                            if (nalive > 1 && rnd.Next(0, 101) < born_percent) {
                                // Выбираем два несовпадающих соседа
                                int parent1_num = 0, parent2_num = 0;
                                while (neighbours[parent1_num].IsAlive == false) parent1_num = rnd.Next(0, 8);
                                while (neighbours[parent2_num].IsAlive == false || parent1_num == parent2_num)
                                    parent2_num = rnd.Next(0, 8);

                                // Шанс мутации
                                bool mutation = rnd.Next(0, 101) <= 5;

                                // Магия (двойное условное выражение)
                                Cell child = new Cell(
                                    mutation ? rnd.Next(0, 8) :
                                        (rnd.Next(0, 2) == 0) ? neighbours[parent1_num].PreferedNeighboursNumber :
                                        neighbours[parent2_num].PreferedNeighboursNumber,
                                    true);
                                cells[i, c] = child;
                            }
                        }
                    }
                }
            ++countOfSteps;
            stepCountLabel.Text = countOfSteps.ToString();
        }
Example #3
0
 private void GenerateField(bool init) {
     for (int i = 0; i < FIELD_WIDTH; i++)
         for (int c = 0; c < FIELD_HEIGHT; c++)
             cells[i, c] = new Cell(
                 rnd.Next(0, 8), 
                 init ? false :
                     rnd.Next(0, 4) == 0 ? true : false
             );
 }
Example #4
0
 // Возвращает цвет ячейки в зависимости от её любимого кол-ва соседей
 private ColorU GetCellColor(Cell c) {
     switch (c.PreferedNeighboursNumber) {
         case 0: return new ColorU(Color.DarkBlue);
         case 1: return ColorU.Blue;
         case 2: return ColorU.DeepSkyBlue;
         case 3: return ColorU.Green;
         case 4: return ColorU.LimeGreen;
         case 5: return ColorU.Gold;
         case 6: return ColorU.Orange;
         case 7: return ColorU.Red;
         default: return bgColor;
     }
 }