SaveText.Ru

Без имени
  1. using System;
  2. using System.Drawing;
  3. using System.Windows.Forms;
  4.  
  5. namespace CSharpApplication.WindowsApplicationExample
  6. {
  7.     // Игра "Пятнашки"
  8.     class Game : Form
  9.     {
  10.         // Размер стороны поля, если изменить игра станет более веселой :)
  11.         const int Side = 4;
  12.         // Номер "пустышки"
  13.         const int Void = Side * Side;
  14.         // Начальные координаты пустышки
  15.         int Voidx = Side - 1, Voidy = Side - 1;
  16.         // Массив кнопок
  17.         Button [,] Field;
  18.         // Массив значений кнопок
  19.         int [,] Numbers;
  20.         // Количество проделанных ходов
  21.         int Moves;
  22.         // Индикатор запуска игры
  23.         bool IsGameRun;
  24.  
  25.         // Надпись для отображения прошедшего времени
  26.         Label clock = new Label();
  27.         // Объект таймера
  28.         Timer timer = new Timer();
  29.         // Инициализация генератора случайных чисел
  30.         Random Randomize = new Random();
  31.  
  32.         // Время игры
  33.         TimeSpan time;
  34.  
  35.         static void Main()
  36.         {
  37.             // Запуск приложения
  38.             Application.Run(new Game());
  39.         }
  40.  
  41.         // Конструктор - инициализация игры
  42.         Game()
  43.         {
  44.             // Заголовок формы
  45.             Text = "Пятнашки";
  46.             // Стиль рамки для формы
  47.             FormBorderStyle = FormBorderStyle.Fixed3D;
  48.             // Выключение кнопки для развертывания окна
  49.             MaximizeBox = false;
  50.             // Вычисление размера клиентской области окна
  51.             ClientSize = new Size(Side * 50 + 20, Side * 50 + 50);
  52.             // Цвет фона
  53.             BackColor = Color.Silver;
  54.  
  55.             // Массив кнопок
  56.             Field = new Button[Side, Side];
  57.             // Массив чисел
  58.             Numbers = new int[Side, Side];
  59.  
  60.             /*************************************************************/
  61.             /* Добавление пунктов меню
  62.             /*************************************************************/
  63.             MenuItem miNewGame = new MenuItem("Новая игра",
  64.                 new EventHandler(OnMenuStart), Shortcut.F2);
  65.             MenuItem miSeparator = new MenuItem("-");
  66.             MenuItem miExit = new MenuItem("Выход",
  67.                 new EventHandler(OnMenuExit), Shortcut.CtrlX);
  68.             MenuItem miGame = new MenuItem("&Игра",
  69.                 new MenuItem[] {miNewGame, miSeparator, miExit});
  70.  
  71.             // Создание меню и его привязка к форме
  72.             Menu = new MainMenu(new MenuItem[] {miGame});
  73.  
  74.             // Игра не запущена
  75.             IsGameRun = false;
  76.  
  77.             // Таймер будет срабатывать каждую секунду
  78.             timer.Interval = 1000;
  79.             // Подключение обработчика таймера
  80.             timer.Tick += new EventHandler(OnTimer);
  81.  
  82.             // Размещение надписи
  83.             clock.Location = new Point(10, 10);
  84.             // Ширина надписи
  85.             clock.Width = Side * 50;
  86.             // Высота надписи
  87.             clock.Height = 20;
  88.             // Родитель надписи (форма)
  89.             clock.Parent = this;
  90.             // Тонкая рамка
  91.             clock.BorderStyle = BorderStyle.FixedSingle;
  92.             // Цвет фона
  93.             clock.BackColor = Color.DarkGray;
  94.             // Текст выравнивается по центру надписи
  95.             clock.TextAlign = ContentAlignment.MiddleCenter;
  96.             // Шифт надписи
  97.             clock.Font = new Font("Century", 14, FontStyle.Bold);
  98.             // Текст надписи
  99.             clock.Text = "00:00:00";
  100.  
  101.             int i, j;
  102.             // Инициализация поля
  103.             for(i = 0; i < Side; i++)
  104.             {
  105.                 for(j = 0; j < Side; j++)
  106.                 {
  107.                     // Создание новой кнопки
  108.                     Field[i, j] = new Button();
  109.                     // Указываем родителя для кнопки (форма)
  110.                     Field[i, j].Parent = this;
  111.                     // Задаем очередное число
  112.                     Numbers[i, j] = i * Side + j + 1;
  113.                     // Если не "пустышка"
  114.                     if(Numbers[i, j] != Void)
  115.                         // Отображаем число на кнопке
  116.                         Field[i, j].Text = Convert.ToString(Numbers[i, j]);
  117.              
  118.                     // Вычисляем координаты очередной кнопки
  119.                     Field[i, j].Left = 10 + j * 50;
  120.                     Field[i, j].Top = 40 + i * 50;
  121.                     Field[i, j].Width = 50;
  122.                     Field[i, j].Height = 50;
  123.                     // Шрифт кнопки
  124.                     Field[i, j].Font = new Font("Century", 12, FontStyle.Bold);
  125.                     // Ассоциируем с кнопкой ее координаты в массиве
  126.                     Field[i, j].Tag = new Point(i, j);
  127.                     // Добавляем обработчик нажатия на кнопку
  128.                     Field[i, j].Click += new EventHandler(OnCellClick);
  129.                     // Цвет текста
  130.                     Field[i, j].ForeColor = Color.Yellow;
  131.                     // Цвет фона
  132.                     Field[i, j].BackColor = Color.Gray;
  133.                 }
  134.             }
  135.  
  136.             // Отображаем форму по центру экрана
  137.             CenterToScreen();
  138.         }
  139.  
  140.         // Обработчик пункта меню "Выход"
  141.         void OnMenuExit(object obj, EventArgs ea)
  142.         {
  143.             // Закрываем форму
  144.             Close();
  145.         }
  146.  
  147.         // Обработчик пункта меню "Новая игра"
  148.         void OnMenuStart(object obj, EventArgs ea)
  149.         {
  150.             int i, j, k;
  151.             int direction;
  152.             /************************/
  153.             /* Перемешивание поля  
  154.             /************************/
  155.             int Times = Side * 100;
  156.             for(k = 0; k < Times; k++)
  157.             {
  158.                 // Направление движения
  159.                 direction = Randomize.Next(4);
  160.        
  161.                 if(direction == 0) // Вверх
  162.                 {
  163.                     // Кнопка сверху существует
  164.                     if(Voidx - 1 >= 0)
  165.                     {
  166.                         Numbers[Voidx, Voidy] = Numbers[Voidx - 1, Voidy];
  167.                         Voidx--;
  168.                     }
  169.                     else
  170.                     {
  171.                         for(i = 0; i < Side - 1; i++)
  172.                         {
  173.                             Numbers[i, Voidy] = Numbers[i + 1, Voidy];
  174.                         }
  175.                         Voidx = Side - 1;
  176.                     }
  177.                 }
  178.                 else if(direction == 1) // Вниз
  179.                 {
  180.                     // Кнопка снизу существует
  181.                     if(Voidx + 1 < Side)
  182.                     {
  183.                         Numbers[Voidx, Voidy] = Numbers[Voidx + 1, Voidy];
  184.                         Voidx++;
  185.                     }
  186.                     else
  187.                     {
  188.                         for(i = Side - 1; i > 0; i--)
  189.                         {
  190.                             Numbers[i, Voidy] = Numbers[i - 1, Voidy];
  191.                         }
  192.                         Voidx = 0;
  193.                     }
  194.                 }
  195.                 else if(direction == 2) // Влево
  196.                 {
  197.                     // Кнопка слева существует
  198.                     if(Voidy - 1 >= 0)
  199.                     {
  200.                         Numbers[Voidx, Voidy] = Numbers[Voidx, Voidy - 1];
  201.                         Voidy--;
  202.                     }
  203.                     else
  204.                     {
  205.                         for(j = 0; j < Side - 1; j++)
  206.                         {
  207.                             Numbers[Voidx, j] = Numbers[Voidx, j + 1];
  208.                         }
  209.                         Voidy = Side - 1;
  210.                     }
  211.                 }
  212.                 else // Вправо
  213.                 {
  214.                     // Кнопка справа существует
  215.                     if(Voidy + 1 < Side)
  216.                     {
  217.                         Numbers[Voidx, Voidy] = Numbers[Voidx, Voidy + 1];
  218.                         Voidy++;
  219.                     }
  220.                     else
  221.                     {
  222.                         for(j = Side - 1; j > 0; j--)
  223.                         {
  224.                             Numbers[Voidx, j] = Numbers[Voidx, j - 1];
  225.                         }
  226.                         Voidy = 0;
  227.                     }
  228.                 }
  229.  
  230.                 // Новая позиция "пустышки"
  231.                 Numbers[Voidx, Voidy] = Void;
  232.             }
  233.  
  234.             // Отображение перемешанных чисел на кнопках
  235.             for(i = 0; i < Side; i++)
  236.             {
  237.                 for(j = 0; j < Side; j++)
  238.                 {
  239.                     if(Numbers[i, j] != Void)
  240.                     {
  241.                         Field[i, j].Text = Convert.ToString(Numbers[i, j]);
  242.                     }
  243.                     else
  244.                     {
  245.                         Field[i, j].Text = "";
  246.                     }
  247.                 }
  248.             }
  249.  
  250.             Moves = 0;
  251.             // Игра запущена
  252.             IsGameRun = true;
  253.             // Начальное время
  254.             time = new TimeSpan(0, 0, 0);
  255.             clock.Text = "00:00:00";
  256.             // Запуск таймера
  257.             timer.Start();
  258.         }
  259.  
  260.         // Обработчик нажатия кнопки (ход)
  261.         void OnCellClick(object obj, EventArgs ea)
  262.         {
  263.             // Если игра не запущена
  264.             if(IsGameRun == false)
  265.                 return;
  266.  
  267.             // Вынимаем "нажатый" объект
  268.             Button btn = (Button)obj;
  269.             // Определяем его месторасположение в массиве
  270.             // по ассоциированным координатам
  271.             int i = ((Point)btn.Tag).X;
  272.             int j = ((Point)btn.Tag).Y;
  273.  
  274.             // Если нажатая кнопка расположена
  275.             // слева, или снизу, или справа, или сверху от "пустышки"
  276.             if(Math.Abs(i - Voidx) + Math.Abs(j - Voidy) == 1)
  277.             {
  278.                 // Ход
  279.                 Numbers[Voidx, Voidy] = Numbers[i, j];
  280.                 Field[Voidx, Voidy].Text = Field[i, j].Text;
  281.                 // Новые координаты "пустышки"
  282.                 Voidx = i;
  283.                 Voidy = j;
  284.                 Numbers[Voidx, Voidy] = Void;
  285.                 Field[Voidx, Voidy].Text = "";
  286.  
  287.                 // Ход сделан
  288.                 Moves++;
  289.             }
  290.  
  291.             // Если "пустышка" в нижнем правом углу
  292.             if(Voidx == Side - 1 && Voidy == Side - 1)
  293.             {
  294.                 // Если победа
  295.                 if(IsWinner() == true)
  296.                 {
  297.                     // Остановка таймера
  298.                     timer.Stop();
  299.  
  300.                     string msg = "Поздравляем!!!nВы достигли успеха за ";
  301.                     msg += Moves;
  302.                     if(Moves % 10 > 1 && Moves % 10 < 5 && Moves % 100 / 10 != 1)
  303.                         msg += " хода.";
  304.                     else if(Moves % 10 == 1 && Moves % 100 / 10 != 1)
  305.                         msg += " ход.";
  306.                     else
  307.                         msg += " ходов.";
  308.                     // Остановка игры
  309.                     IsGameRun = false;
  310.                     // Отображение информационного окна
  311.                     MessageBox.Show(msg, "Победа!!!",
  312.                         MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
  313.                 }
  314.             }
  315.         }
  316.  
  317.         // Определение выигрышной позиции
  318.         bool IsWinner()
  319.         {
  320.             int i, j, k = 1;
  321.             for(i = 0; i < Side; i++)
  322.             {
  323.                 for(j = 0; j < Side; j++)
  324.                 {
  325.                     // Если очередное число не совпадает с порядковым
  326.                     if(Numbers[i, j] != k)
  327.                         return false;
  328.  
  329.                     k++;
  330.                 }
  331.             }
  332.             // Выигрыш
  333.             return true;
  334.         }
  335.  
  336.         // Обработчик событий таймера
  337.         void OnTimer(object obj, EventArgs ea)
  338.         {
  339.             // Увеличиваем время на секунду
  340.             time += new TimeSpan(0, 0, 1);
  341.             // Отображаем полученное время
  342.             clock.Text = time.ToString();
  343.         }
  344.        
  345.         // Обработчик активизации формы (получение фокуса приложением)
  346.         protected override void OnActivated(EventArgs ea)
  347.         {
  348.             // Вызов базового обработчика
  349.             base.OnActivated(ea);
  350.  
  351.             // Если игра запущена
  352.             if(IsGameRun == true)
  353.                 // Запуск таймера
  354.                 timer.Start();
  355.         }
  356.  
  357.         // Обработчик деактивизации формы (потеря фокуса приложением)
  358.         protected override void OnDeactivate(EventArgs ea)
  359.         {
  360.             // Вызов базового обработчика
  361.             base.OnDeactivate(ea);
  362.  
  363.             // Если игра запущена
  364.             if(IsGameRun == true)
  365.                 // Остановка таймера
  366.                 timer.Stop();
  367.         }
  368.     }
  369. }

Share with your friends:

Print