Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.96/75: Рейтинг темы: голосов - 75, средняя оценка - 4.96
29 / 1 / 0
Регистрация: 25.02.2020
Сообщений: 82

Игра "Жизнь"

01.09.2020, 07:01. Показов 16228. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток!
Не могу найти ошибку, игра работает неверно!

Нужно эмитировать жизнь клеток в чаше.
т.е. пользователь задает некоторое количество клеток (отмечает их на поле 10 на 10 клеток, они подсвечиваются черным цветом)
затем нажимаем на кнопку начать, и клетки размножаются и умирают таким образом эмитируя жизнь настоящих клеток.
Правила:
пустая (мертвая) клетка с ровно тремя живыми клетками-соседями оживает;
если у живой клетки есть две или три живые соседки, то эта клетка продолжает жить; в противном случае (если соседок меньше двух или больше трех) клетка умирает (от «одиночества» или от «перенаселенности»).

при запуске игры, на следующие сутки умирают все клетки (т.е. все поле заполнено белыми квадратами)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace Life_Game
{
    public partial class Form1 : Form//сейчас пишем один большой класс Form1
    {
        int n = 10;
        //два массива которые хранят состояние клеток сегодня и завтра
        int[,] today;
        int[,] nextDay;
        public Form1()
        {
            InitializeComponent();//задаем значения для таблицы игры (кол-во столбцов и строк)
            today = new int[n, n];
            nextDay = new int[n, n];
 
            dataGridView1.ColumnCount = n;//для класса DataGridView,вызываем его элемент.вызываем инструмент этого класса и задаем ему значение
            dataGridView1.RowCount = n;
            for (int i = 0; i < n; i++)//размер ячеек будет задан в цикле
            {
                dataGridView1.Columns[i].Width = 30;//для каждого стобца задаем ширину 
                dataGridView1.Rows[i].Height = 30;//для каждой строки задаем высоту
                for (int j = 0; j < n; j++)//заполняем оба массива нулями, чтобы игровое поле изначально было "пустым"
                {
                    today[i, j] = 0;
                    nextDay[i, j] = 0;
                }
            }
        }
 
        private void начатьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            timer1.Enabled=true;
        }
 
        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)//в свойствах элемента DataGridView выбираем события. В событиях для мыши выбираем CellClick
        {
            //если в ячейке на которую кликнули не черный цвет, то сделать его черным
            if (dataGridView1[e.ColumnIndex, e.RowIndex].Style.BackColor != Color.Black)
            {
                dataGridView1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.Black;
                today[e.RowIndex, e.ColumnIndex] = 1;//т.е. при клике на ячейку, ее значение меняется с 0 на 1
            }
            else
            {
                dataGridView1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.White;
                today[e.RowIndex, e.ColumnIndex] = 0;
            }
            //выделенная ячейка подсвечивается синим цветом, для того, чтобы его снять нужно вызвать функцию ClearSelection
            dataGridView1.ClearSelection();
        }
        /*после того, как мы подготовили игровое поле:
        - создали поле 10 на 10 (dataGridView1.ColumnCount=n, dataGridView1.RowCount=n;)
        - научили программу реагировать при клике на ячейку, т.е. менять значение с 0 на 1 и менять цвет ячейки
        - запоминать выбранные пользователем ячейки, сохраняя их в массив today
        Сейчас нужно:
        1. научить программу обрабатывать массив today и сохранять полученный результат в массив nextDay
        2. перенести результаты обработки массива today из массива nextDay обратно в массив today
        3. закрасить в dataGridView1 новые кетки с учетом изменений
         */
        void nextDayGeneration()//в этой функции мы генерируем или прогнозируем как будет выглядеть жизнь на след.день(какие клетки выживут, какие нет)
        {
            int lifeCount = 0;
            int left, right, up, down;
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                {
                    if (i != 0)
                        left = i - 1;
                    else
                        left = n - 1;
                    
                    if (i != n-1)
                        right = i + 1;
                    else
                        right = 0;
 
                    if (j != 0)
                        up = j - 1;
                    else
                        up = n-1;
                    if (j != n-1)
                        down = j + 1;
                    else
                        down = 0;
 
                    lifeCount = today[left, j];
                    lifeCount = today[left, down];
                    lifeCount = today[left, up];
                    lifeCount = today[right, j];
                    lifeCount = today[right, down];
                    lifeCount = today[right, up];
                    lifeCount = today[i, down];
                    lifeCount = today[i, up];
                    //в пер-ю lifeCount подсчитывается сколько у клетки живых соседей (со значением 1)
                    if (lifeCount == 3 && today[i, j] == 0)//если сегодня клетка мертвая (today[i, j]) и соседей у нее 3
                        nextDay[i, j] = 1;
                    else if ((lifeCount < 2 || lifeCount > 3) && today[i, j] == 1)
                        nextDay[i, j] = 0;
                    else
                        nextDay[i, j] = today[i, j];
                } 
        }
        void copuToDay() //ф-ция для 2-го пункта, т.е. после генерации жизни клеток завтрашнего дня, помещаем эти данные в день сегодняшний, т.е. наступило завтра
        {
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    today [i, j] = nextDay[i, j];
        }
        //тепер нужна функция отображения клеток на экране
        void showToGrid()
        {
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                {
                    if (today[i, j] == 1)
                        dataGridView1[j, i].Style.BackColor = Color.Black;
                    else
                        dataGridView1[j, i].Style.BackColor = Color.White;
 
                }
        }
 
        private void остановитьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            timer1.Enabled = false;
        }
 
        private void выходToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }
 
        private void timer1_Tick(object sender, EventArgs e)//в этом методе будет реализация всей программы. Подключаем функции
        {
            //таймер это бесконечный цикл, который повторяет каждую свою итерацию с некоторой здаержкой
            nextDayGeneration();
            copuToDay();
            showToGrid();
        }
    }
}
Добавлено через 20 минут
т.е. визуально должно выглядеть вот так:
https://commons.wikimedia.org/... emblem.gif

Но у меня, после первого шага исчезают все черные клетки и все...а продолжается выполняться программа или нет, я понять не могу, может быть просто не подсвечиваются другие (новые клетки) черным цветом, а может быть они все умирают и по этому не подсвечиваются...

Добавлено через 5 минут
Программа не прекращает свою работу, но новые клетки не отображаются...либо они умирают, либо не подсвечиваются...
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.09.2020, 07:01
Ответы с готовыми решениями:

Игра Жизнь на C#(game of life)
Кто может помочь в создании игры жизнь в С#(game of life)

Игра "Борьба за жизнь": доработать проект
Правила игры: два игрока имеют по n шашек и играют в поле m*m, делая ходы по очереди. Возможные ходы: 1. Переставить свою шашку на...

CSharp и Игра "Жизнь"
Загорелся желанием попробовать C# и решил переписать одну из своих лабораторных Файл программы lab3pr.exe лежит в прикрепленном архиве. ...

4
Фрилансер
 Аватар для Black Fregat
3709 / 2083 / 567
Регистрация: 31.05.2009
Сообщений: 6,683
01.09.2020, 07:29
В конец ShowToGrid добавьте
C#
1
dataGridView1.Refresh();
0
29 / 1 / 0
Регистрация: 25.02.2020
Сообщений: 82
01.09.2020, 11:19  [ТС]
Цитата Сообщение от Black Fregat Посмотреть сообщение
dataGridView1.Refresh();
к сожалению проблема не ушла...
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        void showToGrid()
        {
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                {
                    if (today[i, j] == 1)
                        dataGridView1[j, i].Style.BackColor = Color.Black;
                    else
                        dataGridView1[j, i].Style.BackColor = Color.White;
 
                }
            dataGridView1.Refresh();
 
        }
0
311 / 271 / 118
Регистрация: 05.06.2013
Сообщений: 868
01.09.2020, 13:57
Лучший ответ Сообщение было отмечено m054 как решение

Решение

Главные ошибки:
0. Обнуление переменной lifeCount из 71й строки перенести на место перед 95й строкой, перед подсчётом.
1. В строках с 95 по 102 использовать "+=", а не просто "=".

Второстепенные:
2. dataGridView1.Refresh(); в конец showToGrid() всё же лучше добавить.
3. В "начатьToolStripMenuItem_Click" добавить параметры для таймера и его запуск.
C#
1
2
3
timer1.Enabled = true;
            timer1.Interval = 2000;
            timer1.Start();
4. Вместо 134й строки использовать timer1.Stop();

Улучшения:
5. Что бы понимать идёт процесс или нет можно добавить Label на форму и завести переменную "int day = 0;".
В timer1_Tick добавить:
C#
1
2
label1.Text = "Day " + day;
day++;
После этих действий процесс пошёл и картинка начала меняться.
В логику особо не всматривался, сами проверите не ошиблись ли в расчётах и правильно ли там все "живёт".
1
29 / 1 / 0
Регистрация: 25.02.2020
Сообщений: 82
02.09.2020, 08:03  [ТС]
Спасибо большое, процесс пошел. И про логику верное замечание, работает не корректно, буду править, спасибо!

Добавлено через 1 час 7 минут
Допилил программу!
Может кому пригодится...:
Еще раз спасибо а подсказки
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace Life_Game
{
    public partial class Form1 : Form//сейчас пишем один большой класс Form1
    {
        int n = 10;
        //два массива которые хранят состояние клеток сегодня и завтра
        int[,] today;
        int[,] nextDay;
        public Form1()
        {
            InitializeComponent();//задаем значения для таблицы игры (кол-во столбцов и строк)
            today = new int[n, n];
            nextDay = new int[n, n];
 
            dataGridView1.ColumnCount = n;//для класса DataGridView,вызываем его элемент.вызываем инструмент этого класса и задаем ему значение
            dataGridView1.RowCount = n;
            for (int i = 0; i < n; i++)//размер ячеек будет задан в цикле
            {
                dataGridView1.Columns[i].Width = 30;//для каждого стобца задаем ширину 
                dataGridView1.Rows[i].Height = 30;//для каждой строки задаем высоту
                for (int j = 0; j < n; j++)//заполняем оба массива нулями, чтобы игровое поле изначально было "пустым"
                {
                    today[i, j] = 0;
                    nextDay[i, j] = 0;
                }
            }
        }
 
 
        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)//в свойствах элемента DataGridView выбираем события. В событиях для мыши выбираем CellClick
        {
            //если в ячейке на которую кликнули не черный цвет, то сделать его черным
            if (dataGridView1[e.ColumnIndex, e.RowIndex].Style.BackColor != Color.Black)
            {
                dataGridView1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.Black;
                today[e.RowIndex, e.ColumnIndex] = 1;//т.е. при клике на ячейку, ее значение меняется с 0 на 1
            }
            else
            {
                dataGridView1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.White;
                today[e.RowIndex, e.ColumnIndex] = 0;
            }
            //выделенная ячейка подсвечивается синим цветом, для того, чтобы его снять нужно вызвать функцию ClearSelection
            dataGridView1.ClearSelection();
        }
        /*после того, как мы подготовили игровое поле:
        - создали поле 10 на 10 (dataGridView1.ColumnCount=n, dataGridView1.RowCount=n;)
        - научили программу реагировать при клике на ячейку, т.е. менять значение с 0 на 1 и менять цвет ячейки
        - запоминать выбранные пользователем ячейки, сохраняя их в массив today
        Сейчас нужно:
        1. научить программу обрабатывать массив today и сохранять полученный результат в массив nextDay
        2. перенести результаты обработки массива today из массива nextDay обратно в массив today
        3. закрасить в dataGridView1 новые кетки с учетом изменений
         */
        void nextDayGeneration()//в этой функции мы генерируем или прогнозируем как будет выглядеть жизнь на след.день(какие клетки выживут, какие нет)
        {
            
            int left, right, up, down;
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                {
                    if (i != 0)
                        left = i - 1;
                    else
                        left = n - 1;
                    
                    if (i != n-1)
                        right = i + 1;
                    else
                        right = 0;
 
                    if (j != 0)
                        up = j - 1;
                    else
                        up = n-1;
                    if (j != n-1)
                        down = j + 1;
                    else
                        down = 0;
                    int lifeCount = 0;
                    lifeCount += today[left, j];
                    lifeCount += today[left, down];
                    lifeCount += today[left, up];
                    lifeCount += today[right, j];
                    lifeCount += today[right, down];
                    lifeCount += today[right, up];
                    lifeCount += today[i, down];
                    lifeCount += today[i, up];
                    //в пер-ю lifeCount подсчитывается сколько у клетки живых соседей (со значением 1)
                    if (lifeCount == 3 && today[i, j] == 0)//если сегодня клетка мертвая (today[i, j]) и соседей у нее 3
                        nextDay[i, j] = 1;
                    else if ((lifeCount < 2 || lifeCount > 3) && today[i, j] == 1)
                        nextDay[i, j] = 0;
                    else
                        nextDay[i, j] = today[i, j];
                } 
        }
        private void начатьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }
 
        void copyToDay() //ф-ция для 2-го пункта, т.е. после генерации жизни клеток завтрашнего дня, помещаем эти данные в день сегодняшний, т.е. наступило завтра
        {
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    today [i, j] = nextDay[i, j];
        }
        //тепер нужна функция отображения клеток на экране
        void showToGrid()
        {
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                {
                    if (today[i, j] == 1)
                        dataGridView1[j, i].Style.BackColor = Color.Black;
                    else
                        dataGridView1[j, i].Style.BackColor = Color.White;
 
                }
            dataGridView1.Refresh();
 
        }
 
        private void остановитьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            timer1.Enabled = false;
        }
 
        private void выходToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }
 
        private void timer1_Tick(object sender, EventArgs e)//в этом методе будет реализация всей программы. Подключаем функции
        {
            //таймер это бесконечный цикл, который повторяет каждую свою итерацию с некоторой здаержкой
            nextDayGeneration();//генерируем поле
            copyToDay();//копируем 
            showToGrid();//выводим на экран
        }
      }
    }
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.09.2020, 08:03
Помогаю со студенческими работами здесь

Жизнь студента
Задание: Задане это заменяет &quot;жизнь студента&quot; на неделю, вместо осмысленых предложений используйте бессмысленные сгенерированные,...

Определение состояния соседей в игре в жизнь
Здравствуйте. Пытаюсь сделать свою вариацию игры в жизнь. Она у меня будет довольно маленькой, всего 64 клетки на площади 8Х8. Состояние...

Сколько времени за всю жизнь человек тратит на прием пищи
1. Средний возраст человека 75 лет. Написать программу, которая по указанным количеством приемов пищи в сутки и их продолжительностью...

Написать программу, которая считает сколько спит человек за всю жизнь
Средний возраст человека 75 лет. Написать программу, которая по указанному продолжительностью сна в сутки подсчитывает, сколько времени...

Игра «Жизнь»
Написать программу, демонстрирующую работу с объектами двух типов: O1 – игрок, O2 – автоматический игрок, О3 – рейтинговая таблица...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru