Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Timers;
- using System.Drawing;
- using System.Windows.Forms;
- namespace WindowsFormsApplication2
- {
- public partial class Form1 : Form
- {
- Button modeBut;
- static System.Timers.Timer myTimer; //таймер, который решает судьбу клеток
- const int L = 26, H = 26; //длина и высота одной клетки
- float A = 0, B = 0; //количество клеток в экране приложения по горизонтали и вертикали
- int[,] start = new int[22, 2] { {6, 6}, {6, 7}, {6, 8}, {6, 9}, {6, 10}, {6, 11}, {6, 12}, {6, 13},
- {7, 6}, {7, 8}, {7, 9}, {7, 10}, {7, 11}, {7, 13},
- {8, 6}, {8, 7}, {8, 8}, {8, 9}, {8, 10}, {8, 11}, {8, 12}, {8, 13} }; //живые клетки в начале игры
- int[,,] present, future; //массивы хранят карту живых/мёртвых клеток
- BufferedGraphicsContext myContext; //двойная буферизация
- BufferedGraphics myBuffer;
- bool setup = true;
- public Form1()
- {
- InitializeComponent();
- }
- private void TimerEventProcessor(Object myObject, //решаем судьбу жизни/смерти клеток
- EventArgs myEventArgs)
- {
- Array.Copy(future, present, (int)(A) * (int)(B)*3); //меняем массивы местами. Будущее становится настоящим!
- Draw_All(present); //рисуем в буфере
- myBuffer.Render(); //копируем изображение из буфера на экран
- // myBuffer.Dispose();
- // myContext.Dispose();
- //теперь мы расчитываем следующий шаг
- for (int i = 0; i <= A - 1; i++) //проверяем каждую клетку
- for (int j = 0; j <= B - 1; j++) //внимание! массив начинается с нуля!
- {
- int neighbour = 0; //вычисляем число соседей у данной клетки
- //и следим, чтобы не обращаться за пределы массива
- if ((i > 0) && (j > 0) && (present[i - 1, j - 1, 0] == 1)) neighbour++;
- if ((j > 0) && (present[i, j - 1, 0] == 1)) neighbour++;
- if ((i < A - 1) && (j > 0) && (present[i + 1, j - 1, 0] == 1)) neighbour++;
- if ((i > 0) && present[i - 1, j, 0] == 1) neighbour++;
- if ((i < A - 1) && present[i + 1, j, 0] == 1) neighbour++;
- if ((i > 0) && (j < B - 1) && present[i - 1, j + 1, 0] == 1) neighbour++;
- if ((j < B - 1) && present[i, j + 1, 0] == 1) neighbour++;
- if ((i < A - 1) && (j < B - 1) && present[i + 1, j + 1, 0] == 1) neighbour++;
- //if (neighbour != 0) Text = neighbour.ToString();
- //число соседей известно -
- if (neighbour < 2) future[i, j, 0] = 0; //применяем правила Игры Конвея
- else
- if (((neighbour == 2) || (neighbour == 3)) && present[i, j, 0] == 1) future[i, j, 0] = 1;
- else
- if (neighbour > 3) future[i, j, 0] = 0;
- else
- if (neighbour == 3) future[i, j, 0] = 1;
- //на этом месте массив future полностью заполнен и готов поменяться местами с present
- }
- }
- public void Draw_All(int[,,] array) //процедура рисует все клетки
- {
- for (int i = 0; i < A - 1; i++) //внимание! массив начинается с нуля!
- for (int j = 0; j < B - 1; j++)
- {
- Rectangle Rect = new Rectangle(0 + i * L, 0 + j * H, L , H );
- myBuffer.Graphics.FillRectangle(Brushes.LightGray, Rect); //рисуем серую сетку
- Rect = new Rectangle(0 + i * L + 2, 0 + j * L + 2, L-4, H-4);
- if (array[i, j, 0] == 0) myBuffer.Graphics.FillRectangle(Brushes.White, Rect); //рисуем чёрную или белую клетку в сетке
- else myBuffer.Graphics.FillRectangle(Brushes.Black, Rect);
- }
- }
- public void All_Dead(int[,,] array) //процедура делает клетки мёртвыми, но не рисует их
- {
- for (int i = 0; i < A - 1; i++) //внимание! массив начинается с нуля!
- for (int j = 0; j < B - 1; j++)
- {
- array[i, j, 0] = 0; //определяем, что клетка мертва
- array[i, j, 1] = 0 + i * L; //записываем координату X клетки
- array[i, j, 2] = 0 + j * H; //записываем координату Y клетки
- }
- }
- public void Alive(int l, int h) //делаем заданную клетку в массиве future живой
- {
- Rectangle Rect = new Rectangle(l*L, h*H, L, H); //рисуем серую сетку вокруг клетки
- myBuffer.Graphics.FillRectangle(Brushes.LightGray, Rect);
- Rect = new Rectangle(l*L + 2, h*H + 2, L -4, H -4); //рисуем саму клетку внутри сетки
- myBuffer.Graphics.FillRectangle(Brushes.Black, Rect);
- future[l, h, 0] = 1; //клетка ЖИВА!
- }
- public void Dead(int l, int h) //делаем заданную клетку в массиве future мёртвой
- {
- Rectangle Rect = new Rectangle((l + 1) * L, (h + 1) * H, L, H); //рисуем серую сетку вокруг клетки
- myBuffer.Graphics.FillRectangle(Brushes.LightGray, Rect);
- Rect = new Rectangle((l + 1) * L + 2, (h + 1) * H + 2, L - 4, H - 4); //рисуем саму клетку внутри сетки
- myBuffer.Graphics.FillRectangle(Brushes.White, Rect);
- future[l, h, 0] = 0; //клетка уже не жива
- }
- private void Form1_Shown(object sender, EventArgs e) //исполняется при запуске приложения
- {
- myContext = new BufferedGraphicsContext(); //двойная буферизация
- myBuffer = myContext.Allocate(this.CreateGraphics(), this.DisplayRectangle);
- A = Width / (float)L; //вычисляем количество клеток по горизонтали
- B = Height / (float)H; //по вертикали
- A = (float)Math.Ceiling(A);
- B = (float)Math.Ceiling(B);
- present = new int[(int)A, (int)B, 3]; //два массива одинаковой размерности
- future = new int[(int)A, (int)B, 3]; //№ столбца; № ряда; 0: живая/мёртвая, 1,2: координаты X, Y
- Text = A.ToString() + ' ' + B.ToString(); //пишет в заголовок количество клеток по горизонтали и вертикали
- All_Dead(future); //делаем все клетки мёртвыми
- for (int i = 0; i <= 21; i++) //оживляем заданные клетки (начальное семя)
- {
- future[start[i, 0] + 7, start[i, 1] + 4, 0] = 1;
- }
- Draw_All(future); //рисуем все клетки в буфере
- myTimer = new System.Timers.Timer(1000); //таймер, отсчитывающий шаги игры
- myTimer.Interval = 1000; //интервал таймера - секунда
- myTimer.Elapsed += new ElapsedEventHandler(TimerEventProcessor); //устанавливаем обработчик таймера
- modeBut = new Button(); //создаём кнопку, чтобы выйти из режима редактора
- modeBut.Location = new Point(this.Size.Width -220, this.Size.Height -80);
- modeBut.Size = new Size(200, 40);
- modeBut.Font = new Font("Aerial", 16);
- modeBut.Text = "Exit editor";
- modeBut.Click += new EventHandler(this.modeBut_Click);
- this.Controls.Add(modeBut);
- myBuffer.Render(); //всё, что нарисовали за процедуру - на экран
- }
- private void modeBut_Click(object sender, System.EventArgs e) //обрабатываем нажатие на кнопку
- {
- if (setup == true) //если режим редактирования
- { //то
- modeBut.Text = "Enter editor"; //название кнопки
- myTimer.Start(); //запускаем игру
- setup = false; //теперь мы в режиме Игры
- }
- else //если режим Игры
- { //то
- modeBut.Text = "Exit editor"; //ну ты понел
- myTimer.Stop();
- setup = true;
- }
- }
- private void Form1_MouseDown(object sender, MouseEventArgs e) //обрабатываем нажатие на клетку
- {
- Point location = new Point(e.X, e.Y); //место нажатие в координатах экрана
- if ((e.Button == MouseButtons.Left) && (setup==true))
- {
- if (future[location.X/L , location.Y/H , 0] == 0) Alive(location.X / L , location.Y / H ); //если мёртвая - оживляем
- else Dead(location.X/L , location.Y/H ); //если живая - умерщвляем
- }
- myBuffer.Render(); //рисуем оживлённую/умерщвлённую клетку на экране
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment