s
Sesiya.ru

Разработка автомата «Морской бой»

Информация о работе

Тема
Разработка автомата «Морской бой»
Тип Курсовая работа
Предмет Программирование
Количество страниц 26
Язык работы Русский язык
Дата загрузки 2015-01-03 08:07:06
Размер файла 149.01 кб
Количество скачиваний 53
Скидка 15%

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

Заполнение заявки не обязывает Вас к заказу


Скачать файл с работой

Помогла работа? Поделись ссылкой

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ
УЧРЕЖДЕНИЕ ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
«МОСКОВСКИЙ АВИАЦИОННЫЙ ИНСТИТУТ
(национальный исследовательский университет)» (МАИ)

Кафедра МиПОИС
«УТВЕРЖДАЮ»
Преподаватель__________
«____»_______________2014 г.






Курсовая работа
на тему: Разработка автомата «Морской бой»
по дисциплине: Объектно-ориентированное программирование





Студентки гр. ДА 2-48__________/ /
«____»_______________2014 г.





Байконур 2014 г.
Содержание


Аннотация…………………………………………………………………………………… 3
1 Постановка задачи (Игра «Инь-Ян»)…………………………………………………….. 4
2 Разработка модели………………………………………………………………………. 5
2.1 Класс Element……………………………………………………………………………. 6
2.2 Класс Field……………………………………………………………………………….. 6
2.3 Взаимодействие классов………………………………………………………………... 7
2.4 UML Диаграмма классов……………………………………………………………….. 8
2.5 Диаграмма состояний классов………………………………………………………….. 8
3 Реализация модели………………………………………………………………………... 9
3.1 Особенности методов класса Element…………………………………………………. 9
3.2 Особенности методов класса Field…………………………………………………….. 10
4 Руководство по использованию………………………………………………………….. 16
4.1 Руководство программиста……………………………………………………………... 16
4.1.1 Идентификаторы методов класса Element…………………………………………... 17
4.1.2 Идентификаторы методов класса Field……………………………………………… 18
4.2 Руководство пользователя…………………………………………………………….... 19
5 Анализ результатов……………………………………………………………………….. 21
Заключение…………………………………………………………………………………... 26
Список литературы………………………………………………………………………….. 27
Приложения………………………………………………………………………………….. 28












Аннотация

В курсовом проекте рассматривается разработка программы работы автомата на языке С++, с использованием объектно-ориентированного проектирования. Разработаны алгоритмы работы автомата. Предусмотренвывод на экран состояний автомата.








1 Постановка задачи(Игра «Морской бой»)

Существует две конфликтующие стороны, каждая имеет равное количество кораблей, соответствующее правилам известной игры: 4 однопалубных, 3 двупалубных, 2 трёхпалубных и 1 четырёхпалубный.
Игровые поля условны.
Стороны производят выстрелы одновременно, стреляют по 10 выстрелов каждая сторона. Попадание в тот или инной корабль происходит случайно, соответственно вероятности попадания.

Вероятность попадания рассчитывается в соответствиями с правилами обычной игры:

• Размер условного поля принять равным ста клеткам;
• Чем больше корабль, тем больше шансов в него попасть. Например, в начале партии шанс попадания в однопалубник 1/100, в четырёхпалубный 4/100;
• После «ранения» вероятность повторного попадания в корабль значительно возрастает (попадание в единожды раненный корабль составляет 1/4, а попадание в раненный более одного раза корабль составляет 1/2;
• Одинаковых выстрелов не бывает, т.е. выстрел в каждую клетку условного
поля противника производится лишь однажды. Вследствие чего вероятность попасть в оставшийся корабль с каждым выстрелом возрастает.

Бой продолжается пока у каждой из сторон есть хотя бы по одному кораблю.

Требования к программам:
• Программа должна быть написана в соответствии с принципами ООП, т.е. основываться на работе с объектами.
• Необходимо продемонстрировать работу системы, с помощью вывода на экран состояний игры.



2 Разработка модели

Для решения задачи, поставленной на курсовое проектирование, использовано два класса основных классаShip и BOT, а так же наследники класса Ship : Ship1,Ship2,Ship3, Ship4, отвечающие за одно/двух/трех/четырехпалубные корабли, соответственно.

2.1 Класс Ship
Класс Shipпредназначен для описаниякорабля и его характеристик, содержит 2 поля:
• int length;
• int numOfBroken;

Поле lengthсодержит длинну корабля, а поле numOfBroken содержит количество подбитых палуб данного корабля.
Методы класса:
• Конструктор с параметрамиShip(int l)
• Метод проверяющий «убит» ли корабль bool isDead()
• Метод «подбить палубу» void attack()
• Метод возвращающий количество целых палуб int countAlive()
• Метод проверяющий «подбит» ли корабль («убитый» не считается «подбитым») bool isBroken()


Конструктор с параметрами создает конкретный корабль.
Остальные методы создают интерфейс работы с кораблем, позволяя инкапсулировать логику хранения данных.

2.2 Классы Ship1, Ship2, Ship3, Ship4
Классы Ship1, Ship2, Ship3, Ship4, наследуют класс Ship, и реализуют функцию attack() для одно/двух/трех/четырехпалубных кораблей, соответственно.

2.3 Класс BOT

Класс BOT предназначен для хранения всех кораблей одной играющей стороны, и расчета попадания по этим кораблям. Он содержит поля :
• Массив кораблей Ship ** my;
• Количество кораблей int countShips;
• Массив для хранения попаданий текущей атаки int * stepAttack;
• Количество попаданий текущей атаки int stepAttackAll
• Количество неподбитых клеток на поле int countPoint;


Методы класса:
• конструктор BOT();
• метод возвращающий количество целых палуб всех кораблей int shipsPoints()
• метод проверяющий потерпела ли играющая сторона поражение bool lose()
• метод возвращающий номер подбитого, корабля, если такой есть int haveBrokenShip()
• метод реализующий текущую атаку, состоящую из numberOfAttacks выстрелов void attackStep(int numberOfAttacks)
• метод реализующий единичный выстрел внутри текущей атаки void attack()
• вывод на экран состояния кораблей (количество убитых, целых, раненных) void printState()

Конструктор создает все корабли играющей стороны, и массив для хранения попаданий атаки, а так же инициализирует значения всех переменных.


2.4 Взаимодействие классов

Для взаимодействия классов использован принцип односторонней ассоциации, в частности агрегирование.

Ассоциация – это самый общий вид связи между объектами, который практически ничего конкретного об этой связи не сообщает. Ассоциация реализуется самыми разными способами, такими как передача объекта в метод класса как аргумент этого метода, или созданием объекта внутри метода класса, и другие способы. Ассоциация происходит, когда объявляется, что свойство класса содержит ссылку на экземпляр (экземпляры) другого класса.

Примеры псевдографического обозначения однонаправленной ассоциации:
| A |<----------| B |. Стрелка указывает на тот класс, от которого зависит другой класс. Так если в классе A есть ссылка на класс B, но не наоборот, то тогда эта связь должна обозначаться так: | A |--------->| B |

Агрегирование ещё называют «отношением принадлежности» или «агрегированием по ссылке».Агрегирование, как и Композиция – это однонаправленная ассоциация, имеющая смысл Целое-Часть. Целое в этом случае имеет внутри себя ссылку на часть, а часть не имеет внутри себя ссылку на целое. При этом часть может в один момент времени находиться только в одном целом. В агрегации оба объекта могут существовать независимо: если контейнер будет уничтожен, то его содержимое — нет.

Так класс BOT содержит в себе указатель на указатель типа Ship.









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

Рисунок 2.4 – UML диаграмма классов


3 Реализация модели

Модель работы автомата реализована с использованием основных принципов ООП, а именно агрегирования и инкапсуляции.

Класс Ship является базовым классом, для классов Ship1,Ship2,Ship3,Ship4, которые реализуют хранение конкретных единиц кораблей, и отслеживание их состояния.
Класс BOT хранит все корабли играющей стороны, как следствие, состояние всей играющей стороны. А так же реализует пошаговое изменение этого состояния, в соответствии с правилами игры.

3.1 Особенности методов класса Ship (и наследников)

Конструктор с параметрами Ship(int l) создает экземпляр корабля длинны l, со всеми целыми палубами.
Конструкторы по умолчанию наследников класса Ship вызывают конструктор класса Ship с соответсвующим параметром :
Ship1() : Ship(1){}

Метод bool isDead() проверяет, подбиты ли все палубы данного корабля :
return (numOfBroken == length);

Методvoidattack() реализует попадание в палубу данного корабля, увеличивая количество подбитых палуб (numOfBroken++), и выводя соответсвующее сообщение об количестве оставшихся палуб или о гибели корабля :
cout<< "Попадание в " <<length<< " палубник : ";
if (length-numOfBroken == 0) cout << "Убит!"<<endl;
else cout <<"Осталось палуб :"<< length-numOfBroken << endl;

Метод voidattack() реализуется отдельно в каждом наследнике, класса Ship, поэтому приведенный выше код, никогда не используется, НО структура метода для каждого наследника в точности повторяет структуру базового класса.

Метод int countAlive() возвращает количество целых палуб корабля (return length-numOfBroken;)

Метод bool isBroken() проверяет подбит ли корабль, причем, если корабль уже мертв, то он не является подбитым. Т.е. если на корабле есть подбитые палубы, причем не все палубы подбиты, то возвращается true, иначе false (return ((countAlive()) % length != 0);)

3.2 Особенности методов класса BOT

Конструктор по умолчанию класса BOT создает массив кораблей, а так же заполняет его кораблями :
my = new Ship* [10];
int k=0;

Четырьмя однопалубными :
for (int i =0; i < 4; i++) my[k++]=new Ship1();
Тремя двухпалубными :
for (int i =0 ; i < 3; i++) my[k++]=new Ship2();
Двумя трехпалубными :
for (int i =0; i < 2; i++) my[k++]=new Ship3();
Одним четырехпалубным :
my[k++] = newShip4();

А так же инициализирует переменные и создает массив для записи попаданий текущей атаки.

Метод int haveBrokenShip() проверяет по порядку все корабли и находит первый «подбитый», который не добит во время текущей атаки (my[i]->isBroken() && (my[i]->countAlive() - stepAttack[i])) и возвращает его порядковый номер в массиве кораблей.






4 Руководство по использованию


4.1 Руководство программиста

Для работы алгоритма использованы следующие библиотеки и простора имен:
• библиотека ввода/вывода iostream для работы с <<, >>;
• библиотека ctime для работы stime(), rand();
• Библиотека conio.hдля работы getch()
• пространство имен std для работы с cin, cout, endl.


Корректную работу функции rand(), а именно генерация новых «случайных» значений при каждом последующем запуске программы отвечает функция:
srand(unsigned(time(NULL)));


Объекты классов Element, Field создаются согласно синтаксисом: Тип название_объекта.Используются только указатели на объекты. Методы объектов вызываются при помощи оператора “->” (название_объекта->Метод_объекта() ). Следует обратить внимание, что для класса Ship не существует конструктора по умолчанию, но конструкторы по умолчанию реализуются во всех наследственных классах.

Для работы использованы следующие типы переменных:
Таблица 4.1.1 — Используемые типы данных
Тип байт Диапазон принимаемых значений
bool 1 0 / 255
char 1 0 / 255
int 4 -2 147 483 648 /
2 147 483 647
Ship(int , int) 4+4=8 _______________
BOT ( Ship **, int ,int *, int ,int) 4*5=20 _______________


4.1.1 Идентификаторы методов класса Ship

Таблица 4.1.1.1 – Идентификаторы конструктора класса Ship
Переменная Тип Назначение
l int Длинна корабля


4.1.2 Идентификаторы методов класса BOT
Таблица 4.1.1.1 – Идентификаторыметода attackStep
Переменная Тип Назначение
numberOfAttacks int Количество выстрелов, произведенных в текущую атаку


4.2 Руководство пользователя

Длязапускапрограммызапуститефайлships.exeизпапкиC:ProgramFilesBorlandBuilder6Projects .

Далее программа будет пошагово выводить информацию о процессе игры двух сторон. Для перехода к следующему шагу необходимо будет нажимать клавишу ENTER.
После победы одной из сторон или при ничье программа выведет сообщение о завершении битвы. Необходимо будет нажать клавишу ENTERдля выхода из программы.

5 Демонстрация работы программы

Заключение

В результате курсового проектирования разработана программа, работы автомата – игры «Морской бой».
Учтены все условия работы автомата:
1. Рождение. У пустой ячейки ровно три соседа (живых) и они не все одинаковые, то в ней рождается Ян, когда среди соседей только один Ян, или Инь, когда среди соседей только один Инь.
2. Гибель от перенаселения (одиночества). Живая ячейка, имеющая больше четырех (меньше двух) соседей, умирает от перенаселения (от одиночества);
3. Гибель в неравном противостоянии. У живой ячейки ровно четыре соседа, из которых большинство – противоположного типа – ячейка умирает.
Организован пошаговый вывод результатов работы программы на экран компьютера.
Программа написана в соответствии с принципами ООП, а именно на принципах инкапсуляции, агрегирования, работе с объектами.
Приведена демонстрация работы программы.




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

1. Рамбо Дж., Блаха М. UML 2.0. Объктно-ориентриованное моделирование и разаботка. 2-изд. – СПб.: Питер, 2007. – 544 с.: ил.
2. КалвертЧ., РейсдорфК., BorlandC++ Builder 5. Энциклопедия программиста. "ДиаСофт" - 2001, 944 стр.
3. Н. Б. Культин, С/С++ в задачах и примерах. СПб: БХВ-Петербург, 2001,- 854 стр.
4. Основы объектно-ориентированного программирования. Язык программирования С++/ Волкова И. А., Иванов А. В., Карпов Л. Е. - Учебное пособие для студентов 2 курса. - М.: Издательский отдел факультета ВМК МГУ (лицензия ИД №05899 от 24.09.2001), 2011 – 112 с.
5. http://www.codenet.ru/





















Приложение А
(обязательное)

Листинг программы
#include<ctime>
#include<iostream>
#include<conio.h>


usingnamespace std;

classShip
{
public :
int length; // длинна корабля
int numOfBroken; // количество подбитых палуб

Ship(intl)
{
numOfBroken = 0;
this->length = l;
}

boolisDead() // корабль погиб, если подбиты все палубы
{
return (numOfBroken == length);
}

voidattack() // подбить одну палубу корабля, вывести сообщение
{
numOfBroken++;
cout<<"Попадание в "<<length<<" палубник : ";
if (length-numOfBroken == 0) cout <<"Убит!"<<endl;
else cout <<"Осталось палуб :"<< length-numOfBroken << endl;
}

intcountAlive() // количество целых палуб
{
returnlength-numOfBroken;
}

boolisBroken() // подбит ли корабль (погибший не считаем)
{
return ((countAlive()) % length != 0);
}
};

classShip1 : publicShip// класс однопалубника
{
public :
Ship1() : Ship(1)
{
}

void attack()
{
numOfBroken++;
cout<<"Попадание в однопалубник : ";
cout<<"Убит!"<<endl;
}

};

classShip2 : publicShip// класс двухпалубника
{
public :
Ship2() : Ship(2)
{
}

void attack()
{
numOfBroken++;
cout<<"Попадание в двухпалубник : ";
if (numOfBroken == 2) cout <<"Убит!"<<endl;
else cout <<"Осталось палуб :"<< countAlive() << endl;
}

};

classShip3 : publicShip// класс трехпалубника
{
public :
Ship3() : Ship(3)
{
}

void attack()
{
numOfBroken++;
cout<<"Попадание в трехпалубник : ";
if (numOfBroken == 3) cout <<"Убит!"<<endl;
else cout <<"Осталось палуб :"<< countAlive() << endl;
}

};

classShip4 : publicShip// класс четырехпалубника
{
public :
Ship4() : Ship(4)
{
}

void attack()
{
numOfBroken++;
cout<<"Попадание в четырехпалубник : ";
if (numOfBroken == 4) cout <<"Убит!"<<endl;
else cout <<"Осталось палуб :"<< countAlive() << endl;
}

};

classBOT
{
public :
Ship ** my; // массив кораблей
intcountShips; // количество кораблей (=10)
int * stepAttack; // запоминаем попадания текущей атаки, т.к. вероятность попадания в подбитый корабль меняется только к следующей атаке
intstepAttackAll; // количество попаданий в текущей атаке
intcountPoint; // количество неподбитых клеток на поле


intshipsPoints() // количество клеток неподбитых клеток кораблей
{
int ans =0;
for (int i = 0; i < countShips; i++)
ans += my[i]->countAlive();
return ans-stepAttackAll;
}

boollose() // проверка на поражение ( не осталось неподбитых клеток кораблей)
{
returnshipsPoints()==0;
}

voidprintState()
{
cout<<"Количество целых клеток поля : "<<countPoint<<endl;
int half = 0, die = 0, full = 0;
for (int i =0 ; i < countShips; i++)
if (my[i]->isBroken()) half++;
elseif (my[i]->isDead()) die++;
else full++;
cout<<" Целых кораблей : "<< full << endl;
cout<<" Подбитых кораблей : "<< half << endl;
cout<<" Убитых кораблей : "<< die << endl;
cout<<"Всего цельных палуб : "<<shipsPoints() <<endl;
}

BOT() // инициализация
{
my = newShip* [10];
stepAttack = newint[10];
countShips = 10;
countPoint=100;
// очищаем сохранение попаданий
for (int i = 0 ; i< countShips;i++)
stepAttack[i] = 0;
stepAttackAll = 0;

// создаем корабли
int k=0;
for (int i =0; i < 4; i++) my[k++]=newShip1();
for (int i =0 ; i < 3; i++) my[k++]=newShip2();
for (int i =0; i < 2; i++) my[k++]=newShip3();
my[k++] = newShip4();
}

inthaveBrokenShip() // есть ли подбитые ( не погибшие) корабли, для которых действует особая вероятность попадания
{
for (int i = 0; i < countShips; i++)
if (my[i]->isBroken() && (my[i]->countAlive() - stepAttack[i]))
return i;
return -1;
}

void attackStep(intnumberOfAttacks) // текущая атака ( numberOfAttacks -- количество выстрелов произведенных в эту атаку)
{

//рассчитываем все выстрелы
for (int i = 0; i <numberOfAttacks; i++)
{
attack();
if (lose()) break;
}
// применяем попадания к кораблям
for (int i =0 ; i < countShips; i++)
for (int j =0 ; j < stepAttack[i]; j++)
my[i]->attack();

// очищаем сохранение попаданий
for (int i = 0 ; i< countShips;i++)
stepAttack[i] = 0;
stepAttackAll = 0;

printState();

}

void attack() // один выстрел текущей атаки
{
intbr = haveBrokenShip();
if (br>= 0) // если есть подбитые корабли, то противник стреляет по ним
{
if (my[br]->numOfBroken> 1) // если у корабля > 1 подбитой палубы, то вероятность 1/2
{
int p = rand()%2;
if (!p)
stepAttack[br]++; // записываем попадание
}
else// если 1 подбитая палуба, то вероятность 1/4
{
int p = rand()%4;
if (!p)
stepAttack[br]++; // записываем попадание
}
}
else// если подбитых нет, то все точки равновероятны
{
intp = rand()%countPoint;
if (p<shipsPoints()) // если попадание произошло, то расчитываем корабль в который попали, вероятность попадания в корабль = количество его палуб/общее количество клеток кораблей
{
for (int i =0; i < countShips; i++) //
{
p -= (my[i]->countAlive()-stepAttack[i]);
if (p < 0) {
stepAttack[i]++;
break;
}
}
}
}
countPoint--; // уменьшаем количество неподбитых клеток поля
}
};


int main()
{
setlocale(LC_ALL,"Russian" );
srand(unsignedint(time(NULL)));
BOT * kek1 = newBOT;
BOT * kek2 = newBOT;
int num = 1;
while (!kek1->lose() && !kek2->lose())
{
cout <<"ХОД "<< num << endl << endl;
num++;
cout<<"Атака по 1му игроку : "<<endl;
kek1->attackStep(10);
cout<<endl <<"Атака по 2му игроку : "<< endl;
kek2->attackStep(10);
cout<<endl<<"Нажмите ENTER для перехода к следующему ходу!"<<endl<< endl;
char c;
while ((c=getch()) != 13);
cout<<"----------------------------"<< endl << endl << endl;
}
if (kek1->lose())
if (kek2->lose())
cout<<"НИЧЬЯ!"<<endl;
else
cout<<"ВЫЙГРАЛ 2й!"<<endl;
else
cout<<"ВЫЙГРАЛ 1й!"<<endl;
getchar();
return 0;
}













Приложение Б
(обязательное)

Результаты работы программы

© Copyright 2012-2020, Все права защищены.