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
- {
- 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;
- private void TimerEventProcessor(Object myObject, //решаем судьбу жизни/смерти клеток
- EventArgs myEventArgs)
- {
- myContext = new BufferedGraphicsContext(); //создаём контекст для двойной буферизации
- myBuffer = myContext.Allocate(this.CreateGraphics(), this.DisplayRectangle);
- 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 Form1()
- {
- InitializeComponent();
- }
- public void Draw_All(int[,,] array) //процедура рисует все клетки
- {
- //Graphics Graph = Graphics.FromHwnd(Handle);
- 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 + 6, H + 6);
- myBuffer.Graphics.FillRectangle(Brushes.LightGray, Rect); //рисуем серую сетку
- Rect = new Rectangle(0 + i * L + 3, 0 + j * L + 3, L, H);
- if (array[i, j, 0] == 0) myBuffer.Graphics.FillRectangle(Brushes.White, Rect); //рисуем чёрную или белую клетку в сетке
- else myBuffer.Graphics.FillRectangle(Brushes.Black, Rect);
- }
- //Graph.Dispose();
- }
- 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 x, int y) //делаем заданную клетку в массиве future живой
- {
- future[x, y, 0] = 1; //клетка ЖИВА!
- }
- public void Dead(int x, int y) //делаем заданную клетку в массиве future мёртвой
- {
- future[x, y, 0] = 0; //клетка уже не жива
- }
- private void Form1_Load(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); //делаем все клетки мёртвыми
- Draw_All(future); //рисуем все клетки
- for (int i = 0; i <= 21; i++) //оживляем заданные клетки (начальное семя)
- {
- Alive(start[i, 0], start[i, 1]);
- }
- myBuffer.Render();
- myContext.Dispose();
- myTimer = new System.Timers.Timer(1000);
- myTimer.Interval = 1000; //интервал таймера - секунда
- myTimer.Elapsed += new ElapsedEventHandler(TimerEventProcessor); //устанавливаем обработчик таймера
- myTimer.Start();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment