Создание игры "пятнашки" на языке C#
Автор: Поварницын Е.Н.
Журнал: Форум молодых ученых @forum-nauka
Статья в выпуске: 8 (36), 2019 года.
Бесплатный доступ
Статья посвящается созданию игры «Пятнашки». В данной статье описан сам процесс игры, а так же её суть. Так же наглядное использование языков C# и XAML.
Пятнашки, игра, компьютерная игра
Короткий адрес: https://sciup.org/140287006
IDR: 140287006
Текст научной статьи Создание игры "пятнашки" на языке C#
Сперва, сделаем один уровень игры размером пятнашек 4x4, но в процессе работы осложним игру. Сложность заключается в размерах самой игры: Лёгкий уровень размером 3x3, средний 4x4 и сложный 5x5. После всей работы сама игра выглядела не очень красиво с обычными цветовыми палитрами и поэтому закрасим кнопки с цифрами в текстуру, а сам фон сменим с градиента на более живой. Таким образом, получится, вроде как, красивая и интересная игра «Пятнашки».
РЕАЛИЗАЦИЯ
Для начала нужно создать саму модель игры «Пятнашки». Для этого создадим «класс», в котором будет реализован основной процесс игры. Для облегчения процесса создания также потребовались «методы» в самом классе.
Первый метод «Model» , данный метод позволял создать матрицу для самой игры, так же он намного упрощал создания таких игр как 24,8, в соответствии с рисунком 1. Переменная map служила самой матрицей, а size размер, к примеру 4.
class Model
{ int size;
int[,] map;
int space_x, space_y;
static Random rand = new Random();
public Model (int size)
{ if (size < 2) size = 2;
if (size > 5) size = 5;
map = new int[size, size]
}
Рисунок 1 – Model
Следующий метод «Start». Данный метод заполняет массив цифрами по координатам, в соответствии с рисунком 2. Так же здесь используется метод «coords_to_position», но о нём позже.
public void start(){ for (int x = 0; x < size; x++)
for (int y = 0; y < size; y++)
map[x, y] = coords_to_position(x, y) + 1;
space_x = size -1;
space_y = size -1;
map[space_x,space_y] = 0;
}
Рисунок 2 – Start
Далее расположены методы «coords_to_position» и «position_to_coords».
Первый метод с помощью координат x и y ищет номер матрицы, к примеру, если будет координата x=3, а y=0, то матрица примет значения 3. Так же он не даёт 3
матрице переполниться, что впоследствии могло взывать ошибку. Второй метод же возвращает координаты x и y обратно, то есть даёт возможность с помощью элемента массива найти, какие координаты он имеет, в соответствии с рисунком 3. Так же он проверяется, что бы массив не переполнился.
private int coords_to_position(int x,int y)
{ if (x < 0) x = 0;
if (x > size -1 ) x = size-1;
if (y < 0) y = 0;
if (y > size - 1) y = size - 1;
return y * size + x;
} private void position_to_coords (int position, out int x, out int y) { if (position < 0) position = 0;
if (position > size * size - 1) y=size*size-1 ;
x = position % size;
y = position / size;
}
Рисунок 3 – coords_to_position и position_to_coords
Следующий метод «Shift» позволяет нам передвигать нулевой элемент в массиве, в соответствии с рисунком 4. Другими словами обмениваться числами. Это позволит нам в будущем передвигать наши пятнашки.
public void shift(int position)
{ int x, y;
position_to_coords(position, out x, out y);
map[x, y]= 0;
space_x =x;
space_y =y;}
}
Рисунок 4 – Shift
Метод «Get_number» нам понадобится для того, чтобы в будущем получить координату, на котором будет расположено число, в соответствии с рисунком 5.
public int get_number(int position)
{ int x, y;
position_to_coords(position, out x, out y);
if (x < 0 || x >= size) return 0;
if (y < 0 || y >= size) return 0;
return map[x, y];
}
Рисунок 5 – Get_number
Для того чтобы в начале игры числа располагались случайно составим метод
«Shift_random». В нём нулевое число будет передвигаться на 4 стороны наугад, в соответствии с рисунком 6.
public void shift_random()
int x = space_x;
int y = space_y;
switch (a)
{
case |
0: |
x--; |
break; |
case |
1: |
x++; |
break; |
case |
2: |
y--; |
break; |
case |
3: |
y++; |
break; |
} shift(coords_to_position(x, y));
}
Рисунок 6 – Shift_random
И самый последний метод в данном классе является «Chek_game». Данный метод проверяет не окончена ли ещё игра. Он сверяет, не совпадают ли начальные координаты с текущими, и если они совпадают, то он выдаёт значение «true», в соответствии с рисунком 7. Игра будет продолжаться до тех пор, пока этот метод не будет действительным.
public bool chek_game()
{ if (!(space_x == size - 1 for (int x = 0; x < size; x++)
for (int y = 0; y < size; y++)
if (map[x, y] != coords_to_position(x, y) + 1) return false;
return true;
}
Рисунок 7 – Chek_game
WINDOWS PRESENTATION FOUNDATION
На данном этапе будет показано, как делается средний уровень 4x4 сложности в игре «Пятнашки». Лёгкий уровень 3x3 и сложный 5x5 делается аналогично, с добавлением или удалением кнопок, в зависимости от параметра матрицы.
Сначала, следует разделить окно на равную клетчатую таблицу, где будут расположены 4 строки и 4 столбца. В них следует сделать кнопки («Button») и установить обработчик событий «По клику». Таким образом, у нас в .xaml.cs добавятся методы при взаимодействии с данной кнопкой. Для взаимодействия с кнопками добавим «Tag» к каждой кнопки начиная с 0 и заканчивая 15.
Далее добавим метод Button, который позволит с помощью кейсов взаимодействовать с кнопками, в соответствии с рисунком 8.
private Button button (int position) { switch (position)
{
case |
0: |
return |
button0; |
case |
1: |
return |
button1; |
case |
2: |
return |
button2; |
case |
3: |
return |
button3; |
case |
4: |
return |
button4; |
case |
5: |
return |
button5; |
case |
6: |
return |
button6; |
case |
7: |
return |
button7; |
case |
8: |
return |
button8; |
case |
9: |
return |
button9; |
case |
10: |
return |
button10; |
case |
11: |
return |
button11; |
case |
12: |
return |
button12; |
case |
13: |
return |
button13; |
case |
14: |
return |
button14; |
case |
15: |
return |
button15; |
default: |
return |
null; |
} }
Рисунок 8 – Button
Далее создадим метод «refresh», который будет отвечать за расстановку чисел на кнопки, он будет брать номера из массива и преобразовывать их в текст (контент), в соответствии с рисунком 9. Также для красивой картинки сделаем кнопку, на которой будет расположено число 0 невидимой.
private { for {
} }
void refresh()
(int position = 0; position < 16; position++)
button(position).Content = game.get_number(position);
button(position).Visibility = (game.get_number(position)==0)?
Visibility.Collapsed:Visibility ;
Рисунок 9 – Refresh
Остаётся только начать игру. И для этого нужно создать метод «Start_game». В котором будут располагаться сначала элементы в массиве, потом перемешиваться с определённой точностью n шагов и преобразовываться в текст (контент), в соответствии с рисунком 10.
for (int i = 0; i < 100; i++)
game.shift_random();
}
Рисунок 10 – Start_game
Далее возвратимся к нашим кнопкам. В них следует отметить позицию, конвертировав наш тэг, для определения кнопки, далее следует добавить наше передвижение по матрицы и конвертировать ее в текст. Следует это сделать ко всем кнопкам. Теперь цифры передвигаются с кнопки на кнопку. Теперь чтобы понять что игра закончена следует её проверить через метод «chek_game», и если оно true, то вывести на экран победное сообщение с предложением либо повторить игру, либо закрыть приложение. Это следует сделать в соответствии с рисунком 1 1 и применить ко всем кнопкам соответственно.
private void Button_Click(object sender, RoutedEventArgs e) { |
|
int position = Convert.ToInt16(((Button)sender).Tag); game.shift(position); refresh(); if (game.chek_game()) { |
|
var res = MessageBox.Show("Победа!!!\nЕще разок?", "Ура!! |
!", |
MessageBoxButton.YesNo); |
|
if (res == MessageBoxResult.Yes) start_game(); else |
|
Close(); |
|
} } |
Рисунок 11 – Button_Ckick_N
Всё, наша игра готова, теперь остаётся сделать ее визуально красивой. Для этого в файле .xaml отредактируем фон игры и собственно сами кнопки.
Наложим на фон красящую картинку, в соответствии с рисунком 12.
Stretch="UniformToFill"/>
Рисунок 12 – Background
Далее будет работать с кнопками приложения. Добавим на кнопки фон, сделаем так, чтобы кнопки имели формы фона, у меня они квадратные. Так же я сделал рамку под цвет фона, для того что бы лучше выглядело. Следует всё это выполнить в соответствии с рисунком 13, и применить ко всем кнопкам, дабы они не различались друг от друга
Для будущего взаимодействия с главным экранам я сделал кнопки «В главное меню». Так же я добавил «Рестарт» и «Выход». Для того чтобы выйти в главное меню, нужно прежде всего создать ещё одно окно и сделать переход на него при нажатии определённой кнопки, в соответствии с рисунком 14.
private void Button_Click_17(object sender, RoutedEventArgs e) {
Window1 taskWindow = new Window1();
Close();
}
Рисунок 14 – Переход в главное меню
private void Window_Loaded(object sender, RoutedEventArgs e) { start_game();
}
Рисунок 15 – Загрузка игры
В итоге мы получаем игру «Пятнашки», показанную на рисунке 16.

Рисунок 16 – Пятнашки
Теперь можно создать лёгкий и сложный уровень, сделав некоторые махинации с кнопками. Для увеличения или уменьшения массива стоит всего лишь поменять одну переменную game = new Model(поле NxN), в соответствии с рисунком 17.
public partial class MainWindow { Model game; public MainWindow() { InitializeComponent(); game = new Model(4); } |
Window |
Рисунок 17 – Размер поля
Так же следует изменить кол-во кейсов в методе «Button» на необходимое количество, в соответствии с рисунком 18.1 и 18.2.
private Button button(int position) { switch (position)
{
ФОРУМ М
}
Рисунок 18.1 – Изменение Button для 3x3
private |
Button |
button(int position) |
{ switch (position) |
||
{ |
case 0: |
return button0; |
case 1: |
return button1; |
|
case 2: |
return button2; |
|
case 3: |
return button3; |
|
case 4: |
return button4; |
|
case 5: |
return button5; |
|
case 6: |
return button6; |
|
case 7: |
return button7; |
|
case 8: |
return button8; |
|
case 9: |
return button9; |
|
case 10: |
return button10; |
|
case 11: |
return button11; |
|
case 12: |
return button12; |
|
case 13: |
return button13; |
|
case 14: |
return button14; |
|
case 15: |
return button15; |
|
case 16: |
return button16; |
|
case 17: |
return button17; |
|
case 18: |
return button18; |
|
case 19: |
return button19; |
|
case 20: |
return button20; |
|
case 21: |
return button21; |
|
case 22: |
return button22; |
|
case 23: |
return button23; |
|
case 24: |
return button24; |
|
default: |
return null; |
|
} } |
Рисунок 18.2 – Изменение Button для 5x5
После чего следует поменять расстановку чисел на кнопках в методе «Refresh», если поле 4x4, то будет 16, если 3x3, то 9, если 5x5, то 25 и т.д., в соответствии с рисунком 19.1 и рисунком 19.2.
private void refresh()
{ for (int position = 0; position < 9; position++)
{ button(position).Content = game.get_number(position);
button(position).Visibility = (game.get_number(position) == 0) ? Visibility.Collapsed: Visibility;
}
Рисунок 19.1 – Изменение Refresh для 3x3
private void refresh()
{ for (int position = 0; position < 25; position++)
{ button(position).Content = game.get_number(position);
button(position).Visibility = (game.get_number(position) == 0) ? Visibility.Collapsed: Visibility;
}
}
Рисунок 19.2 – Изменение Refresh для 5x5
После этих операций и некоторых работы в XAML мы получаем игры, в соответствии с рисунками 20.1 и 20.2

Рисунок 20.1 – Лёгкий уровень
в Пятнашки

Рисунок 20.2 – Сложный уровень
Далее в уже созданном меню, разместим ссылки на открытие самих уровней и закрытие самой игры, в соответствии с рисунком 21.
private void Button_Click(object sender, RoutedEventArgs e)
{
Easy taskWindow = new Easy();
} Close();
ФО
private void Button_Click_1(object sender, RoutedEventArgs e) {
MainWindow taskWindow = new MainWindow();
Рисунок 21 – Ссылка на уровни и выход
В итоге после редактирования фона и кнопок, мы получим меню через которое можно проходить на уровни, в соответствии с рисунком 22.
■ | Пятнашки

Рисунок 22 – Меню игры
И в самом конце можно добавить иконку для игры, в соответствии с рисунком 23
Рисунок 23 – Иконка для игры
Всё, мы получили игру с красивым оформлением. Это можно увидеть на рисунке 24.

Рисунок 24 – Готовая игра
Список литературы Создание игры "пятнашки" на языке C#
- Подбельский, В.В. Язык декларативного программирования XAML / В.В. Подбельский. - Москва: ДМК Пресс
- Александров, Э.Э. Программирование на языке C в Microsoft Visual Studio 2010: учебное пособие / Э.Э. Александров, В.В. Афонин. - 2-е изд. - Москва