Guest User

Untitled

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