Guest User

Untitled

a guest
Dec 31st, 2015
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.99 KB | None | 0 0
  1. using System;
  2. using System.Timers;
  3. using System.Drawing;
  4. using System.Windows.Forms;
  5.  
  6.  
  7. namespace WindowsFormsApplication2
  8. {
  9.     public partial class Form1 : Form
  10.     {
  11.         Button modeBut;
  12.         static System.Timers.Timer myTimer;             //таймер, который решает судьбу клеток
  13.         const int L = 26, H = 26;                       //длина и высота одной клетки
  14.         float A = 0, B = 0;                             //количество клеток в экране приложения по горизонтали и вертикали
  15.         int[,] start = new int[22, 2] { {6, 6}, {6, 7}, {6, 8}, {6, 9}, {6, 10}, {6, 11}, {6, 12}, {6, 13},
  16.                                         {7, 6},         {7, 8}, {7, 9}, {7, 10}, {7, 11},          {7, 13},
  17.                                         {8, 6}, {8, 7}, {8, 8}, {8, 9}, {8, 10}, {8, 11}, {8, 12}, {8, 13} };  //живые клетки в начале игры
  18.         int[,,] present, future;                        //массивы хранят карту живых/мёртвых клеток
  19.         BufferedGraphicsContext myContext;              //двойная буферизация
  20.         BufferedGraphics myBuffer;
  21.         bool setup = true;
  22.  
  23.         public Form1()
  24.         {
  25.             InitializeComponent();
  26.         }
  27.  
  28.         private void TimerEventProcessor(Object myObject,                      //решаем судьбу жизни/смерти клеток
  29.                                             EventArgs myEventArgs)
  30.         {
  31.            
  32.             Array.Copy(future, present, (int)(A) * (int)(B)*3);      //меняем массивы местами. Будущее становится настоящим!
  33.             Draw_All(present);                                       //рисуем в буфере
  34.             myBuffer.Render();                                       //копируем изображение из буфера на экран
  35.            // myBuffer.Dispose();
  36.            // myContext.Dispose();
  37.  
  38.             //теперь мы расчитываем следующий шаг
  39.                for (int i = 0; i <= A - 1; i++)                      //проверяем каждую клетку
  40.                 for (int j = 0; j <= B - 1; j++)                     //внимание! массив начинается с нуля!
  41.                 {
  42.                     int neighbour = 0;                               //вычисляем число соседей у данной клетки
  43.                                                                      //и следим, чтобы не обращаться за пределы массива                                                                          
  44.                     if ((i > 0) && (j > 0) && (present[i - 1, j - 1, 0] == 1)) neighbour++;
  45.                     if ((j > 0) && (present[i, j - 1, 0] == 1)) neighbour++;
  46.                     if ((i < A - 1) && (j > 0) && (present[i + 1, j - 1, 0] == 1)) neighbour++;
  47.                     if ((i > 0) && present[i - 1, j, 0] == 1) neighbour++;
  48.                     if ((i < A - 1) && present[i + 1, j, 0] == 1) neighbour++;
  49.                     if ((i > 0) && (j < B - 1) && present[i - 1, j + 1, 0] == 1) neighbour++;
  50.                     if ((j < B - 1) && present[i, j + 1, 0] == 1) neighbour++;
  51.                     if ((i < A - 1) && (j < B - 1) && present[i + 1, j + 1, 0] == 1) neighbour++;
  52.  
  53.                     //if (neighbour != 0)  Text = neighbour.ToString();
  54.                                                                                    //число соседей известно -
  55.                     if (neighbour < 2) future[i, j, 0] = 0;                        //применяем правила Игры Конвея
  56.                     else
  57.                     if (((neighbour == 2) || (neighbour == 3)) && present[i, j, 0] == 1) future[i, j, 0] = 1;
  58.                     else
  59.                     if (neighbour > 3) future[i, j, 0] = 0;
  60.                     else
  61.                     if (neighbour == 3) future[i, j, 0] = 1;
  62.                     //на этом месте массив future полностью заполнен и готов поменяться местами с present
  63.                 }
  64.         }
  65.        
  66.  
  67.         public void Draw_All(int[,,] array)                                    //процедура рисует все клетки
  68.         {
  69.             for (int i = 0; i < A - 1; i++)                                    //внимание! массив начинается с нуля!
  70.                 for (int j = 0; j < B - 1; j++)
  71.                 {
  72.                     Rectangle Rect = new Rectangle(0 + i * L, 0 + j * H, L , H );
  73.                     myBuffer.Graphics.FillRectangle(Brushes.LightGray, Rect);                        //рисуем серую сетку
  74.                     Rect = new Rectangle(0 + i * L + 2, 0 + j * L + 2, L-4, H-4);
  75.                     if (array[i, j, 0] == 0) myBuffer.Graphics.FillRectangle(Brushes.White, Rect);   //рисуем чёрную или белую клетку в сетке
  76.                     else myBuffer.Graphics.FillRectangle(Brushes.Black, Rect);
  77.                 }  
  78.         }
  79.  
  80.         public void All_Dead(int[,,] array)                                    //процедура делает клетки мёртвыми, но не рисует их
  81.         {
  82.             for (int i = 0; i < A - 1; i++)                          //внимание! массив начинается с нуля!
  83.                 for (int j = 0; j < B - 1; j++)
  84.                 {
  85.                     array[i, j, 0] = 0;                              //определяем, что клетка мертва
  86.                     array[i, j, 1] = 0 + i * L;                      //записываем координату X клетки
  87.                     array[i, j, 2] = 0 + j * H;                      //записываем координату Y клетки
  88.                 }
  89.         }
  90.        
  91.         public void Alive(int l, int h)                                        //делаем заданную клетку в массиве future живой
  92.         {
  93.             Rectangle Rect = new Rectangle(l*L, h*H, L, H);            //рисуем серую сетку вокруг клетки
  94.             myBuffer.Graphics.FillRectangle(Brushes.LightGray, Rect);
  95.             Rect = new Rectangle(l*L + 2, h*H + 2, L -4, H -4);        //рисуем саму клетку внутри сетки
  96.             myBuffer.Graphics.FillRectangle(Brushes.Black, Rect);
  97.             future[l, h, 0] = 1;                                               //клетка ЖИВА!
  98.         }
  99.  
  100.         public void Dead(int l, int h)                                         //делаем заданную клетку в массиве future мёртвой
  101.         {
  102.             Rectangle Rect = new Rectangle((l + 1) * L, (h + 1) * H, L, H);            //рисуем серую сетку вокруг клетки
  103.             myBuffer.Graphics.FillRectangle(Brushes.LightGray, Rect);
  104.             Rect = new Rectangle((l + 1) * L + 2, (h + 1) * H + 2, L - 4, H - 4);      //рисуем саму клетку внутри сетки
  105.             myBuffer.Graphics.FillRectangle(Brushes.White, Rect);
  106.             future[l, h, 0] = 0;                                               //клетка уже не жива
  107.         }
  108.  
  109.         private void Form1_Shown(object sender, EventArgs e)                   //исполняется при запуске приложения
  110.         {
  111.             myContext = new BufferedGraphicsContext();                         //двойная буферизация
  112.             myBuffer = myContext.Allocate(this.CreateGraphics(), this.DisplayRectangle);
  113.  
  114.             A = Width / (float)L;                                              //вычисляем количество клеток по горизонтали
  115.             B = Height / (float)H;                                             //по вертикали
  116.             A = (float)Math.Ceiling(A);
  117.             B = (float)Math.Ceiling(B);
  118.             present = new int[(int)A, (int)B, 3];              //два массива одинаковой размерности
  119.             future = new int[(int)A, (int)B, 3];               //№ столбца; № ряда; 0: живая/мёртвая, 1,2: координаты X, Y
  120.  
  121.             Text = A.ToString() + ' ' + B.ToString();          //пишет в заголовок количество клеток по горизонтали и вертикали
  122.  
  123.             All_Dead(future);                                  //делаем все клетки мёртвыми
  124.             for (int i = 0; i <= 21; i++)                      //оживляем заданные клетки (начальное семя)
  125.             {
  126.                 future[start[i, 0] + 7, start[i, 1] + 4, 0] = 1;
  127.             }
  128.             Draw_All(future);                                  //рисуем все клетки в буфере
  129.  
  130.  
  131.             myTimer = new System.Timers.Timer(1000);                             //таймер, отсчитывающий шаги игры
  132.             myTimer.Interval = 1000;                                             //интервал таймера - секунда
  133.             myTimer.Elapsed += new ElapsedEventHandler(TimerEventProcessor);     //устанавливаем обработчик таймера
  134.  
  135.             modeBut = new Button();                                              //создаём кнопку, чтобы выйти из режима редактора
  136.             modeBut.Location = new Point(this.Size.Width -220, this.Size.Height -80);
  137.             modeBut.Size = new Size(200, 40);
  138.             modeBut.Font = new Font("Aerial", 16);  
  139.             modeBut.Text = "Exit editor";            
  140.             modeBut.Click += new EventHandler(this.modeBut_Click);
  141.             this.Controls.Add(modeBut);
  142.  
  143.             myBuffer.Render();                                                    //всё, что нарисовали за процедуру - на экран
  144.         }
  145.  
  146.         private void modeBut_Click(object sender, System.EventArgs e)          //обрабатываем нажатие на кнопку
  147.         {
  148.             if (setup == true)                                  //если режим редактирования
  149.             {                                                   //то
  150.                modeBut.Text = "Enter editor";                   //название кнопки
  151.                myTimer.Start();                                 //запускаем игру
  152.                setup = false;                                   //теперь мы в режиме Игры
  153.             }
  154.             else                                                //если режим Игры
  155.             {                                                   //то
  156.                modeBut.Text = "Exit editor";                    //ну ты понел
  157.                myTimer.Stop();
  158.                setup = true;
  159.             }
  160.         }
  161.  
  162.         private void Form1_MouseDown(object sender, MouseEventArgs e)         //обрабатываем нажатие на клетку
  163.         {
  164.             Point location = new Point(e.X, e.Y);                             //место нажатие в координатах экрана
  165.             if ((e.Button == MouseButtons.Left) && (setup==true))
  166.             {
  167.                 if (future[location.X/L , location.Y/H , 0] == 0) Alive(location.X / L , location.Y / H );  //если мёртвая - оживляем
  168.                 else Dead(location.X/L , location.Y/H );                      //если живая - умерщвляем
  169.             }
  170.             myBuffer.Render();       //рисуем оживлённую/умерщвлённую клетку на экране
  171.              
  172.         }
  173.     }
  174. }
Advertisement
Add Comment
Please, Sign In to add comment