Логическая игра "Морской бой"

Тип работы:
Курсовая
Предмет:
Программирование


Узнать стоимость

Детальная информация о работе

Выдержка из работы

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ

РОССИЙСКОЙ ФЕДЕРАЦИИ

Федеральное государственное бюджетное образовательное учреждение

высшего профессионального образования

«НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ ТОМСКИЙ ПОЛИТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»

Институт дистанционного образования

Кафедра Автоматики и компьютерных систем

Направление «Управление в технических системах»

Пояснительная записка к курсовой работе

по дисциплине

«Объектно-ориентированное программирование»

Студент гр. З-8001 Поспелова И. В.

Ассистент каф. АиКС Татарский Ф. Е.

Томск — 2013

Оглавление

Введение

1. Задание на курсовую работу

2. Правила игры

2.1 Описание классов игры

3. Описание работы приложения

Заключение

Список использованных источников

Приложение А

Введение

Компьютерные и видео игры — это самое новое, молодое и бурно развивающееся искусство. Цифровая эпоха породила компьютерные игры так же, как эпоха машин породила искусство кинематографии. Игры открывают нам новые эстетические опыты, превращая экран монитора в область экспериментирования и инноваций, доступных каждому. Они открывают широкой публике мир цифрового искусства.

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

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

Целью данной курсовой работы была разработка кроссплатформенной игры «Морской бой». В качестве языка программирования был взят язык программирования С++, так как это чрезвычайно мощный язык, содержащий средства создания эффективных программ практически любого назначения, от низкоуровневых утилит и драйверов до сложных программных комплексов самого различного назначения. Также С++ дает возможность разрабатывать программы для самых различных платформ и систем.

В качестве инструмента кроссплатформенной разработки мною была выбрана библиотека qt и среда разработки qt creator. Qt предоставляет программисту не только удобный набор библиотек классов, но и определённую модель разработки приложений, определённый каркас их структуры. Следование принципам и правилам «хорошего стиля программирования на C++/Qt» существенно снижает частоту таких трудно отлавливаемых ошибок в приложениях, как утечки памяти (memory leaks), необработанные исключения, незакрытые файлы или неосвобождённые дескрипторы ресурсных объектов.

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

1 Задание на курсовую работу

Разработать программу — компьютерную логическую игру. В результате выполнения данной работы студенты осваивают приемы практического использования объектно-ориентированного подхода в создании законченного программного продукта:

· Реализующую выбранную компьютерную логическую игру;

· Обладающего графическим интерфейсом пользователя;

· Удовлетворяющего требованию переносимости на кровне исходного кода;

· Простого в установке и обслуживании.

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

· Начало игры на чистом поле, сброс предыдущей игры;

· Выбор противника (человек, компьютер), если применимо;

· Сохранение текущей игры в любой момент игры в файл, восстановление состояния игры из файла;

· Отмену хода (если применимо);

· Подсказку следующего хода (если применимо);

· Контроль правильности хода игрока (ов);

· Определение конца игры, отслеживание патовых ситуаций;

· Возможность задания произвольного размера поля (если применимо);

· Возможность визуального редактирования уровней (если применимо);

· Управление как с клавиатуры, так и мышью;

· Настройку клавиш управления;

· Использование горячих клавиш;

· Возможность задания настроек в конфигурационном файле или реестре Windows;

· Индикацию текущего счета (если применимо);

· Ведение списка чемпионов для каждого размера поля;

· Выбор уровня сложности игры (если применимо);

· Вынесение графических элементов (курсоры, иконки, спрайты) в ресурсный файл (если применимо);

· Наличие инсталлятора (показ лицензии, выбор устанавливаемых компонентов, выбор пути установки и т. п.).

Логическая игра «Морской бой».

Разрабатываемое приложение представляет собой программную реализацию известной логической игры. Приложение должно обеспечивать:

· Расстановку кораблей на игровом поле 10×10;

· Выбор противника (человек, компьютер);

· Изменение интерфейса в зависимости от выбора противника;

· Фиксацию имен противников и число побед.

2. Правила игры

«Морской бой» -- игра для двух участников, в которой игроки по очереди называют координаты на неизвестной им карте соперника. Если у соперника по этим координатам имеется корабль (координаты заняты), то корабль или его часть «топится», а попавший получает право сделать ещё один ход. Цель игрока -- первым поразить все корабли противника.

Игровое поле -- квадрат 10?10 каждого игрока (рисунок 1), на котором размещается флот кораблей.

Рисунок 1

Горизонтали обычно нумеруются сверху вниз, а вертикали помечаются буквами слева направо. При этом используются буквы русского алфавита от «а» до «к» (буквы «ё» и «й» обычно пропускаются), либо буквы латинского алфавита от «a» до «j».

На поле размещаются:

· 1 корабль -- ряд из 4 клеток («линкоры», или «четырёхпалубные»)

· 2 корабля -- ряд из 3 клеток («крейсеры», или «трёхпалубные»)

· 3 корабля -- ряд из 2 клеток («эсминцы», или «двухпалубные»)

· 4 корабля -- 1 клетка («подлодки», или «однопалубные»)

Палубы корабля не могут строиться по диагонали. При размещении корабли не могут касаться друг друга углами.

Рядом со «своим» полем чертится «чужое» такого же размера, только пустое. Это участок моря, где плавают чужие корабли противника.

При попадании в корабль противника -- на чужом поле ставится крестик, при промахе — точка. При попадании попавший игрок стреляет ещё раз.

Игра считается законченной, когда будут убиты все корабли одного из противников.

2.1 Описание классов игры

1) Класс Ships. Представляет собой абстрактный класс, описывающий корабли. Класс содержит в себе:

— целочисленную переменную amountDeck, в которую будет записываться количество палуб для каждого корабля в игре.

— целочисленный двумерный массив location, в который будут записываться координаты палуб для каждого корабля на игровом поле.

2) Класс BattleShip. Наследуется от Ships, характеризует четырехпалубный корабль.

3) Класс Cruiser. Наследуется от Ships, характеризует трехпалубный корабль.

4) Класс Destroyer. Наследуется от Ships, характеризует двухпалубный корабль.

5) Класс Boat. Наследуется от Ships, характеризует однопалубный корабль.

6) Класс Field. Является абстрактным классом. Описывает игровое поле.

В программе игровое поле представляет собой целочисленную матрицу размером 10×10. Элементы матрицы могут принимать 4 различных значения:

— «- 1» — пустая клетка;

— «0» — клетка является палубой корабля;

— «1» — палуба подбита;

— «2» — в эту позицию стреляли, но промахнулись.

На основании данных этой матрицы осуществляется графическая прорисовка игровых полей.

В классе Field описаны следующие функции:

— Функция прорисовки пустого игрового поля.

— Функция формирования матрицы игрового поля.

— Функция загрузки и прорисовки загруженного игрового поля.

— Функции, осуществляющие построение кораблей для каждого игрока

— Функции формирования массивов локации для каждого корабля.

— Функции сохранения игрового поля и координат локации для каждого корабля.

— Функцию, осуществляющую стрельбу игроком-человеком.

— Функции, обрабатывающие попадания, промахи и окончание игры в процессе стрельбы.

— Функции, осуществляющие проверку на гибель корабля в случае попадания.

7) Класс PlayerField. Наследуется от класса Field и описывает поле игрока-человека.

8) Класс EnemyField. Наследуется от класса Field и описывает поле игрока-компьютера.

9) Класс PutName. Представляет собой виджет для ввода имен игроков и передачу этих имен в другие классы программы.

10) Класс SelectMode. Представляет собой виджет для выбора режима игры: человек-человек или человек-компьютер. Передает данные о выбранном режиме игры в другие классы программы для дальнейшей обработки.

11) Класс StartWidget. Представляет собой виджет, который выводится на экран при запуске игры. Виждет предлагает выбрать игроку один из следующих пунктов:

— Начать новую игру. При выборе данного пункта, игроку предоставляется возможность выбрать режим игры, ввести имена игроков и начать новую игру на чистом игровом поле.

— Загрузить игру. При выборе этого пункта откроется файловый диалог, предлагающий игроку загрузить ранее сохраненную игру. После выбора соответствующего файла, игрок сможет продолжить игру с момента сохранения.

— Выход. При выборе этого пункта произойдет закрытие игры.

12) Класс MainWindow. Представляет собой виджет, описывающий основное окно игры. Содержит в себе два игровых поля: поле игрока и поле соперника и меню игры со следующими пунктами:

а) Пункт «Игра». Содержит в себе следующие подпункты:

— Новая. При выборе этого пункта будет предложено сохранить текущую игру, после чего игроку будет предоставлена возможность начать новую игру на чистом игровом поле в соответствии с выбранным режимом игры.

— Сохранить. При выборе этого пункта откроется файловый диалог, предлагающий игроку сохранить игру в выбранном месте под выбранным именем.

— Загрузить. При выборе этого пункта игроку будет предложено сохранить текущую игру. Затем откроется файловый диалог, предлагающий выбрать и загрузить файл сохраненной ранее игры.

— Выход. При выборе этого пункта игроку будет предложено сохранить текущую игру, после чего произойдет завершение приложения.

б) Пункт «Справка». Содержит в себе следующие подпункты:

— О программе. При выборе этого пункта на экране появится сообщение с названием программы и именем разработчика.

— Как играть. При выборе этого пункта на экране появится окно, содержащее в себе правила игры.

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

3. Описание работы приложения

При установке игры пользователь выбирает пусть установки игры (рисунок 2).

Рисунок 2

При старте игры на экране появляется окно, изображенное на рисунке 3, предлагающее игроку сделать выбор.

Рисунок 3

Если игрок решил начать новую игру, на экране появится сообщение, изображенное на рисунке 4, предлагающее выбрать режим игры.

Рисунок 4

После того, как режим игры был выбран, Игроку необходимо ввести свое имя (рисунок 5).

Рисунок 5

Далее игроку необходимо расставить на своем поле корабли (рисунок 6, рисунок 7).

Рисунок 6

Рисунок 7

Если при расстановке кораблей игрок попытается поставить корабль не по правилам, то он будет предупрежден выводом на экран сообщения (Рисунок 8).

Рисунок 8

Если игра идет в режиме человек-человек, то игроки расставляют свои корабли по очереди, после чего экран затемняется и начинается игра (Рисунок 9).

Рисунок 9

Если игра идет в режиме человек-компьютер, то экран не затемняется (рисунок 10).

Рисунок 10

При победе одного из игроков на экран выводится соответствующее сообщение (рисунок 11)

Рисунок 11

Если игрок пожелает сохранить или загрузить игру, то при выборе соответствующего пункта меню на экран будет выведен файловый диалог соответственно для сохранения или для загрузки файла (рисунок 12).

Рисунок 12

При выборе в меню справки пункт «О программе», игрок может получить информацию о приложении (рисунок 13)

Рисунок 13

Если игрок пожелает ознакомиться с правилами игры, он может выбрать в меню справки пункт «Как играть», после чего на экране появится соответствующее окно (рисунок 14)

Рисунок 14

Заключение

В ходе выполнения курсовой работы были закреплены и углублены навыки использования объектно-ориентированного подхода к программированию.

При помощи языка C++ и библиотеки Qt было спроектировано и разработано готовое кроссплатформенное приложение, соответствующее всем требованиям поставленной задачи.

Приложение осуществляет расстановку кораблей на игровом поле 10×10, предоставляет выбор противника, осуществляет сохранение и загрузку игры из файла. Также в игре отслеживается правильность ходов, правильность расстановки кораблей и момент окончания игры. Приложение обеспечивает возможность начать новую игру на чистом поле и сброс предыдущей игры.

Помимо этого, настройки игры вынесены в конфигурационный файл settings. conf и загружаются в программу из него.

Также при помощи программы WinRar был сделан инсталлятор, позволяющий выбрать путь распаковки приложения.

кроссплатформенный компьютерной игра класс

Список использованных источников

1. «Qt 4.5. Профессиональное программирование на С++» М. Шлее — СПб.: БХВ-Петербург, 2010. 896 с.

2. «С++: руководство для начинающих» Г. Шилдт — М.: Издательский дом «Вильямс», 2005. 672 с.

3. «Qt 4: программирование GUI на С++» Ж. Бланшет, М. Саммерфилд — М.: КУДИЦ-ПРЕСС, 2008. 736 с.

4. «Язык программирования С++. Лекции и упражнения» С. Прата — М.: ООО «И.Д. Вильямс», 2012. 1248 с.

Приложение А

Исходный текст программы

Файл battleship. h

#ifndef BATTLESHIP_H

#define BATTLESHIP_H

#include «ships. h»

class BattleShip: public Ships

{

public:

BattleShip ();

~BattleShip ();

};

#endif // BATTLESHIP_H

Файл battleship. cpp

#include «battleship. h»

BattleShip: :BattleShip ()

{

int i;

amountDeck=4;

location = new int*[amountDeck];

for (i=0; i<amountDeck;i++)

location[i]=new int[2];

}

BattleShip: :~BattleShip ()

{

int i;

for (i=0; i<amountDeck;i++)

delete[] location[i];

delete[] location;

}

Файл boat. h

#ifndef BOAT_H

#define BOAT_H

#include «ships. h»

class Boat: public Ships

{

public:

Boat ();

~Boat ();

};

#endif // BOAT_H

Файл boat. cpp

#include «boat. h»

Boat: :Boat ()

{

int i;

amountDeck=1;

location = new int*[amountDeck];

for (i=0; i<amountDeck;i++)

location[i]=new int[2];

}

Boat: :~Boat ()

{

int i;

for (i=0; i<amountDeck;i++)

delete[] location[i];

delete[] location;

}

Файл cruiser. h

#ifndef CRUISER_H

#define CRUISER_H

#include «ships. h»

class Cruiser: public Ships

{

public:

Cruiser ();

~Cruiser ();

};

#endif // CRUISER_H

Файл cruiser. cpp

#include «cruiser. h»

Cruiser: :Cruiser ()

{

int i;

amountDeck=3;

location = new int*[amountDeck];

for (i=0; i<amountDeck;i++)

location[i]=new int[2];

}

Cruiser: :~Cruiser ()

{

int i;

for (i=0; i<amountDeck;i++)

delete[] location[i];

delete[] location;

}

Файл dectroyer. h

#ifndef DESTROYER_H

#define DESTROYER_H

#include «ships. h»

class Destroyer: public Ships

{

public:

Destroyer ();

~Destroyer ();

};

#endif // DESTROYER_H

Файл dectroyer. cpp

#include «destroyer. h»

Destroyer: :Destroyer ()

{

int i;

amountDeck=2;

location = new int*[amountDeck];

for (i=0; i<amountDeck;i++)

location[i]=new int[2];

}

Destroyer: :~Destroyer ()

{

int i;

for (i=0; i<amountDeck;i++)

delete[] location[i];

delete[] location;

}

Файл enemyfield. h

#ifndef ENEMYFIELD_H

#define ENEMYFIELD_H

#include «field. h»

class EnemyField: public Field

{

Q_OBJECT

public:

EnemyField ();

~EnemyField ();

void calcPos ();

void buildShips (int size);

void mousePressEvent (QMouseEvent *event);

signals:

void EFSignal ();

public slots:

void autoBuild ();

};

#endif // ENEMYFIELD_H

Файл enemyfield. hcpp

#include «enemyfield. h»

EnemyField: :EnemyField ()

{

this-> setScene (&scene);

}

void EnemyField: :calcPos ()

{

jShip = (rand () % 9+0)+1;

iShip = (rand () % 9+0)+1;

}

void EnemyField: :mousePressEvent (QMouseEvent *event)

{

int x, y;

x = event-> pos (). x ()-30;

y = event-> pos (). y ()-20;

if (event-> button ()==Qt:LeftButton)

{

if (x> =30&&x<=330&&y>=30&&y<=330)

{

iShip=y/30;

jShip=x/30;

emit startFight ();

}

}

}

void EnemyField: :autoBuild ()

{

int l;

size=4;

buildShips (size);

for (l=0; l<2;l++)

{

amount=0;

size=3;

buildShips (size);

}

for (l=0; l<3;l++)

{

amount=0;

size=2;

buildShips (size);

}

for (l=0; l<4;l++)

{

amount=0;

size=1;

buildShips (size);

}

amount=10;

}

void EnemyField: :buildShips (int size)

{

while (amount≠1)

{

calcPos ();

selectShip (flag, t, size);

}

}

EnemyField: :~EnemyField ()

{

}

Файл field. h

#ifndef FIELD_H

#define FIELD_H

#include < QtGui>

#include < QApplication>

#include < QSettings>

#include «battleship. h»

#include «cruiser. h»

#include «destroyer. h»

#include «boat. h»

class Field: public QGraphicsView

{

Q_OBJECT

public:

Field ();

~Field ();

QGraphicsScene scene;

void paintField (QColor Bcolor, QColor Lcolor);

int player[10][10];

int iShip, jShip;

int size;

int amount;

int flag;

int t;

int move;

int thI, twI, oI;

int K;

int f;

int lhit, h;

int M[4][2];

int sizeField, sizeDeck;

QColor lColor, bColor, deckColor, hitColor;

BattleShip fourDeck;

Cruiser threeDeck[2];

Destroyer twoDeck[3];

Boat oneDeck[4];

virtual void calcPos (int x, int y); //сопоставляет позицию нажатия ЛКМ с player[][]

void loadField (QColor lColor, QColor bColor, QColor deckColor, QColor hitColor); //выгружает player[][] на игровое поле

void save (QByteArray & array);

void saveShips (QByteArray & array);

void supSaveShips (QByteArray & array, int s, int **m);

void matrix ();

signals:

void completed ();

void startFight ();

void endFight ();

void miss ();

void hit ();

public slots:

void fire ();

protected:

void selectShip (int & flag, int & t, int & size); //выделяет палубы для окончательной прорисовки

void paintShip (int size, QColor lColor, QColor deckColor); //заполняет player[][]

bool checkPosition (); //проверяет, можно ли поставить палубу

void wound (int i, int j, QColor lColor, QColor hitColor); //обрабатывает попадание в корабль

void past (QColor lColor, int i, int j); //обрабатывает промах

void paintDeck (QColor lColor, QColor deckColor, int i, int j); //рисует палуьбы

void getLocation (int size, int i, int j, int locI); //записывает координаты палоб для каждого корабля

void checkDeath (int i, int j); //проверка на уничтожение корабля

void supCheck (int sizeShip, int **a); //вспомогательная

void paintPoints (int sizeShip, int **a, QColor lColor);

};

#endif // FIELD_H

Файл field. cpp

#include «field. h»

Field: :Field ()

{

size=-1;

amount=0;

thI=0;

twI=0;

oI=0;

move=0;

K=0;

lhit=0;

h=0;

f=0;

flag=0;

t=0;

QString path=QApplication: :applicationDirPath ()+"/settings. conf";

QSettings *settings = new QSettings (path, QSettings: :IniFormat);

sizeField = settings-> value («settings/sizeField»). toInt ();

qDebug ()< <sizeField;

sizeDeck = settings-> value («settings/sizeDeck»). toInt ();

matrix ();

}

void Field: :paintField (QColor Bcolor, QColor Lcolor)

{

int i, j;

char ch;

QString str;

QGraphicsTextItem *numbers, *letters;

scene. setBackgroundBrush (QBrush (Bcolor));

//------прорисовка поля-------------------------------------

for (i=30; i<330;i=i+30)

for (j=30; j<330;j=j+30)

scene. addRect (j, i, sizeDeck, sizeDeck, QPen (Lcolor), QBrush (Bcolor));

//----------------------------------------------------------

//---------прорисовка букв и цифр---------------------------

for (i=1; i< =sizeField;i++)

{

numbers = scene. addText (QString:number (i));

numbers-> setDefaultTextColor (Lcolor);

numbers-> setPos (5, i*sizeDeck);

}

i=1;

for (ch='A'; ch< ='J';ch++)

{

str=ch;

letters = scene. addText (str);

letters-> setDefaultTextColor (Lcolor);

letters-> setPos ((i+0. 3)*sizeDeck, 0);

i++;

}

//----------------------------------------------------------

}

void Field: :matrix ()

{

int i, j;

for (i=0; i<sizeField;i++)

for (j=0; j<sizeField;j++)

player[i][j]=-1;

}

void Field: :calcPos (int x, int y)

{

}

void Field: :loadField (QColor lColor, QColor bColor, QColor deckColor, QColor hitColor)

{

int i, j;

paintField (bColor, lColor);

for (i=0; i<sizeField;i++)

for (j=0; j<sizeField;j++)

{

if (player[i][j]==0)paintDeck (lColor, deckColor, i, j);

else if (player[i][j]==2)past (lColor, i+1, j+1);

else if (player[i][j]==1)wound (i+1, j+1, lColor, hitColor);

}

}

bool Field: :checkPosition ()

{

int i, j, f, iStart, jStart, jFinish, iFinish;

f=0;

i=iShip-1;

j=jShip-1;

if (i==0)iStart=0;

else iStart = i-1;

if (j==0)jStart=0;

else jStart=j-1;

if (i==9)iFinish=9;

else iFinish=i+1;

if (j==9)jFinish=9;

else jFinish=j+1;

if (player[iShip-1][jShip-1]==size)f=1;

for (i=iStart; i< =iFinish; i++)

for (j=jStart; j< =jFinish; j++)

if (player[i][j]==0)f=1;

if (f≠0)return false;

else return true;

}

void Field: :selectShip (int & flag, int & t, int & size)

{

int i, j, f, iStart, jStart, jFinish, iFinish;

f=0;

if (flag< size)

{

i=iShip-1;

j=jShip-1;

if (i==0)iStart=0;

else iStart = i-1;

if (j==0)jStart=0;

else jStart=j-1;

if (i==9)iFinish=9;

else iFinish=i+1;

if (j==9)jFinish=9;

else jFinish=j+1;

if (checkPosition ())

{

if (t≠1)

{

scene. addRect (jShip*sizeDeck, iShip*sizeDeck, sizeDeck, sizeDeck, QPen (Qt: :red, 1));

player[iShip-1][jShip-1]=size;

f=1;

t=1;

}

for (i=iStart; i<=iFinish;i++)

for (j=jStart; j<=jFinish;j++)

{

if (player[i][j]==size)

{

if ((i==iShip-1& &j≠jShip-1)||(i≠iShip-1&&j==jShip-1))

{

scene. addRect (jShip*sizeDeck, iShip*sizeDeck, sizeDeck, sizeDeck, QPen (Qt: :red, 1));

player[iShip-1][jShip-1]=size;

f=1;

}

}

}

if (f≠0)flag++;

if (flag==size)

{

paintShip (size, lColor, deckColor);

t=0;

flag=0;

if (size==3)thI++;

else if (size==2)twI++;

else if (size==1)oI++;

emit completed ();

amount++;

}

}

}

}

void Field: :paintShip (int size, QColor lColor, QColor deckColor)

{

int i, j;

int locI=0;

for (i=0; i<sizeField;i++)

for (j=0; j<sizeField;j++)

if (player[i][j]==size)

{

paintDeck (lColor, deckColor, i, j);

player[i][j]=0;

getLocation (size, i, j, locI);

locI++;

}

}

void Field: :getLocation (int size, int i, int j, int locI)

{

if (size==4)

{

fourDeck. location[locI][0]=i;

fourDeck. location[locI][1]=j;

}

else if (size==3)

{

threeDeck[thI]. location[locI][0]=i;

threeDeck[thI]. location[locI][1]=j;

}

else if (size==2)

{

twoDeck[twI]. location[locI][0]=i;

twoDeck[twI]. location[locI][1]=j;

}

else if (size==1)

{

oneDeck[oI]. location[0][0]=i;

oneDeck[oI]. location[0][1]=j;

}

}

void Field: :save (QByteArray & array)

{

int i, j;

for (i=0; i<sizeField;i++)

{

for (j=0; j<sizeField;j++)

array. append (QString:number (player[i][j]));

array. append («n»);

}

}

void Field: :saveShips (QByteArray & array)

{

int i;

supSaveShips (array, 4, fourDeck. location);

for (i=0; i<2;i++)

supSaveShips (array, 3, threeDeck[i]. location);

for (i=0; i<3;i++)

supSaveShips (array, 2, twoDeck[i]. location);

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

supSaveShips (array, 1, oneDeck[i]. location);

}

void Field: :supSaveShips (QByteArray & array, int s, int **m)

{

int i;

for (i=0; i<s;i++)

{

array. append (QString:number (m[i][0]));

array. append (««);

array. append (QString:number (m[i][1]));

array. append («n»);

}

}

void Field: :fire ()

{

if (player[iShip-1][jShip-1]≠0)

{

if (player[iShip-1][jShip-1]≠1& &player[iShip-1][jShip-1]≠2)

{

past (lColor, iShip, jShip);

move=0;

emit miss ();

}

}

else

{

move=1;

f=1;

M[lhit][0]=iShip-1;

M[lhit][1]=jShip-1;

lhit++;

player[iShip-1][jShip-1]=1;

checkDeath (iShip-1, jShip-1);

wound (iShip, jShip, lColor, hitColor);

K++;

emit hit ();

if (K==20)emit endFight ();

}

}

void Field: :checkDeath (int i, int j)

{

int l;

int fD=0;

int thD=0;

int twD=0;

int oD=0;

int numShip=0;

int sizeShip;

for (l=0; l<4;l++)

if (fourDeck. location[l][0]==i&&

fourDeck. location[l][1]==j)fD=1;

for (thI=0; thI<2;thI++)

for (l=0; l<3;l++)

if (threeDeck[thI]. location[l][0]==i&&

threeDeck[thI]. location[l][1]==j)

{

thD=1;

numShip=thI;

}

for (twI=0; twI<3;twI++)

for (l=0; l<2;l++)

if (twoDeck[twI]. location[l][0]==i&&

twoDeck[twI]. location[l][1]==j)

{

twD=1;

numShip=twI;

}

for (oI=0; oI<4;oI++)

{

if (oneDeck[oI]. location[0][0]==i&&

oneDeck[oI]. location[0][1]==j)

{

oD=1;

numShip=oI;

}

}

if (fD≠0)

{

sizeShip=4;

supCheck (sizeShip, fourDeck. location);

}

else if (thD≠0)

{

sizeShip=3;

supCheck (sizeShip, threeDeck[numShip]. location);

}

else if (twD≠0)

{

sizeShip=2;

supCheck (sizeShip, twoDeck[numShip]. location);

}

else if (oD≠0)

{

sizeShip=1;

supCheck (sizeShip, oneDeck[numShip]. location);

}

}

void Field: :supCheck (int sizeShip, int**a)

{

int fD=0;

int l;

for (l=0; l<sizeShip;l++)

{

if (player[a[l][0]][a[l][1]]==1)fD++;

}

if (fD==sizeShip)

{

lhit=0;

h=0;

f=0;

paintPoints (sizeShip, a, lColor);

}

}

void Field: :paintPoints (int sizeShip, int**a, QColor lColor)

{

int i, j, l;

int k, m, n, p;

for (l=0; l<sizeShip;l++)

{

if (a[l][0]==0)k=0;

else k = a[l][0]-1;

if (a[l][0]==9)m=9;

else m=a[l][0]+1;

if (a[l][1]==0)p=0;

else p = a[l][1]-1;

if (a[l][1]==9)n=9;

else n = a[l][1]+1;

for (i=k; i< m+1;i++)

for (j=p; j< n+1;j++)

{

if (player[i][j]==-1||player[i][j]==2)

{

past (lColor, i+1, j+1);

}

}

}

}

void Field: :wound (int i, int j, QColor lColor, QColor hitColor)

{

scene. addRect (j*sizeDeck, i*sizeDeck, sizeDeck, sizeDeck, QPen (lColor, 2), QBrush (hitColor));

scene. addLine (j*sizeDeck, i*sizeDeck, (j*sizeDeck)+sizeDeck, (i*sizeDeck)+sizeDeck, QPen (lColor, 2));

scene. addLine ((j*sizeDeck)+sizeDeck, i*sizeDeck, j*sizeDeck, (i*sizeDeck)+sizeDeck, QPen (lColor, 2));

}

void Field: :past (QColor color, int i, int j)

{

scene. addEllipse ((j*sizeDeck)+12, (i*sizeDeck)+12, 5, 5, QPen (color), QBrush (color));

player[i-1][j-1]=2;

}

void Field: :paintDeck (QColor lColor, QColor deckColor, int i, int j)

{

scene. addRect ((j+1)*sizeDeck, (i+1)*sizeDeck, sizeDeck, sizeDeck, QPen (lColor), QBrush (deckColor));

}

Field: :~Field ()

{

}

Файл main. cpp

#include < QtGui>

#include < QTextCodec>

#include < QApplication>

#include «startwidget. h»

int main (int argv, char **args)

{

//QTextCodec: :setCodecForCStrings (QTextCodec:codecForName («UTF-8»));

//QTextCodec: :setCodecForLocale (QTextCodec:codecForName («UTF-8»));

//QTextCodec: :setCodecForTr (QTextCodec:codecForName («UTF-8»));

QTextCodec: :setCodecForCStrings (QTextCodec:codecForName («Windows-1251»));

QTextCodec: :setCodecForLocale (QTextCodec:codecForName («Windows-1251»));

QTextCodec: :setCodecForTr (QTextCodec:codecForName («Windows-1251»));

QApplication app (argv, args);

app. connect (&app, SIGNAL (lastWindowClosed ()), & app, SLOT (quit ()));

StartWidget SW;

SW. show ();

return app. exec ();

}

Файл mainwindow. h

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

#include < QtGui>

#include < QFile>

#include < QApplication>

#include < QSettings>

#include «playerfield. h»

#include «enemyfield. h»

#include «selectionships. h»

class MainWindow: public QMainWindow

{

Q_OBJECT

public:

MainWindow ();

~MainWindow ();

PlayerField *PF1, *PF2;

EnemyField *EF;

SelectionShips *sShip;

QDockWidget *Pfield;

QDockWidget *Efield;

QDockWidget *StartGame;

QMenu *Game, *About;

QString path;

void difinMode (int mode, QString PlayerName1, QString PlayerName2, int& load);

void readFile (QString fileName);

signals:

void MWSignal ();

void loadGame ();

void startNew ();

public slots:

void quit (); //выход из игры

void newGameWidget (); //добавление виджетов на форму

void closeSelectionShips (); //закрытие окна выбора кораблей

void decrement (); //декремент количества кораблей при их выборе

void saveGame (); //сохранение игры

void saveAs ();

void secondDock (); //обработка второго игрового поля при наличии двух игроков

void firePF1(); //обработка стрельбы первого игрока

void firePF2(); //обработка игры второго игрока

void won (); //оповещение о победе

void lose (); //оповещение о проигрыше

void blockMenu (); //блокировка главного меню

void unblockMenu (); //разблокировка главного меню

void MWLoad (); //загрузка существующей игры

void startNewGame ();

void about ();

void help ();

protected:

void menu ();

void playing ();

void connection (PlayerField *var);

void loadWidgets (QDockWidget *& wdgt, PlayerField *& var, QString fieldName);

void loadWidgets (QDockWidget *& wdgt, EnemyField *& var, QString fieldName);

void choice ();

void getMatrix (QString line, PlayerField *& var, int i);

void getMatrix (QString line, EnemyField *& var, int i);

void checkEnd (QString & line);

void loadShips (PlayerField *& var);

void loadShips (EnemyField *& var);

void supLoadShips (int i, int **& m, QString temp);

void checkRepeat (QVector < QString> a, QString name);

int gMode;

QString PN1, PN2;

QFile file;

};

#endif // MAINWINDOW_H

Файл mainwindow. cpp

#include «mainwindow. h»

MainWindow: :MainWindow ()

{

menu ();

PF1 = new PlayerField ();

PF2 = new PlayerField ();

EF = new EnemyField ();

sShip = new SelectionShips ();

Pfield = new QDockWidget (tr («Поле игрока»));

Efield = new QDockWidget (tr («Поле врага»));

StartGame = new QDockWidget ();

}

void MainWindow: :menu ()

{

Game = menuBar ()-> addMenu (tr («&Игра»));

Game-> addAction (tr («&Новая»), this, SLOT (startNewGame ()));

Game-> addAction (tr («&Сохранить»), this, SLOT (saveGame ()));

Game-> addAction (tr («&Загрузить»), this, SLOT (MWLoad ()));

Game-> addAction (tr («&Выход»), this, SLOT (quit ()));

About = menuBar ()-> addMenu (tr («&Справка»));

About-> addAction (tr («&О программе»), this, SLOT (about ()));

About-> addAction (tr («&Как играть»), this, SLOT (help ()));

}

void MainWindow: :newGameWidget ()

{

QString str = PN1+" расставляет свои корабли";

PF1 = new PlayerField ();

PF1-> deckColor=Qt:darkCyan;

loadWidgets (Pfield, PF1, PN1);

addDockWidget (Qt: :LeftDockWidgetArea, Pfield);

choice ();

addDockWidget (Qt: :LeftDockWidgetArea, StartGame);

if (gMode≠1)

{

PF2 = new PlayerField ();

PF2-> deckColor=Qt:darkCyan;

loadWidgets (Efield, PF2, PN2);

addDockWidget (Qt: :RightDockWidgetArea, Efield);

Efield-> setEnabled (false);

PF2-> blackout (Qt:black, Qt: :white, Qt: :red);

connect (sShip-> start, SIGNAL (clicked ()), this, SLOT (secondDock ()));

connection (PF1);

}

else

{

EF = new EnemyField ();

EF-> deckColor=Qt:white;

loadWidgets (Efield, EF, PN2);

addDockWidget (Qt: :RightDockWidgetArea, Efield);

connect (sShip-> start, SIGNAL (clicked ()), this, SLOT (closeSelectionShips ()));

connect (sShip-> start, SIGNAL (clicked ()), this, SLOT (unblockMenu ()));

connect (sShip-> start, SIGNAL (clicked ()), EF, SLOT (autoBuild ()));

connection (PF1);

}

QMessageBox: :information (NULL, «Внимание!», tr (str. toStdString (). c_str ()));

}

void MainWindow: :secondDock ()

{

Efield-> setEnabled (true);

closeSelectionShips ();

PF1-> blackout (Qt:black, Qt: :white, Qt: :red);

PF2-> blackout (Qt:white, Qt: :black, Qt: :red);

QString str = PN2+" расставляет свои корабли";

QMessageBox: :information (NULL, «Внимание!», tr (str. toStdString (). c_str ()));

choice ();

addDockWidget (Qt: :RightDockWidgetArea, StartGame);

connection (PF2);

connect (sShip-> start, SIGNAL (clicked ()), this, SLOT (closeSelectionShips ()));

connect (sShip-> start, SIGNAL (clicked ()), this, SLOT (unblockMenu ()));

}

void MainWindow: :loadWidgets (QDockWidget*&wdgt, PlayerField*& var, QString fieldName)

{

wdgt-> close ();

wdgt = new QDockWidget (tr (fieldName. toStdString (). c_str ()));

wdgt-> setFeatures (QDockWidget:NoDockWidgetFeatures);

wdgt-> setFixedSize (400, 400);

var-> loadField (Qt:black, Qt: :white, Qt: :darkCyan, Qt: :red);

wdgt-> setWidget (var);

}

void MainWindow: :loadWidgets (QDockWidget*&wdgt, EnemyField*& var, QString fieldName)

{

wdgt-> close ();

wdgt = new QDockWidget (tr (fieldName. toStdString (). c_str ()));

wdgt-> setFeatures (QDockWidget:NoDockWidgetFeatures);

wdgt-> setFixedSize (400, 400);

var-> loadField (Qt:black, Qt: :white, Qt: :white, Qt: :red);

wdgt-> setWidget (var);

}

void MainWindow: :choice ()

{

StartGame-> close ();

StartGame = new QDockWidget (tr («Выберите корабль: «));

StartGame-> setFeatures (QDockWidget:NoDockWidgetFeatures);

sShip = new SelectionShips ();

StartGame-> setWidget (sShip);

}

void MainWindow: :connection (PlayerField *var)

{

connect (sShip-> fourBtn, SIGNAL (clicked ()), var, SLOT (four ()));

connect (sShip-> fourBtn, SIGNAL (clicked ()), this, SLOT (blockMenu ()));

connect (sShip-> threeBtn, SIGNAL (clicked ()), var, SLOT (three ()));

connect (sShip-> threeBtn, SIGNAL (clicked ()), this, SLOT (blockMenu ()));

connect (sShip-> twoBtn, SIGNAL (clicked ()), var, SLOT (two ()));

connect (sShip-> twoBtn, SIGNAL (clicked ()), this, SLOT (blockMenu ()));

connect (sShip-> oneBtn, SIGNAL (clicked ()), var, SLOT (one ()));

connect (sShip-> oneBtn, SIGNAL (clicked ()), this, SLOT (blockMenu ()));

connect (var, SIGNAL (completed ()), this, SLOT (decrement ()));

}

void MainWindow: :blockMenu ()

{

Game-> actions (). at (0)->setEnabled (false);

Game-> actions (). at (1)->setEnabled (false);

Game-> actions (). at (2)->setEnabled (false);

}

void MainWindow: :unblockMenu ()

{

Game-> actions (). at (0)->setEnabled (true);

Game-> actions (). at (1)->setEnabled (true);

Game-> actions (). at (2)->setEnabled (true);

}

void MainWindow: :difinMode (int mode, QString PlayerName1, QString PlayerName2, int & load)

{

load=1;

gMode = mode;

PN1 = PlayerName1;

PN2 = PlayerName2;

}

void MainWindow: :closeSelectionShips ()

{

if (sShip-> fourEdit->text ()=="0"&&sShip->threeEdit->text ()=="0"&&sShip->twoEdit->text ()=="0"&&sShip->oneEdit->text ()=="0″)

StartGame-> close ();

else

QMessageBox: :warning (NULL, «Warring», tr («Вы должны построить все корабли, чтобы начать игру!»));

if (PF1-> amount==10&&PF2->amount==10) playing ();

else if (gMode≠0& &PF1->amount==10)playing ();

}

void MainWindow: :decrement ()

{

int n;

if (PF1-> size==4||PF2->size==4)

{

n = sShip-> fourEdit->text (). toInt ();

n--;

sShip-> fourEdit->setText (QString:number (n));

if (n==0)

{

sShip-> fourEdit->setEnabled (false);

sShip-> fourBtn->setEnabled (false);

if (PF1-> size==4)PF1->size=-1;

else PF2-> size=-1;

}

}

else if (PF1-> size==3||PF2->size==3)

{

n = sShip-> threeEdit->text (). toInt ();

n--;

sShip-> threeEdit->setText (QString:number (n));

if (n==0)

{

sShip-> threeEdit->setEnabled (false);

sShip-> threeBtn->setEnabled (false);

if (PF1-> size==3)PF1->size=-1;

else PF2-> size=-1;

}

}

else if (PF1-> size==2||PF2->size==2)

{

n = sShip-> twoEdit->text (). toInt ();

n--;

sShip-> twoEdit->setText (QString:number (n));

if (n==0)

{

sShip-> twoEdit->setEnabled (false);

sShip-> twoBtn->setEnabled (false);

if (PF1-> size==2)PF1->size=-1;

else PF2-> size=-1;

}

}

else if (PF1-> size==1||PF2->size==1)

{

n = sShip-> oneEdit->text (). toInt ();

n--;

sShip-> oneEdit->setText (QString:number (n));

if (n==0)

{

sShip-> oneEdit->setEnabled (false);

sShip-> oneBtn->setEnabled (false);

if (PF1-> size==1)PF1->size=-1;

else PF2-> size=-1;

}

}

}

void MainWindow: :saveAs ()

{

QString str=QApplication: :applicationDirPath ()+"/users/";

path=QFileDialog: :getSaveFileName (this, tr («Сохраните файл»), str, tr («Save Files (*. xml)»));

}

void MainWindow: :saveGame ()

{

if (path==NULL) saveAs ();

QByteArray array;

array. append (QString:number (gMode));

array. append («n»);

array. append (QString:number (PF1->move));

array. append («n»);

array. append (PN1);

array. append («n»);

array. append (QString:number (PF1->K));

array. append («n»);

PF1-> save (array);

array. append (PN2);

array. append («n»);

if (gMode≠1)array. append (QString:number (PF2->K));

else array. append (QString:number (EF->K));

array. append («n»);

if (gMode≠1)PF2-> save (array);

else EF-> save (array);

PF1-> saveShips (array);

if (gMode≠1)PF2-> saveShips (array);

else EF-> saveShips (array);

file. setFileName (path);

file. open (QIODevice:WriteOnly);

file. write (array);

file. close ();

}

void MainWindow: :MWLoad ()

{

emit loadGame ();

}

void MainWindow: :readFile (QString fileName)

{

QString temp;

int i, j;

file. setFileName (fileName);

file. open (QIODevice:ReadOnly);

while (!file. atEnd ())

{

temp = file. readLine ();

checkEnd (temp);

gMode = temp. toInt ();

temp = file. readLine ();

checkEnd (temp);

PF1-> move = temp. toInt ();

temp = file. readLine ();

checkEnd (temp);

PN1 = temp;

temp = file. readLine ();

checkEnd (temp);

PF1->K = temp. toInt ();

for (i=0; i<10;i++)

{

temp = file. readLine ();

checkEnd (temp);

getMatrix (temp, PF1, i);

}

temp = file. readLine ();

checkEnd (temp);

PN2 = temp;

temp = file. readLine ();

checkEnd (temp);

if (gMode≠1) PF2->K = temp. toInt ();

else EF->K = temp. toInt ();

for (i=0; i<10;i++)

{

temp = file. readLine ();

checkEnd (temp);

if (gMode≠1) getMatrix (temp, PF2, i);

else getMatrix (temp, EF, i);

}

loadShips (PF1);

if (gMode≠1)loadShips (PF2);

else

{

loadShips (EF);

PF1-> lhit=0;

for (i=0; i<PF1->sizeField;i++)

for (j=0; j<PF1->sizeField;j++)

{

if (PF1-> player[i][j]==1)

{

if (PF1-> player[i-1][j]==0&&i>0)

{

PF1-> M[PF1->lhit][0]=i;

PF1-> M[PF1->lhit][1]=j;

PF1-> lhit++;

PF1-> f=1;

}

else if (PF1-> player[i+1][j]==0&&i<9)

{

PF1-> M[PF1->lhit][0]=i;

PF1-> M[PF1->lhit][1]=j;

PF1-> lhit++;

PF1-> f=1;

}

else if (PF1-> player[i][j-1]==0&&j>0)

{

PF1-> M[PF1->lhit][0]=i;

PF1-> M[PF1->lhit][1]=j;

PF1-> lhit++;

PF1-> f=1;

}

else if (PF1-> player[i][j+1]==0&&j<9)

{

PF1-> M[PF1->lhit][0]=i;

PF1-> M[PF1->lhit][1]=j;

PF1-> lhit++;

PF1-> f=1;

}

}

}

}

}

StartGame-> close ();

loadWidgets (Pfield, PF1, PN1);

addDockWidget (Qt: :LeftDockWidgetArea, Pfield);

PF1-> amount=10;

if (gMode≠1)

{

PF2-> amount=10;

loadWidgets (Efield, PF2, PN2);

addDockWidget (Qt: :RightDockWidgetArea, Efield);

}

else

{

EF-> amount=10;

loadWidgets (Efield, EF, PN2);

addDockWidget (Qt: :RightDockWidgetArea, Efield);

}

playing ();

file. close ();

}

void MainWindow: :getMatrix (QString line, PlayerField*& var, int i)

{

int j, len, l;

QString ch;

l=0;

len = line. length ();

for (j=0; j<len;j++)

{

if (line. at (j)=='-')

{

ch=line. at (j);

j++;

ch=ch+line. at (j);

}

else ch=line. at (j);

var-> player[i][l]=ch. toInt ();

l++;

if (l> 9) l=0;

}

}

void MainWindow: :getMatrix (QString line, EnemyField*& var, int i)

{

int j, len, l;

QString ch;

l=0;

len = line. length ();

for (j=0; j<len;j++)

{

if (line. at (j)=='-')

{

ch=line. at (j);

j++;

ch=ch+line. at (j);

}

else ch=line. at (j);

var-> player[i][l]=ch. toInt ();

l++;

if (l> 9) l=0;

}

}

void MainWindow: :checkEnd (QString & line)

{

int i, len;

QString temp;

len = line. length ();

for (i=0; i<len;i++)

if (line. at (i)≠'n')

temp = temp+line. at (i);

line = temp;

}

void MainWindow: :loadShips (PlayerField*&var)

{

int i, j;

QString temp;

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

{

temp = file. readLine ();

checkEnd (temp);

supLoadShips (i, var-> fourDeck. location, temp);

}

for (j=0; j< 2;j++)

for (i=0; i<3;i++)

{

temp = file. readLine ();

checkEnd (temp);

supLoadShips (i, var-> threeDeck[j]. location, temp);

}

for (j=0; j<3;j++)

for (i=0; i<2;i++)

{

temp = file. readLine ();

checkEnd (temp);

supLoadShips (i, var-> twoDeck[j]. location, temp);

}

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

{

temp = file. readLine ();

checkEnd (temp);

supLoadShips (0, var-> oneDeck[j]. location, temp);

}

}

void MainWindow: :loadShips (EnemyField*&var)

{

int i, j;

QString temp;

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

{

temp = file. readLine ();

checkEnd (temp);

supLoadShips (i, var-> fourDeck. location, temp);

}

for (j=0; j< 2;j++)

for (i=0; i<3;i++)

{

temp = file. readLine ();

checkEnd (temp);

supLoadShips (i, var-> threeDeck[j]. location, temp);

}

for (j=0; j<3;j++)

for (i=0; i<2;i++)

{

temp = file. readLine ();

checkEnd (temp);

supLoadShips (i, var-> twoDeck[j]. location, temp);

}

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

{

temp = file. readLine ();

checkEnd (temp);

supLoadShips (0, var-> oneDeck[j]. location, temp);

}

}

void MainWindow: :supLoadShips (int i, int**& m, QString temp)

{

QString ch;

int j, l, len;

l=0;

len = temp. length ();

for (j=0; j<len;j++)

{

if (temp. at (j)≠' ')

{

ch=temp. at (j);

m[i][l]=ch. toInt ();

l++;

}

else

{

ch. clear ();

}

}

}

void MainWindow: :playing ()

{

PF1-> hitColor = Qt: :red;

if (gMode≠1)

{

PF1-> blackout (Qt:black, Qt: :white, Qt: :red);

PF2-> blackout (Qt:black, Qt: :white, Qt: :red);

PF1-> lColor = Qt: :white;

PF2-> lColor=Qt:white;

PF2-> hitColor = Qt: :red;

}

else

{

EF-> hitColor = Qt: :red;

}

if (PF1-> move≠0)

{

firePF2();

}

else

{

firePF1();

}

if (gMode≠1)QObject: :connect (PF2, SIGNAL (endFight ()), this, SLOT (won ()));

else QObject: :connect (EF, SIGNAL (endFight ()), this, SLOT (won ()));

QObject: :connect (PF1, SIGNAL (endFight ()), this, SLOT (lose ()));

}

void MainWindow: :firePF1()

{

if (gMode≠1)

{

PF1-> setEnabled (false);

PF2-> setEnabled (true);

QString str="Ходит игрок «+PN1;

QMessageBox: :information (this, «Внимание!», str);

QObject: :disconnect (PF1, SIGNAL (miss ()), this, SLOT (firePF1()));

QObject: :disconnect (PF1, SIGNAL (startFight ()), PF1, SLOT (fire ()));

QObject: :connect (PF2, SIGNAL (miss ()), this, SLOT (firePF2()));

QObject: :connect (PF2, SIGNAL (startFight ()), PF2, SLOT (fire ()));

}

else

{

PF1-> setEnabled (false);

EF-> setEnabled (true);

QObject: :disconnect (PF1, SIGNAL (hit ()), PF1, SLOT (compFire ()));

QObject: :disconnect (PF1, SIGNAL (miss ()), this, SLOT (firePF1()));

QObject: :connect (EF, SIGNAL (miss ()), PF1, SLOT (compFire ()));

QObject: :connect (PF1, SIGNAL (comp ()), this, SLOT (firePF2()));

QObject: :connect (EF, SIGNAL (startFight ()), EF, SLOT (fire ()));

}

}

void MainWindow: :firePF2()

{

if (gMode≠1)

{

PF2-> setEnabled (false);

PF1-> setEnabled (true);

QString str="Ходит игрок «+PN2;

QMessageBox: :information (this, «Внимание!», str);

QObject: :disconnect (PF2, SIGNAL (miss ()), this, SLOT (firePF2()));

QObject: :disconnect (PF2, SIGNAL (startFight ()), PF2, SLOT (fire ()));

QObject: :connect (PF1, SIGNAL (startFight ()), PF1, SLOT (fire ()));

QObject: :connect (PF1, SIGNAL (miss ()), this, SLOT (firePF1()));

}

else

{

PF1-> setEnabled (true);

EF-> setEnabled (false);

QObject: :disconnect (PF1, SIGNAL (comp ()), this, SLOT (firePF2()));

QObject: :disconnect (EF, SIGNAL (miss ()), PF1, SLOT (compFire ()));

QObject: :disconnect (EF, SIGNAL (startFight ()), EF, SLOT (fire ()));

QObject: :connect (PF1, SIGNAL (hit ()), PF1, SLOT (compFire ()));

QObject: :connect (PF1, SIGNAL (miss ()), this, SLOT (firePF1()));

}

}

void MainWindow: :lose ()

{

QString str = «Выиграл игрок «+PN2;

if (gMode≠1)

QMessageBox: :warning (NULL, «Внимение», str);

else

QMessageBox: :warning (NULL, «Внимение», tr («Вы проиграли!»));

PF2-> setEnabled (false);

PF1-> setEnabled (false);

EF-> setEnabled (false);

}

void MainWindow: :won ()

{

QString str = «Выиграл игрок «+PN1;

if (gMode≠1)

QMessageBox: :warning (NULL, «Внимение», str);

else

QMessageBox: :warning (NULL, «Внимение», tr («Вы выиграли!»));

PF2-> setEnabled (false);

PF1-> setEnabled (false);

EF-> setEnabled (false);

}

void MainWindow: :checkRepeat (QVector<QString> a, QString name)

{

QString stName, stCount, temp;

int i, j, count, len, n;

bool fine = false;

qDebug ()< <a. size ();

/*for (i=0; i<a. size ();i++)

{

temp = a. at (i);

len = temp. length ();

j=0;

while (temp. at (j)≠'-')

{

stName=stName+temp. at (j);

j++;

}

n=j;

for (j=n; j<len;j++)

stCount=stCount+temp. at (j);

count = stCount. toInt ();

if (stName==name)

{

count++;

stName=stName+'-'+QString: :number (count);

a. insert (i, stName);

fine=true;

}

}

if (!fine)

{

stName = name+"-1″;

a. append (stName);

}*/

}

void MainWindow: :startNewGame ()

{

int res = QMessageBox: :warning (this, «Внимание!», tr («Вы уверены, что хотите начать новую игру?»), QMessageBox: :Yes, QMessageBox: :No);

if (res==QMessageBox: :Yes)

{

saveGame ();

path="";

emit startNew ();

}

}

void MainWindow: :quit ()

{

int res = QMessageBox: :warning (this, «Внимание!», tr («Вы уверены, что хотите выйти?»), QMessageBox: :Yes, QMessageBox: :No);

if (res==QMessageBox: :Yes)

{

if (gMode≠1)

{

if (PF1-> amount<10&&PF2->amount<10)exit (0);

}

else if (PF1-> amount<10)exit (0);

int sres = QMessageBox: :warning (this, «Внимание!», tr («Сохранить игру перед выходом?»), QMessageBox: :Yes, QMessageBox: :No);

if (sres==QMessageBox: :Yes)

{

if (PF1-> K<20)

{

saveGame ();

exit (0);

}

else exit (0);

if (gMode≠1)

if (PF2-> K<20)

{

saveGame ();

exit (0);

}

else if (EF-> K<20)

{

saveGame ();

exit (0);

}

else exit (0);

}

if (sres==QMessageBox: :No)exit (0);

}

}

void MainWindow: :about ()

{

QString str;

str = «Игра 'Морской бой’nВерсия 1. 0nИгра разработана студенткой группы З-8001 Поспеловой И. В. «;

QMessageBox: :information (NULL, tr («О программе»), str);

}

void MainWindow: :help ()

{

QFile hFile;

QString str, path;

path = QApplication: :applicationDirPath ()+"/help. txt";

hFile. setFileName (path);

hFile. open (QIODevice:ReadOnly);

while (!hFile. atEnd ())

str = hFile. readAll ();

hFile. close ();

QMessageBox: :information (NULL, tr («Как играть»), str);

}

MainWindow: :~MainWindow ()

{

}

Файл playerfield. h

#ifndef PLAYERFIELD_H

#define PLAYERFIELD_H

#include < QApplication>

#include «field. h»

#include «battleship. h»

#include «cruiser. h»

#include «destroyer. h»

#include «boat. h»

class PlayerField: public Field

{

Q_OBJECT

public:

PlayerField ();

~PlayerField ();

void blackout (QColor bColor, QColor lColor, QColor hitColor); //закрывает вражеское поле

void calcPos (int x, int y); //сопоставляет позицию нажатия ЛКМ с player[][]

void mousePressEvent (QMouseEvent *event); //мышь

void deleteDeck (); //удаляет выделенную палубу

signals:

void comp ();

public slots:

void four ();

void three ();

void two ();

void one ();

void compFire ();

void randCalc ();

protected:

void checkAround (int x, int y);

};

#endif // PLAYERFIELD_H

Файл playerfield. cpp

#include «playerfield. h»

PlayerField: :PlayerField ()

{

this-> setScene (&scene);

}

void PlayerField: :blackout (QColor bColor, QColor lColor, QColor hitColor)

{

int i, j;

paintField (bColor, lColor);

for (i=0; i<sizeField;i++)

for (j=0; j<sizeField;j++)

{

if (player[i][j]==0& &player[i][j]==-1)

scene. addRect ((j+1)*sizeDeck, (i+1)*sizeDeck, sizeDeck, sizeDeck, QPen (lColor), QBrush (bColor));

else if (player[i][j]==2) past (lColor, i+1, j+1);

else if (player[i][j]==1)wound (i+1, j+1, lColor, hitColor);

}

}

void PlayerField: :mousePressEvent (QMouseEvent *event)

{

int x, y;

x = event-> pos (). x ()-30;

y = event-> pos (). y ()-20;

calcPos (x, y);

if (event-> button () == Qt: :LeftButton)

{

if (x> =30&&x<=330&&y>=30&&y<=330)

{

if (size> 0) selectShip (flag, t, size);

else if (amount≠10)

QMessageBox: :warning (NULL, «Warring», tr («Выберите тип корабля!»));

else emit startFight ();

}

}

else if (event-> button ()==Qt:RightButton)

{

deleteDeck ();

}

}

void PlayerField: :calcPos (int x, int y)

{

if (x> =30&&x<=330&&y>=30&&y<=330)

{

jShip=x/30;

iShip=y/30;

}

}

void PlayerField: :randCalc ()

{

jShip = (rand () % 10+0)+1;

iShip = (rand () % 10+0)+1;

}

void PlayerField: :deleteDeck ()

{

int i, j, f;

f=0;

i=iShip-1;

j=jShip-1;

if (player[i][j]==size)

{

if (player[i-1][j]==size)

{

if ((player[i][j-1]==size)||(player[i][j+1]==size)||(player[i+1][j])==size)

{

f=1;

QMessageBox: :warning (NULL, «Warring», tr («Вы не можете удалить эту палубу!»));

}

}

if (player[i+1][j]==size)

{

if ((player[i][j-1]==size)||(player[i][j+1]==size))

{

f=1;

QMessageBox: :warning (NULL, «Warring», tr («Вы не можете удалить эту палубу!»));

}

}

if (player[i][j-1]==size)

{

if (player[i][j+1]==size)

{

f=1;

QMessageBox: :warning (NULL, «Warring», tr («Вы не можете удалить эту палубу!»));

}

}

if (f≠1)

{

player[i][j]=-1;

scene. addRect (jShip*sizeDeck, iShip*sizeDeck, sizeDeck, sizeDeck, QPen (Qt: :black), QBrush (Qt: :transparent));

if (player[i-1][j]==size)

scene. addLine (jShip*sizeDeck, iShip*sizeDeck, (jShip*sizeDeck+sizeDeck), iShip*sizeDeck, QPen (Qt: :red));

else if (player[i+1][j]==size)

scene. addLine (jShip*sizeDeck, (iShip*sizeDeck+sizeDeck), (jShip*sizeDeck+sizeDeck), (iShip*sizeDeck+sizeDeck), QPen (Qt: :red));

else if (player[i][j-1]==size)

scene. addLine (jShip*sizeDeck, iShip*sizeDeck, jShip*sizeDeck, (iShip*sizeDeck+sizeDeck), QPen (Qt: :red));

else if (player[i][j+1]==size)

scene. addLine ((jShip*sizeDeck+sizeDeck), iShip*sizeDeck, (jShip*sizeDeck+sizeDeck), (iShip*sizeDeck+sizeDeck), QPen (Qt: :red));

flag--;

if (flag==0)t=0;

}

}

}

void PlayerField: :four ()

{

size=4;

}

void PlayerField: :three ()

{

size=3;

}

void PlayerField: :two ()

{

size=2;

}

void PlayerField: :one ()

{

size=1;

}

void PlayerField: :compFire ()

{

int i, j;

emit comp ();

if (f≠1)

{

do

{

randCalc ();

}

while ((player[iShip-1][jShip-1]==2)||(player[iShip-1][jShip-1]==1));

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

{

M[i][0]=-1;

M[i][1]=-1;

}

fire ();

}

else

{

checkAround (M[h][0], M[h][1]);

}

}

void PlayerField: :checkAround (int x, int y)

{

int m, n, p, q;

if (x==0)m=0;

else m = x-1;

if (y==0)n=0;

else n=y-1;

if (x==9)p=9;

else p=x+1;

if (y==9)q=9;

else q=y+1;

if (player[m][y]< =0)

{

iShip = x;

jShip = y+1;

fire ();

if (move≠1)

{

iShip = x+1;

jShip = y+1;

}

}

else if (player[x][n]< =0)

{

iShip = x+1;

jShip = y;

fire ();

if (move≠1)

{

iShip = x+1;

jShip = y+1;

}

}

else if (player[x][q]< =0)

{

iShip = x+1;

jShip = y+2;

fire ();

if (move≠1)

{

iShip = x+1;

jShip = y+1;

}

}

else if (player[x+1][y]< =0)

{

iShip = x+2;

jShip = y+1;

fire ();

if (move≠1)

{

iShip = x+1;

jShip = y+1;

}

}

else

{

h++;

checkAround (M[h][0], M[h][1]);

}

}

PlayerField: :~PlayerField ()

{

}

Файл putname. h

#ifndef PUTNAME_H

#define PUTNAME_H

#include < QtGui>

class PutName: public QDialog

{

Q_OBJECT

public:

PutName ();

~PutName ();

QLabel *label;

QLineEdit *edit;

QPushButton *button;

QVBoxLayout *layout;

QString playerName;

signals:

void PNSignal ();

public slots:

void setName ();

protected:

void output ();

};

#endif // PUTNAME_H

Файл putname. cpp

#include «putname. h»

PutName: :PutName ()

{

label = new QLabel («Введите имя игрока: «);

edit = new QLineEdit;

button = new QPushButton (tr («OK»));

layout = new QVBoxLayout;

output ();

QObject: :connect (button, SIGNAL (clicked ()), this, SLOT (setName ()));

}

void PutName: :output ()

{

layout-> addWidget (label);

layout-> addWidget (edit);

layout-> addWidget (button);

setLayout (layout);

}

void PutName: :setName ()

{

if (!edit-> text (). isEmpty ())

{

playerName=edit-> text ();

emit PNSignal ();

}

else QMessageBox: :warning (this, «Внимание!», «Вы не ввели имя!»);

}

PutName: :~PutName ()

{

}

Файл Selectionships. h

#ifndef SELECTIONSHIPS_H

#define SELECTIONSHIPS_H

#include < QtGui>

class SelectionShips: public QWidget

{

Q_OBJECT

public:

SelectionShips ();

~SelectionShips ();

QPushButton *fourBtn;

QPushButton *threeBtn;

QPushButton *twoBtn;

QPushButton *oneBtn;

QPushButton *start;

QLineEdit *fourEdit;

QLineEdit *threeEdit;

QLineEdit *twoEdit;

QLineEdit *oneEdit;

QGridLayout *layout;

void linkage ();

};

#endif // SELECTIONSHIPS_H

Файл Selectionships. cpp

#include «selectionships. h»

SelectionShips: :SelectionShips ()

{

fourBtn = new QPushButton (tr («4 палубы»));

threeBtn = new QPushButton (tr («3 палубы»));

twoBtn = new QPushButton (tr («2 палубы»));

oneBtn = new QPushButton (tr («1 палуба»));

start = new QPushButton (tr («Старт»));

fourEdit = new QLineEdit ();

threeEdit = new QLineEdit ();

twoEdit = new QLineEdit ();

oneEdit = new QLineEdit ();

layout = new QGridLayout ();

linkage ();

}

void SelectionShips: :linkage ()

{

fourEdit-> setText («1»);

fourEdit-> setFixedWidth (30);

fourEdit-> setReadOnly (true);

threeEdit-> setText («2»);

threeEdit-> setFixedWidth (30);

threeEdit-> setReadOnly (true);

twoEdit-> setText («3»);

twoEdit-> setFixedWidth (30);

twoEdit-> setReadOnly (true);

oneEdit-> setText («4»);

oneEdit-> setFixedWidth (30);

oneEdit-> setReadOnly (true);

fourBtn-> setFixedWidth (90);

threeBtn-> setFixedWidth (90);

twoBtn-> setFixedWidth (90);

oneBtn-> setFixedWidth (90);

start-> setFixedWidth (50);

layout-> addWidget (fourBtn, 1, 0, Qt: :AlignLeft);

layout-> addWidget (fourEdit, 1, 1);

layout-> addWidget (threeBtn, 2, 0, Qt: :AlignLeft);

layout-> addWidget (threeEdit, 2, 1);

layout-> addWidget (twoBtn, 3, 0, Qt: :AlignLeft);

layout-> addWidget (twoEdit, 3, 1);

layout-> addWidget (oneBtn, 4, 0, Qt: :AlignLeft);

layout-> addWidget (oneEdit, 4, 1);

layout-> addWidget (start, 5, 0, Qt: :AlignRight);

this-> setLayout (layout);

}

SelectionShips: :~SelectionShips ()

{

}

Файл selectmode. h

#ifndef SELECTMODE_H

#define SELECTMODE_H

#include < QDialog>

#include < QtGui>

class SelectMode: public QDialog

{

Q_OBJECT

public:

SelectMode ();

~SelectMode ();

ПоказатьСвернуть
Заполнить форму текущей работой