Алгоритм работы программы




 

Создание массива, заполненного последовательно 1,..,15,0
Перемешать массив
Перемешанный массив, число ходов
Нажата клавиша
Победа?
Переместить пустую клетку в противоположном направлении
нет
Alt + R
Начать новую игру (перемешать таблицу, счетчик ходов = 0)
Alt + X
Выход из программы
 
Стрелка влево / вправо / вверх / вниз
да

 


Описание классов

Для решения задачи создано два класса. Один класс – базовый – описывает игровое поле, в нем содержатся методы, связанные с отображением таблицы на экране. Второй – производный с обобществленным типом наследования – содержит поля и методы, связанные с ходом игры. Именно в нем содержатся методы, двигающие пустую клетку; ожидание нажатия клавиши, проверка на завершение игры.

 

Диаграмма классов

 

Структура классов

Класс GameField отвечает за формирование таблицы и за вывод информации на экран.

Поля класса GameField:

- int Field[4][4] – игровое поле

- int izero – номер строки, в которой находится пустая ячейка

- int jzero – номер столбца, в котором находится пустая ячейка

- int RightField[4][4] – эталон победного положения чисел для победы

- int Step – число сделанных игроком ходов

 

 

Методы класса GameField:

- GameField() – конструктор, заполняет таблицу в правильную последовательность

- void MoveElements (int i1, int j1, int i2, int j2) – меняет местами значения ячеек таблицы, находящиеся в [i1][j1] и [i2][j2].

- bool CheckForSolution() – проверяет, решаема ли данная конфигурация чисел в таблице. Если решаема, возвращает 1, иначе 0.

- void Mix() – случайным образом перемешивает значения клеток поля так, чтобы в итоге получилась решаемая комбинация.

- void Draw() – выводит на экран картинку игры.

Класс Game отвечает за ход игры, за передвижение клеток при нажатии клавиш, за контроль за завершением текущей игры.

Поля класса Game:

- bool EndGame – признак завершения игры

 

Методы класса Game:

- Game() – конструктор, инициализирует таблицу и задает EndGame = FALSE

- void Mix() – перемешивает таблицу при запросе на новую игру

- void CheckEndGame() – устанавливает флаг признака завершения игры

- void MoveDown() – перемещает в пустую клетку ячейку сверху

- void MoveUp() – перемещает пустую ячейку вниз

- void MoveLeft() – перемещает пустую ячейку вправо

- void MoveRight() – перемещает пустую ячейку влево

- bool EndGameIs() - проверяет таблицу на правильность

- void TheEnd() – выводит на экран сообщение о победе

- void GetInstruction() – ожидает нажатия клавиши и реагирует на нажатие

 

 


 

Общие сведения о программе

 

Игровая программа «Пятнадцать»

Для функционирования программы необходимо следующее программное обеспечение:

Windows 7/ Windows 8/Windows 8.1/Windows 10;

Программа написана на языке программирования C++. Использовалась интегрированная среда разработки Visual Studio 2015.


 

Функциональное назначение

 

Функциональное назначение программы – реализация игровой программы «Пятнадцать».

Программа должна выполнять следующие действия:

- Взаимодействие с игроком;

- Чтение данных с клавиатуры;

- Перемещение пустой клетки;

- Проверка на завершение игры;

- Оповещать игрока о завершении игры;

- Перемешивать таблицу для начала новой игры.

Кроме того необходимо предусмотреть:

- Краткую справку, позволяющую понять управление в игре.

- Выход из программы.


 

Используемые технические средства

При создании программного проекта использовались следующие технические средства:

· Персональный компьютер с процессором AMD A6-5200 APU with Radeon (TM) HD Graphics 2.00GHz. 64-разрядная операционная система, процессор x64. Установленная память 6.00 ГБ.

 


 

Вызов и загрузка

 

Запуск программы осуществляется запуском файла Пятнашки.exe. Также возможно запускать непосредственно через интегрированную систему разработки программного обеспечения Visual Studio 2015 Community.

EXE-файл занимает 14 336 байт.

Размер модулей, входящих в состав проекта:

- GameField.h – 498 байт.

- GameField.cpp – 3 083 байт.

- Game.h – 367 байт.

- Game.cpp – 2 201 байт

- Main.cpp – 133 байт.

Общий размер проекта – 35 977 978 байт

Потребление памяти – 0,4 МБ


 

Выводы

В ходе выполнения курсовой работы углублены и закреплены теоретические знания, навыки практического применения основных принципов объективно-ориентированных систем: наследования, инкапсуляции, полиморфизма, а также сформированы новые взгляды на процессы программирования с учетом абстракции данных.

 


 

Список литературы

1. [Интернет-ресурс] https://ru.wikipedia.org/wiki/Игра_в_15

2. [Интернет-ресурс] https://msdn.microsoft.com/ru-ru/library/3bstk3k5.aspx

 


 

Тестовые данные

 

При запуске программы открывается окно, в котором отображается таблица с перемешанными числами.

Рис.3. Начальное положение игрового поля

При нажатии стрелки влево «8» поменяется местами с пустой клеткой, количество ходов увеличится на 1

Рис.4. После первого хода

 

При нажатии сочетания клавиш Alt+R числа в таблице перемешиваются, количество ходов обнуляется

Рис.5. После перемешивания

После выстраивания чисел в правильном порядке игра завершится и на экран выведет сообщение о победе

Рис.6. Победа


 

Тексты программ

 

GameField.h

#include <iostream>

#include <time.h>

#include <conio.h>

using namespace std;

 

class GameField {

protected:

int Field[4][4];

int Step;

int izero;

int jzero;

int RightField[4][4];

public:

GameField();

bool CheckForSolution();

virtual void Mix();

void MoveElements(int, int, int, int);

void Draw();

};

 

GameField.cpp

 

#include "GameField.h"

 

GameField::GameField() {

for (int i = 0; i < 16; i++) {

Field[i / 4][i % 4] = i + 1;

if (i == 15)

Field[i / 4][i % 4] = 0;

}

for (int i = 0; i < 4; i++)

for (int j = 0; j < 4; j++)

RightField[i][j] = Field[i][j];

for (int i = 0; i < 4; i++)

for (int j = 0; j < 4; j++)

UnCalcField[i][j] = Field[i][j];

int t = UnCalcField[3][2];

izero = 3;

jzero = 3;

UnCalcField[3][2] = UnCalcField[3][1];

UnCalcField[3][1] = t;

Step = 0;

}

bool GameField::CheckForSolution() {

int a[16];

int inv = 0;

for (int i = 0; i < 4; ++i)

for (int j = 0; j < 4; ++j)

a[i * 4 + j] = Field[i][j];

for (int i = 16; i < 16; ++i)

if (a[i]!= 0)

for (int j = 0; j < i; ++j)

if (a[j] > a[i])

++inv;

for (int i = 0; i < 16; ++i)

if (a[i] == 0)

inv += 1 + i / 4;

return (inv & 1)? false: true;

}

void GameField::Mix() {

for (int i = 0; i < 16; i++) {

Field[i / 4][i % 4] = i + 1;

if (i == 15)

Field[i / 4][i % 4] = 0;

}

srand(time(0));

for (int i = 0; i < 16; i++) {

int j = rand() % (16 - i) + i;

int tmp = Field[j / 4][j % 4];

Field[j / 4][j % 4] = Field[i / 4][i % 4];

Field[i / 4][i % 4] = tmp;

}

int i1, i2, j1, j2;

bool Solution = CheckForSolution();

if (!Solution) {

for (int i = 0; i < 16; ++i) {

if (Field[i / 4][i % 4] == 14) {

i1 = i / 4;

j1 = i % 4;

}

else

if (Field[i / 4][i % 4] == 15) {

i2 = i / 4;

j2 = i % 4;

}

}

MoveElements(i1, j1, i2, j2);

}

}

void GameField::MoveElements(int i1, int j1, int i2, int j2) {

int tmp = Field[i1][j1];

Field[i1][j1] = Field[i2][j2];

Field[i2][j2] = tmp;

}

void GameField::Draw() {

system("cls");

setlocale(0, "rus");

cout << " ALT+X - выход из программы ALT+R - перемешать" << endl;

cout << endl << endl;

cout << " Игровая программа \"Пятнадцать\"" << endl;

cout << " ___________________________" << endl;

for (int i = 0; i < 4; i++) {

cout << " | | | | |" << endl << " |";

for (int j = 0; j < 4; j++) {

if (Field[i][j] == 0) {

cout << " |";

izero = i;

jzero = j;

}

else

if (Field[i][j] <= 9) cout << " " << Field[i][j] << " |";

else

cout << " " << Field[i][j] << " |";

}

cout << endl;

cout << " |______|______|______|______|" << endl;

}

cout << endl << " Количество ходов: " << Step << endl;

}

 

Game.h

#include "GameField.h"

 

class Game: public GameField {

protected:

bool EndGame;

public:

Game();

void GetInstruction();

void MoveDown();

void MoveUp();

void MoveLeft();

void MoveRight();

void Mix();

bool EndGameIs();

void CheckEndGame();

void TheEnd();

};

Game.cpp

#include "Game.h"

 

Game::Game() {

GameField();

GameField::Mix();

EndGame = false;

};

 

void Game::GetInstruction() {

char c;

c = _getch();

while ((int)c!= 120) { //alt+X

c = _getch();

switch (c) {

case 72: if (EndGame) break; //стрелка вверх

else {

MoveUp(); break;

}

case 80: if (EndGame) break; //стрелка вниз

else {

MoveDown(); break;

}

case 75: if (EndGame) break; //стрелка влево

else {

MoveLeft(); break;

}

case 77: if (EndGame) break; //стрелка вправо

else {

MoveRight(); break;

}

case 114: Mix(); break; //alt+R

default: break;

}

}

}

 

 

void Game::MoveDown() {

if (izero - 1 >= 0) {

++Step;

MoveElements(izero, jzero, izero - 1, jzero);

Draw();

 

}

CheckEndGame();

}

 

void Game::MoveUp() {

if (izero + 1 < 4) {

++Step;

MoveElements(izero, jzero, izero + 1, jzero);

Draw();

 

}

CheckEndGame();

}

 

void Game::MoveRight() {

if (jzero - 1 >= 0) {

++Step;

MoveElements(izero, jzero, izero, jzero - 1);

Draw();

 

}

CheckEndGame();

}

 

void Game::MoveLeft() {

if (jzero + 1 < 4) {

++Step;

MoveElements(izero, jzero, izero, jzero + 1);

Draw();

 

}

CheckEndGame();

}

 

void Game::Mix() {

GameField::Mix();

Step = 0;

EndGame = false;

Draw();

}

 

bool Game::EndGameIs() {

for (int i = 0; i < 4; i++)

for (int j = 0; j < 4; j++)

if (Field[i][j]!= RightField[i][j])

return false;

return true;

}

 

void Game::CheckEndGame() {

EndGame = EndGameIs();

if (EndGame) TheEnd();

}

 

void Game::TheEnd() {

cout << endl;

cout << " Победа! "<< endl;//29-7=22

}

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-06-12 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: