РАЗРАБОТКА ИГРЫ МОРСКОЙ БОЙ С AI

Министерство общего и профессионального образования

Российской Федерации

Государственное образовательное учреждение высшего профессионального образования

САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ

МЕХАНИКИ И ОПТИКИ



ФАКУЛЬТЕТ СРЕДНЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ















КУРСОВАЯ РАБОТА

на тему: РАЗРАБОТКА ИГРЫ «МОРСКОЙ БОЙ» С AI



По дисциплине «Технология Разработки Программных Продуктов»



Специальность «Программное обеспечение вычислительной техники и автоматизированных систем» (230105)







Преподаватель:

«___»_________20__г.

Выполнил:

Индыков Максим Игоревич

гр. 323 дневного отделения











Санкт-Петербург

2011


АННОТАЦИЯ

Цель работы - создать игру "морской бой" с противником, обладающим искусственным интеллектом, запускаемую на ОС Android 2.2.

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

Выбор данной ОС обусловлен её актуальностью и доступностью инструментов для разработки. Разработка велась на языке программирования Java с использованием инструментария разработчика. Результатом разработки стал программный продукт, функционирующий на указанном в отчёте оборудовании и обладающий возможностью для улучшения и модификации.




СОДЕРЖАНИЕ

	ВВЕДЕНИЕ	4

	1 ОПРЕДЕЛЕНИЕ ТРЕБОВАНИЙ	4

	1.1 Описание бизнес процесса	4

	1.2 Сравнение аналогов	5

	1.3 Моделирование требований	6

	1.4 Выбор модели жизненного цикла	7

	2 ПРОЕКТИРОВАНИЕ	9

	2.1 Выбор модели системы	9

	2.2 Проектирование структуры системы	9

	2.3 Проектирование логики работы	10

	2.4 Проектирование интерфейса	13

	3 РАЗРАБОТКА ПРОГРАММНОГО КОДА	15

	4 ВЕРИФИКАЦИЯ И АТТЕСТАЦИЯ	16

	4.1 Выбор методов верификации и аттестации	16

	4.2 Инспектирование	16

	4.3 Тестирование	17

	5 ПРОГРАММНАЯ ДОКУМЕНТАЦИЯ	18

	5.1 Инструкция по установке	18

	5.2 Инструкция пользователя	18

	ЗАКЛЮЧЕНИЕ	19

	СПИСОК ИСТОЧНИКОВ ИНФОРМАЦИИ	20

	ПРИЛОЖЕНИЕ A ТЕХНИЧЕСКОЕ ЗАДАНИЕ	21

	1НАЗНАЧЕНИЕ РАЗРАБОТКИ	21

	2 ЦЕЛЬ И ЗАДАЧИ	21

	3 ТРЕБОВАНИЯ К РАЗРАБОТКЕ	21

	3.1Требованияк функциональным характеристикам	21

	3.2 Описание входных и выходных данных	22

	3.3 Модель работы продукта разработки	23

	3.4 Требования к надежности	25

	3.5 Эргономические и техникоэстетические требования	25

	3.6 Требования к защите информации	26

	3.7 Другие требования к разработке	26

	3.8 Требования к аппаратно-программному комплексу.	26

	3.9 Требования к технологиям разработки	26

	3.10 Требования к составу технических средств при эксплуатации.	26

	4 МЕТОДЫ ТЕСТИРОВАНИЯ СООТВЕТСТВИЯ РАЗРАБОТКИ ПРЕДЪЯВЛЕННЫМ ТРЕБОВАНИЯМ	26

	ПРИЛОЖЕНИЕ Б ПРОГРАММНЫЙ КОД	27






ВВЕДЕНИЕ

На данный период времени разработка является актуальной и имеет перспективы для улучшения. Актуальность темы разработки обусловлена малым количеством аналогов данного проекта представленных в данный период времени.

Данный документ содержит следующую информацию:

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

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

в разработке программного кода содержится краткий обзор разработанных функций;

в верификации и аттестации описывается, как будет выполняться тестирование проекта;

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

1 ОПРЕДЕЛЕНИЕ ТРЕБОВАНИЙ

1.1 Описание бизнес процесса

Необходимо реализовать игру Морской бой между компьютером и человеком. Доказать то, что компьютер пытается выиграть.

Особенностью игры, будут являться более реалистичные правила игры (зона поражения для кораблей, шанс промахнуться), наличие различных видов кораблей с исторической справкой о них. Наличие системы повреждений корпуса. Бой должен вестись на общем для обоих игроков поле.

Игра проходит на поле размером 10 на 10 клеток. 

На поле размещаются 10 кораблей (один 4-х палубный, два 3-х палубных, три 2-х палубных и один 1-палубный).

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

Различные корабли, имеют различный режим атаки и радиус.

Выстрелы делаются по-очереди. Если при выстреле произошло попадание в корабль, игроку предоставляется дополнительный выстрел.

Побеждает тот, кто первым потопит флот противника.

Так как на большинстве платформ уже имеется некоторое количество подобных проектов, разработка будет вестись для мобильных систем на базе ОС Android.



1.2 Сравнение аналогов

1.Морской бой на flash, официальный сайт:

http://www.flashzona.ru/i3529

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

2. Battle Ships, официальный сайт:

http://www.androidfreeware.net/download-battleships.html

Игра, разработка под Android 1.5.Не нужно ждать пока ваш противник сделает выстрел, вы просто делаете их подряд, наблюдая как ваш противник, ходит одновременно с вами. Что не очень привычно. Не нужно расставлять корабли вы просто выбираете одну из случайно предложенных расстановок кораблей. Так же автоматически закрываются ячейки, куда уже нельзя поставить корабли, что удобно для расчета спрятанных кораблей противника.

3. Sea Battle, официальный сайт:

http://android-apps.com/featured/sea-battle/

Игра, разработка под Android. Предлагает пользователям два варианта игры, одиночный и мультиплеерный (bluetooth). Правила игры классические, но возможен выбор режима с уменьшенным количеством кораблей. Единственным недостатком игры являются слегка затянутые переходы между полями игроков, но это компенсируется заботливо продуманной разработчиками функцией сохранения.



Таблица 1 – Сравнение аналогов



Морской Бой на flash



BattleShips







Sea Battle 1.03



Различные варианты игры

-

-

+

Игра по сети

-

-

+

Игра на мобильном телефоне

+-

+

+

Разработана специально для android

-

+

+

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

1.3 Моделирование требований

Диаграмма IDEF0 построена для описания поведения приложения во время игры и определения последовательности действий во время игры.  Данная последовательность определена правилами, описанными в п. 1.1.

Входными данными являются события созданные пользователем (такие как выбор пункта меню, выбор клетки).

За запуск игры отвечает виртуальная java-машина, т.к. она обеспечивает поддержку устройством приложений. 

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

Диаграмма Use Case представляет собой концептуальную модель системы и является основой для проектирования пользовательского интерфейса.

Блок «Регистрация» позволяет создать новый аккаунт для ведения статистики побед и поражений.

Блок «Начать бой» начинает игру с заданным набором кораблей.

«Выбрать стартовый набор кораблей» позволяет отойти от классических правил морского боя и определить своё собственное кол-во каждого вида корабля.

«Просмотр статистики» осуществляет вызов функции отвечающей за выборку данных для текущего аккаунта.

































1.4 Выбор модели жизненного цикла

Таблица 2 – Сравнение моделей ЖЦ

Вид модели



Качество данной

модели

Каскадная

+:Оптимальна, при максимальном выделении всех требований.

-: Результат в самом конце разработки.

Прототипированная

+Решение возникающих проблем на ранних стадиях.

-: Малая вероятность, что будет сразу готов прототип системы.

Инкрементная

+: Добавление функции с каждым инкрементом.

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

На основе раннее созданных компонентов

+: Снижает время разработки.

-: Искажаются требования.

Спиральная

+: Преимущества инкрементной и прототипированной модели.

-: Усложнённая структура разработки.

V образная

+: Обеспечивает максимальную надёжность.

-: Невозможно изменение требований.

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

 Описание технического задания

Требования к функциональным характеристикам:

Главной функцией игры является игра с искусственным противником, поэтому необходимо реализовать выбор ИИ игроком клетки на основе логики.

Требования к надежности:

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

Эргономические и техникоэстетические требования:

Так как приложение должно гармонично выглядеть внутри системы, разработку пользовательского интерфейса необходимо производить согласно рекомендациям разработчиков Android SDK.

Требования к защите информации:

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

Другие требования к разработке:

Не предъявляются.

Требования к аппаратно-программному комплексу:

Приложение не является кросс-платформенным, необходимо обеспечить работу приложения на последней стабильной версии ОС.

Требования к технологиям разработки:

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

Требования к составу технических средств при эксплуатации:

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




2 ПРОЕКТИРОВАНИЕ

2.1 Выбор модели системы

Игра разрабатывается по модели локального приложения. Все компоненты приложения будут объединены в один файл, устанавливаемый на устройство.  Приложения будет взаимодействовать с необходимыми уровнями ОС. Использовать встроенные компоненты по работе с БД Sqlite.  Следуя идеологии разработки с использованием предложенных компонентов, в приложении используются компоненты, такие как виджеты ввода и вывода данных на экран и пр. 

2.2 Проектирование структуры системы

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



Рисунок 1.Диаграмма компонентов



Как показано на рисунке 1, главный компонент программы обращается к файлам с изображениями, файлу manifest,  в котором описаны разрешения при работе программы. Статистика и аккаунты хранятся в базе данных Sqlite.



	

Рисунок 2. Диаграмма классов



Для работы с базой данных используется SQLite. Это возможно благодаря классу SQliteOpenHelper и собственному классу DbOpenHelper. Main класс, в соответствие с рисунком 2,  содержит необходимые методы для работы приложения в данной среде, такие как onCreate и onClick.

2.3 Проектирование логики работы

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

Для осуществления противником хода используется неслучайный алгоритм выбора клетки. Алгоритм основан на предполагаемом размещении кораблей игрока. Искусственный противник не имеет сведений о расположении кораблей игрока, благодаря чему оппоненты находятся в относительно одинаковых условиях.

При запуске, система находится в состоянии отображения меню, из которого возможен выход и дальнейшая работа с программой, что видно на рисунке 3. Выбор “начать игру” переводит систему в состояние самой игры, которое включает в себя такие состояния как: отображение игрового поля, расстановка кораблей, ожидание действия пользователя и прочее. 





Рисунок 3. Диаграмма состояний



			Рисунок 4. Диаграмма Activity

2.4 Проектирование интерфейса

Меню программы, рисунок 5.





Рисунок 5. Меню программы


Выбор способа расстановки в виде диалога, рисунок 6.





Рисунок 6. Диалог расстановки



Игровое поле, рисунок 7. На нём отображаются атаки противника.





Рисунок 7. Игровое поле



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



Рисунок 8. Поле окончания игры

3 РАЗРАБОТКА ПРОГРАММНОГО КОДА

По ходу разработки программного кода были изучены такие такие программные средства как AndroidSDK,программирование на языке Java. Получен опыт разработки приложения для мобильных устройств.

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

динамическая отрисовка игрового поля;

многопоточность (в разных потоках выполняются функции расстановки кораблей и выполнения атаки ИИ противником).




4 ВЕРИФИКАЦИЯ И АТТЕСТАЦИЯ

4.1 Выбор методов верификации и аттестации

При разработке ПО применяются следующие методы:

основной метод тестирование: “Тестирование Белого Ящика”. Подразумевает тестирование программы с доступными исходными текстами;

при разработке пользовательского интерфейса применяется тестирование “Чёрного Ящика”, т.к. конечный пользователь не знает о внутреннем устройстве программы.

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

4.2 Инспектирование

Требования к разработке:

Требования к функциональным характеристикам.

Меню приложения: требования невозможно идентифицировать, так как нет доступа к файлу, в котором описывается данная функция.

Игра: требование описано в Communication Diagramm, пункты на диаграмме – 6 и 7.

Расстановка кораблей ИИ: требование описано в Activity Diagramm – расстановка кораблей компонента, проверка на правильность расстановки – проверить на возможность расстановки корабля.

Определение набора кораблей: требование описано в Use Сase Diagramm – выбрать стартовый набор кораблей.

Просмотр статистики и регистрация: требование описано в Class Diagram – создание пользователя, работа с БД, Communication Diagramm – пункты 4 и 5.

Требования к надежности. 

Возможность сворачивания и разворачивание приложения обеспечивается методом onResume и onPause. События ОС обрабатываются при постановке приложения на паузу. Невозможно проверить данное требование так оно не отражается  в диаграммах.

 Эргономические и техникоэстетические требования.

Дизайн меню и элементов управления должен соответствовать дизайну ОС. Использовать объекты (виджеты), представленные в Android SDK. Не перегружать пользовательский интерфейс излишними элементами. Основное меню должно быть выдержано в тёмных тонах с фоновым изображением на морскую тематику. Игровое поле должно целиком помещаться на экране в вертикальном режиме отображения. Невозможно проверить данное  требование так как к диаграммам оно не относиться.

 Требование к защите информации.

Готовое приложение упаковано в apk файл. Защита от реверс-инжинеринга обеспечивается встроенной в среду разработки программой ProGuard. Невозможно проверить данное требование, так как оно не отражается в диаграммах.

 Другие требования к разработке.

Реализовать алгоритм выбора клетки для атаки на основе уже выбранных клеток. Требование описано в ActivityDiagram – ИИ выбирает клетку

 Требования к аппаратно-программному комплексу.

Разработка ориентирована на Android 2.3.4 API Level: 10. Работа возможна на устройствах с различным типом экрана. Поддержка мультитача не требуется. Требование невозможно проверить, так как оно не отражается в диаграммах.

 Требования к технологиям разработки.

Разработка ведётся с использованием среды разработки Eclipse 3.6 (Helios), с установленным ADK плагином, JDK и Android SDK. Требование невозможно проверить,  так как оно не отражается в диаграммах.

 Требования к составу технических средств при эксплуатации.

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

Итог: При инспектировании работы были проверены требования в соответствии с техническим заданием. Проверить удалось не все требования, так как не все требования описывались в диаграммах. Те требования, что описывались в диаграммах, были выполнены качественно. Диаграммы полностью отображали работу системы на программном уровне.



4.3 Тестирование

При тестировании белым ящиком данные для теста выбирались с расчётом на рабочие функции программы.

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


5 ПРОГРАММНАЯ ДОКУМЕНТАЦИЯ

5.1 Инструкция по установке

Приложение поставляется в виде apk файла. Рекомендуемые системные требования: Android 2.2. Размер экрана не имеет значения т.к. приложение автоматически подстраивается под нужное разрешение. Для установки необходимо разрешить установку пакетов из сторонних источников.

5.2 Инструкция пользователя

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

При начале новой игры возможен выбор между ручной и автоматической расстановкой кораблей (в данной версии возможно только автоматическая расстановка). Для атаки игрок должен нажать на выбранную клетку. Цвет клетки сообщает игроку о результате атаки. Зелёный - неоткрытая клетка, жёлтый - промах, красный-попадание.

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




ЗАКЛЮЧЕНИЕ

На данный момент времени разработаны следующие компоненты программы:

главное меню и финальный экран (описаны в xml-файле, следовательно, возможно их свободное редактирование в ходе дальнейшей разработки);

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

классы, обеспечивающие игровые функции (выбор клетки, определение типа клетки, определение результата атаки);

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




СПИСОК ИСТОЧНИКОВ ИНФОРМАЦИИ

Голощапов А.Л. Google Android. Программирование для мобильных устройств (Профессиональное программирование), 2011.

Android Developers, официальный сайт:

http://developer.android.com/sdk/index.html




ПРИЛОЖЕНИЕ A ТЕХНИЧЕСКОЕ ЗАДАНИЕ

1НАЗНАЧЕНИЕ РАЗРАБОТКИ

Приложение разрабатывается для дальнейшей продажи при помощи Android Market. 

2 ЦЕЛЬ И ЗАДАЧИ

Целью разработки является получение прибыли с продаж продукта.

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

Создание документации к проекту (пункты Определение требований, Проектирование и Техническое задание)  необходимо закончить к 20 мая 2011 года.

Разработку программного кода необходимо закончить к концу июля 2011года.

3 ТРЕБОВАНИЯ К РАЗРАБОТКЕ

3.1Требованияк функциональным характеристикам

Функции:

Меню приложения.

Часть меню описывается в xml-файле, создание системных сообщений обеспечивается в коде программы. В меню используются стандартные объекты(кнопки, поля ввода).

Игра.

Выполняет вызов функции создания игрового поля. Обеспечивает возможность выбора клеток для атаки. Отображает результат хода.

Расстановка кораблей основывается на исходном выборе набора кораблей до начала игры.

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

Расстановка кораблей.

Корабли расставляются на поле случайным образом.

Ограничения: минимальное расстояние между кораблями – 1 клетка. Части кораблей не должны выходить за пределы игрового поля.

Определение набора кораблей.

Обеспечивает возможность пользователю составить список кораблей, которые будут использованы в бою.

Каждый корабль имеет свою цену. Цена определяется длиной  корабля.

4-х трубный – цена 5

3х трубный – цена 4

2-х трубный – цена 2

1-х трубный – цена 3

Всего дано 35 очков.

Дальнейшее количество определяется победами и поражениями. Победа прибавляет одно очко, поражение – вычитает. Верхний и нижний пределы: +-50. Готовая конфигурация сохраняется в файл.

Просмотр статистики и регистрация.

Осуществляют запись и выборку данных.При регистрации создаётся отдельная запись с пустой статистикой. Имя аккаунта необходимо для записи в таблицу рекордов. Статистика выводится в виде таблицы: имя – очки.

3.2 Описание входных и выходных данных

Таблица 1 – Описания входных и выходных данных.

Функция

Входные параметры



Выходные параметры

Меню приложения

Выбранный пункт

Отображение результата выбора

Игра

Конфигурация кораблей, текущий ход (Игрок или ИИ)

Результат хода/игры

Расстановка кораблей ИИ противником

Конфигурация кораблей

Координаты

Определение набора кораблей

Имя пользователя, кол-во очков

Конфигурация кораблей

Просмотр статистики и регистрация

Имя пользователя

Выборка данных

Вся система принимает данные от пользователя, и выводит данные при помощи экрана и динамиков.



3.3 Модель работы продукта разработки



























































Рисунок 2. Диаграмма IDEF0































































Рисунок 3. Диаграмма IDEF0



3.4 Требования к надежности

Возможность сворачивания и разворачивание приложения обеспечивается методом onResume и onPause. События ОС обрабатываются при постановке приложения на паузу.

3.5 Эргономические и техникоэстетические требования







Рисунок 4. Use Case диаграмма



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

Дизайн меню и элементов управления должен соответствовать дизайну ОС.

Использовать объекты (виджеты), представленные в AndroidSDK. Не перегружать пользовательский интерфейс излишними элементами.

Основное меню должно быть выдержано в тёмных тонах с фоновым изображением на морскую тематику.

Игровое поле должно целиком помещаться на экране в вертикальном режиме отображения.





3.6 Требования к защите информации

Готовое приложение упаковано в apk файл.

Защита от реверс-инжинеринга обеспечивается встроенной в среду разработки программой ProGuard.

3.7 Другие требования к разработке

Реализовать алгоритм выбора клетки для атаки на основе уже выбранных клеток.

3.8 Требования к аппаратно-программному комплексу.

Разработка ориентирована на Android 2.2API Level: 9.Работа возможна на устройствах с различным типом экрана. Поддержка мультитача не требуется.

3.9 Требования к технологиям разработки

Разработка ведётся с использованием среды разработки Eclipse 3.6 (Helios) с установленным ADK плагином, JDK и Android SDK.

3.10 Требования к составу технических средств при эксплуатации.

Устройство с поддержкой необходимой версии Android и удовлетворяющее описанным характеристикам.

4 МЕТОДЫ ТЕСТИРОВАНИЯ СООТВЕТСТВИЯ РАЗРАБОТКИ ПРЕДЪЯВЛЕННЫМ ТРЕБОВАНИЯМ

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




ПРИЛОЖЕНИЕ Б ПРОГРАММНЫЙ КОД

Battle.java

package ru.ship.game;

import java.util.Random;

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.util.Log;

public class Battle extends Activity {

	private static final String TAG = "BattleShip";

	public static final int HERE_SHIP_1=1;//здесь есть 1 корабль

	public static final int HERE_SHIP_2=2;//здесь есть 2 корабль

	public static final int HERE_SHIP_3=3;//здесь есть 3 корабль

	public static final int HERE_SHIP_4=4;//здесь есть 4 корабль

	public static final int HERE_NO_CHOOSE=5;//здесь уже ничего быть не может

	public static final int BOMB_HERE=6;//клетка атакована

	public static final int SHIP_ON_FIRE=7;

	private int ships_count=0; 

	public static int[][] field_gamer=new int[11][11];//поля игрока и оппонента

	public static int[][] field_opp=new int[11][11];

public static boolean comm_attack=true;

	public static final int IDM_GAMER_ROUND=100; //интент актив. мен.

	public static final int IDM_OPP_ROUND=200;

	int opp=GameStats.total_ships_opp_count;

	protected void onCreate(Bundle savedInstanceState) {

	super.onCreate(savedInstanceState);

	new Thread(new Runnable() {public void run() {autoPlacing(field_opp);				autoPlacing(field_gamer);}}).start();

	Intent intent=new Intent();

	intent.setClass(getApplicationContext(), GamerRound.class);

	      Intent intent_opp=new Intent();

	      intent_opp.setClass(getApplicationContext(), OppRound.class);

	     Intent finIntent=new Intent();

		finIntent.setClass(getApplicationContext(), FinishSplash.class);

		startActivity(finIntent);

		opp=4;

		do {

		startActivity(intent_opp);

		startActivity(intent);

		opp-=1;

		}while(opp==0); }

	@Override

	protected void onResume() {

		super.onResume();

		opp=GameStats.total_ships_opp_count; }

	@Override

	protected void onSaveInstanceState(Bundle savedInstanseState) {

		super.onSaveInstanceState(savedInstanseState);

		//savedInstanseState.putInt(key, value);	}

public static int attack(int selX, int selY,int field_gamer[][]) {

if(field_gamer[selX][selY]>HERE_NO_CHOOSE) return -1;//не важно

		if(field_gamer[selX][selY]==0 || field_gamer[selX][selY]==HERE_NO_CHOOSE) {//если клетка пустая то записываем что её удже атаковали

field_gamer[selX][selY]=BOMB_HERE; return 0; }

		if(field_gamer[selX][selY]<5) {//если не пустая то записываем что тут корабль взорван	

		if(field_gamer[selX][selY]==HERE_SHIP_1) {//если игрок нашёл однотрубник то и искать дальше нечего

		field_gamer[selX][selY]=SHIP_ON_FIRE;

		field_gamer[selX+1][selY-1]=BOMB_HERE;

		field_gamer[selX+1][selY]=BOMB_HERE;

		field_gamer[selX+1][selY-1]=BOMB_HERE;

		field_gamer[selX][selY-1]=BOMB_HERE;

		field_gamer[selX][selY+1]=BOMB_HERE;

		field_gamer[selX-1][selY-1]=BOMB_HERE;

		field_gamer[selX-1][selY]=BOMB_HERE;

		field_gamer[selX-1][selY+1]=BOMB_HERE;

		GameStats.total_ships_opp_count-=1; }//вычёркиваем корабль у противника

		if(field_gamer[selX][selY]==HERE_SHIP_3) {//

		field_gamer[selX][selY]=SHIP_ON_FIRE; 

		GameStats.ship_3_opp_heal-=1;

		if(GameStats.ship_3_opp_heal==0) GameStats.total_ships_opp_count-=1;

			}

		if(field_gamer[selX][selY]==HERE_SHIP_4) {

		field_gamer[selX][selY]=SHIP_ON_FIRE; 

		GameStats.ship_4_opp_heal-=1;

		if(GameStats.ship_4_opp_heal==0) GameStats.total_ships_opp_count-=1;}

	return 1; }//успешно

		return 0; }//промах

	private void autoPlacing(int field_gamer[][]) {//авто расстановка

Random generateRandom=new Random();

		int gorizont=0;

		int vertic=0;

		int tmep_gorizont=0;

		//расставляем 4х трубные

		int choose=generateRandom.nextInt(2);

			switch(choose) {

			case 0: //ставимпогоризонтали

tmep_gorizont=gorizont=generateRandom.nextInt(6)+1;//конец не включая

vertic=generateRandom.nextInt(9)+1;//корабль нельзя начать на буферных полях 0,0 и 10,10

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

						

field_gamer[tmep_gorizont][vertic]=HERE_SHIP_4;

field_gamer[tmep_gorizont][vertic-1]=HERE_NO_CHOOSE;

field_gamer[tmep_gorizont][vertic+1]=HERE_NO_CHOOSE;

tmep_gorizont+=1; }//переходим на следующую клетку

				

field_gamer[gorizont-1][vertic]=HERE_NO_CHOOSE;//конец и начало

field_gamer[gorizont+4][vertic]=HERE_NO_CHOOSE;

field_gamer[gorizont-1][vertic+1]=HERE_NO_CHOOSE;//диагональные клетки

field_gamer[gorizont-1][vertic-1]=HERE_NO_CHOOSE;//диагональные клетки

field_gamer[gorizont+4][vertic+1]=HERE_NO_CHOOSE;

field_gamer[gorizont+4][vertic-1]=HERE_NO_CHOOSE;

break;

		case 1://поехали по вертикали

gorizont=generateRandom.nextInt(9)+1;//конец не включая

int tmep_vertic=vertic=generateRandom.nextInt(6)+1;

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

field_gamer[gorizont][tmep_vertic]=HERE_SHIP_4;

field_gamer[gorizont-1][tmep_vertic]=HERE_NO_CHOOSE;

field_gamer[gorizont+1][tmep_vertic]=HERE_NO_CHOOSE;

		tmep_vertic+=1; }

field_gamer[gorizont][vertic-1]=HERE_NO_CHOOSE;

field_gamer[gorizont][vertic+4]=HERE_NO_CHOOSE;

field_gamer[gorizont-1][vertic-1]=HERE_NO_CHOOSE;

field_gamer[gorizont+1][vertic-1]=HERE_NO_CHOOSE;

field_gamer[gorizont-1][vertic+4]=HERE_NO_CHOOSE;

field_gamer[gorizont+1][vertic+4]=HERE_NO_CHOOSE;

		break; }//закончили 4х трубный

		do {//начинаем 3 трубные 2 штуки

		gorizont=0;

		vertic=0;

		tmep_gorizont=0;

int choose1=generateRandom.nextInt(2);

		switch(choose1) {

		case 0: //ставим по горизонтали

			//два корабля ставим

booleanenter=false; //надо ли ещё раз генерить новую точку отсчёта

int ship_place=tmep_gorizont=gorizont=generateRandom.nextInt(6)+1; //конец не включая

vertic=generateRandom.nextInt(9)+1;//корабль нельзя начать на буферных полях 0,0 и 10,10

for(intk=0;k<HERE_SHIP_3;k++) { //если уже занято одна клетка if(field_gamer[ship_place][vertic]==0

 && (field_gamer[ship_place][vertic+1]>4||field_gamer[ship_place][vertic+1]==0)

 && (field_gamer[ship_place][vertic-1]>4|| field_gamer[ship_place][vertic-1]==0)

 && (field_gamer[gorizont-1][vertic]>4|| field_gamer[gorizont-1][vertic]==0) 

&&(field_gamer[gorizont+HERE_SHIP_3][vertic]>4||field_gamer[gorizont+HERE_SHIP_3][vertic]==0) &&(field_gamer[gorizont-1][vertic+1]>4||field_gamer[gorizont-1][vertic+1]==0)  

&&(field_gamer[gorizont-1][vertic-1]>4    || field_gamer[gorizont-1][vertic-1]==0) 

&&(field_gamer[gorizont+HERE_SHIP_3][vertic+1]>4||field_gamer[gorizont+HERE_SHIP_3][vertic+1]==0)&&(field_gamer[gorizont+HERE_SHIP_3][vertic-1]>4|| field_gamer[gorizont+HERE_SHIP_3][vertic-1]==0))	{

enter=true; }

else{enter=false; break;}

ship_place=ship_place+1;}

		if(enter) {//если занято то не выполнится цикл

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

field_gamer[tmep_gorizont][vertic]=HERE_SHIP_3;

field_gamer[tmep_gorizont][vertic-1]=HERE_NO_CHOOSE;

field_gamer[tmep_gorizont][vertic+1]=HERE_NO_CHOOSE;

tmep_gorizont=tmep_gorizont+1; }//переходим на следующую клетку

field_gamer[gorizont-1][vertic]=HERE_NO_CHOOSE;

field_gamer[gorizont+3][vertic]=HERE_NO_CHOOSE;

field_gamer[gorizont-1][vertic+1]=HERE_NO_CHOOSE;//диагональные клетки

field_gamer[gorizont-1][vertic-1]=HERE_NO_CHOOSE;//диагональные клетки

field_gamer[gorizont+HERE_SHIP_3][vertic+1]=HERE_NO_CHOOSE;

field_gamer[gorizont+HERE_SHIP_3][vertic-1]=HERE_NO_CHOOSE;

		ships_count=ships_count+1; }

		break;

		case 1: //повертикали

		intt2_vertic=0;

booleanenter1=false; //надо ли ещё раз генерить новую точку отсчёта

ship_place=gorizont=generateRandom.nextInt(9)+1;//конец не включая

int t_vertic=t2_vertic=vertic=generateRandom.nextInt(6)+1;//корабль нельзя начать на буферных полях 0,0 и 10,10

		for(intk=0;k<HERE_SHIP_3;k++) {//если уже занято одна клетка

if(field_gamer[gorizont][t_vertic]==0&&(field_gamer[gorizont+1][t_vertic]>4|| field_gamer[gorizont+1][t_vertic]==0)&&(field_gamer[gorizont-1][t_vertic]>4|| field_gamer[gorizont-1][t_vertic]==0)&&(field_gamer[gorizont+1][vertic-1]>4|| field_gamer[gorizont+1][vertic-1]==0)&&(field_gamer[gorizont][vertic+HERE_SHIP_3]>4 ||field_gamer[gorizont][vertic+HERE_SHIP_3]==0)&&(field_gamer[gorizont-1][vertic-1]>4||field_gamer[gorizont-1][vertic-1]==0)&&(field_gamer[gorizont-1][vertic+HERE_SHIP_3]>4 || field_gamer[gorizont-1][vertic+HERE_SHIP_3]==0)&&	  (field_gamer[gorizont+1][vertic+HERE_SHIP_3]>4|| field_gamer[gorizont+1][vertic+HERE_SHIP_3]==0)) {					

		enter1=true; }

		else { enter1=false; break;}

		t_vertic=t_vertic+1; }

		if(enter1) {//если занято то ещё разок цикл вхиле

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

field_gamer[gorizont][t2_vertic]=HERE_SHIP_3;

field_gamer[gorizont-1][t2_vertic]=HERE_NO_CHOOSE;

field_gamer[gorizont+1][t2_vertic]=HERE_NO_CHOOSE;

		t2_vertic+=1; }//переходим на следующую клетку

field_gamer[gorizont][vertic-1]=HERE_NO_CHOOSE;

field_gamer[gorizont][vertic+3]=HERE_NO_CHOOSE;

field_gamer[gorizont-1][vertic-1]=HERE_NO_CHOOSE;

field_gamer[gorizont+1][vertic-1]=HERE_NO_CHOOSE;

field_gamer[gorizont-1][vertic+3]=HERE_NO_CHOOSE;

field_gamer[gorizont+1][vertic+3]=HERE_NO_CHOOSE;

		ships_count=ships_count+1; 

		break; }//КОНЕЦ РАССТАНОВКИ

		} while(ships_count<3);

/*//начинаемдвухтрубники 3 штуки

		ships_count=0;

		int ships_2_count=0;

		do {//

		gorizont=0;

		vertic=0;

		tmep_gorizont=0;

		int choose2=generateRandom.nextInt(2);//choose=1;

		switch(choose2) {

		case 0: //ставим по горизонтали

		//два корабля ставим

booleanenter3=false; //надо ли ещё раз генерить новую точку отсчёта

int ship_place=tmep_gorizont=gorizont=generateRandom.nextInt(6)+1;//конец не включая

vertic=generateRandom.nextInt(9)+1;//корабль нельзя начать на буферных полях 0,0 и 10,10

for(intk=0;k<HERE_SHIP_2;k++) {//если уже занято одна клетка

if(field_gamer[ship_place][vertic]==0&&(field_gamer[ship_place][vertic+1]>4||field_gamer[ship_place][vertic+1]==0)&&(field_gamer[ship_place][vertic-1]>4||field_gamer[ship_place][vertic-1]==0)&&(field_gamer[gorizont-1][vertic]>4|| field_gamer[gorizont-1][vertic]==0)&&(field_gamer[gorizont+HERE_SHIP_2][vertic]>4 || field_gamer[gorizont+HERE_SHIP_2][vertic]==0)&&(field_gamer[gorizont-1][vertic+1]>4    ||field_gamer[gorizont-1][vertic+1]==0)&&(field_gamer[gorizont-1][vertic-1]>4|| field_gamer[gorizont-1][vertic-1]==0)

&&(field_gamer[gorizont+HERE_SHIP_2][vertic+1]>4||field_gamer[gorizont+HERE_SHIP_2][vertic+1]==0)&&(field_gamer[gorizont+HERE_SHIP_2][vertic-1]>4|| field_gamer[gorizont+HERE_SHIP_2][vertic-1]==0))	{

		enter3=true; }

		else {enter3=false;break;}

		ship_place=ship_place+1; }

		if(enter3) {//если занято то не выполнится цикл

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

field_gamer[tmep_gorizont][vertic]=HERE_SHIP_2;

field_gamer[tmep_gorizont][vertic-1]=HERE_NO_CHOOSE; field_gamer[tmep_gorizont][vertic+1]=HERE_NO_CHOOSE;

	 	tmep_gorizont+=1; }//переходим на следующую клетку

field_gamer[gorizont-1][vertic]=HERE_NO_CHOOSE;

field_gamer[gorizont+3][vertic]=HERE_NO_CHOOSE;

		ships_2_count=ships_2_count+1;}			

		break;

		case 1: //повертикали

booleanenter2=false;//надо ли ещё разгенерить новую точку отсчёта

ship_place=gorizont=generateRandom.nextInt(9)+1;//конец не включая 

int t_vertic=vertic=generateRandom.nextInt(6)+1;//корабль нельзя начать на буферных полях 0,0 и 10,10

		for(intk=0;k<HERE_SHIP_2;k++) {//если уже занято одна клетка

if(field_gamer[gorizont][t_vertic]==0&&(field_gamer[gorizont+1][t_vertic]>4|| field_gamer[gorizont+1][t_vertic]==0)&&(field_gamer[gorizont-1][t_vertic]>4|| field_gamer[gorizont-1][t_vertic]==0)&&(field_gamer[gorizont+1][vertic-1]>4|| field_gamer[gorizont+1][vertic-1]==0)&& field_gamer[gorizont][vertic+HERE_SHIP_2]>4||field_gamer[gorizont][vertic+HERE_SHIP_2]==0)&&(field_gamer[gorizont-1][vertic-1]>4||field_gamer[gorizont-1][vertic-1]==0)&&(field_gamer[gorizont-1][vertic+HERE_SHIP_2+1]>4||field_gamer[gorizont-1][vertic+HERE_SHIP_2+1]==0)&&(field_gamer[gorizont+1][vertic+HERE_SHIP_2+1]>4 || field_gamer[gorizont+1][vertic+HERE_SHIP_2+1]==0))  {

		enter2=true; }

else {enter2=false;break;}

		t_vertic=t_vertic+1; }

		if(enter2) {//если занято то ещё разок цикл вхиле

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

field_gamer[gorizont][t_vertic]=HERE_SHIP_2;

field_gamer[gorizont-1][t_vertic]=HERE_NO_CHOOSE;

field_gamer[gorizont+1][t_vertic]=HERE_NO_CHOOSE;

		t_vertic+=1; }//переходим на следующую клетку

field_gamer[gorizont-1][vertic]=HERE_NO_CHOOSE;

field_gamer[gorizont+3][vertic]=HERE_NO_CHOOSE;

		ships_2_count=ships_2_count+1;}

		break;}//КОНЕЦРАССТАНОВКИ

		} while(ships_2_count<3);*/

		//начинаем 1хтрубники

		int ship_4_count=0;

		do {

		//boolean enter_4=false;

		int gorizont_4=generateRandom.nextInt(9)+1;

		int vertic_4=generateRandom.nextInt(9)+1;

if(field_gamer[gorizont_4][vertic_4]==0&&(field_gamer[gorizont_4+1][vertic_4-1]==0 ||field_gamer[gorizont_4+1][vertic_4-1]>4) && (field_gamer[gorizont_4+1][vertic_4]==0 || field_gamer[gorizont_4+1][vertic_4]>4) && (field_gamer[gorizont_4+1][vertic_4-1]==0 ||field_gamer[gorizont_4+1][vertic_4-1]>4) && (field_gamer[gorizont_4][vertic_4-1]==0 ||field_gamer[gorizont_4][vertic_4-1]>4) && (field_gamer[gorizont_4][vertic_4+1]==0 ||field_gamer[gorizont_4][vertic_4+1]>4) &&  (field_gamer[gorizont_4-1][vertic_4-1]==0 ||field_gamer[gorizont_4-1][vertic_4-1]>4) &&  (field_gamer[gorizont_4-1][vertic_4]==0 ||field_gamer[gorizont_4-1][vertic_4]>4) &&   (field_gamer[gorizont_4-1][vertic_4+1]==0 ||field_gamer[gorizont_4-1][vertic_4+1]>4)) {

field_gamer[gorizont_4][vertic_4]=HERE_SHIP_1;					   field_gamer[gorizont_4+1][vertic_4-1]=HERE_NO_CHOOSE;

field_gamer[gorizont_4+1][vertic_4]=HERE_NO_CHOOSE;

field_gamer[gorizont_4+1][vertic_4-1]=HERE_NO_CHOOSE;

field_gamer[gorizont_4][vertic_4-1]=HERE_NO_CHOOSE;

field_gamer[gorizont_4][vertic_4+1]=HERE_NO_CHOOSE;

field_gamer[gorizont_4-1][vertic_4-1]=HERE_NO_CHOOSE;

field_gamer[gorizont_4-1][vertic_4]=HERE_NO_CHOOSE;

field_gamer[gorizont_4-1][vertic_4+1]=HERE_NO_CHOOSE;

		ship_4_count+=1;}

		} while(ship_4_count<6);}	//функция атаки корабля противником

		static int[] autoAttack(int field_gamer[][]) {

		int m_att_y=0,m_i=0;

		int[] return_coord=new int[3];

		Random attRand=new Random();

		int att_x = 0;

		int att_y = 0;

		GameStats.bot_mem_full=false;

		if(!GameStats.bot_mem_full) {//если память бота пуста

		boolean att_ok=false;//успех атаки

while(!att_ok) {//это чтобы бот не ошибался и не кликал по уже атакованым клеткам и клеткам где физически не может быть корабля

		att_x=attRand.nextInt(9)+1;

		att_y=attRand.nextInt(9)+1;//выбор клетки для атаки

if(field_gamer[att_x][att_y]!=SHIP_ON_FIRE && field_gamer[att_x][att_y]!=BOMB_HERE) 

att_ok=true; } 

		if(field_gamer[att_x][att_y]==0){ field_gamer[att_x][att_y]=BOMB_HERE;return_coord[0]=att_x;return_coord[1]=att_y;return_coord[2]=0; return return_coord; }//если клетка пуста то отметка об атаке

if(field_gamer[att_x][att_y]==HERE_SHIP_1) {//если бот нашёл однотрубник то и искать дальше нечего

field_gamer[att_x][att_y]=SHIP_ON_FIRE;

field_gamer[att_x+1][att_y-1]=BOMB_HERE;

field_gamer[att_x+1][att_y]=BOMB_HERE;

field_gamer[att_x+1][att_y-1]=BOMB_HERE;

field_gamer[att_x][att_y-1]=BOMB_HERE;

field_gamer[att_x][att_y+1]=BOMB_HERE; 

field_gamer[att_x-1][att_y-1]=BOMB_HERE;

field_gamer[att_x-1][att_y]=BOMB_HERE;

field_gamer[att_x-1][att_y+1]=BOMB_HERE;

GameStats.total_ships_gamer_count-=1;//вычёркиваем корабль у игрока

		  return_coord[0]=att_x;

		  return_coord[1]=att_y;

		  return_coord[2]=1;

		  return return_coord; } //попадание!

if(field_gamer[att_x][att_y]==HERE_SHIP_3) {

field_gamer[att_x][att_y]=SHIP_ON_FIRE; GameStats.ship_3_gamer_heal-=1;	

if(GameStats.ship_3_gamer_heal==0)

GameStats.total_ships_gamer_count-=1;//запоминаем координаты

GameStats.ship_3_gamer_coord[0]=att_x;

GameStats.ship_3_gamer_coord[1]=att_y;

GameStats.bot_last_found=HERE_SHIP_3;

GameStats.bot_mem_full=true;

		return_coord[0]=att_x; 

		return_coord[1]=att_y;

		return_coord[2]=1;

		return return_coord;}

if(field_gamer[att_x][att_y]==HERE_SHIP_4) {

field_gamer[att_x][att_y]=SHIP_ON_FIRE; GameStats.ship_4_gamer_heal-=1;	

if(GameStats.ship_4_gamer_heal==0) GameStats.total_ships_gamer_count-=1;

GameStats.ship_4_gamer_coord[0]=att_x;

GameStats.ship_4_gamer_coord[1]=att_y;

GameStats.bot_last_found=HERE_SHIP_4;

GameStats.bot_mem_full=true;

		return_coord[0]=att_x; 

		return_coord[1]=att_y;

		return_coord[2]=1;

		return return_coord;}

		} //конец пустой атаки

	

	////////////////////////////////////////////////////////

		//начало продолжения атаки по памяти		

		if(GameStats.bot_mem_full ){	

		boolean comm_att_ok=false;

		int now_att_direction=5; //текущее направление атаки

if(field_gamer[att_x][att_y]==HERE_SHIP_3) {

field_gamer[att_x][att_y]=SHIP_ON_FIRE; GameStats.ship_3_gamer_heal-=1;

		do {

int choose_att_direction=attRand.nextInt(1);//выбираем одно из 4х направлений атаки

		if(now_att_direction!=5) choose_att_direction=now_att_direction;//сохраняем в текущее нпавление если оно есть

		switch(choose_att_direction) {

		case 0://влево

for(inti=1;i<HERE_SHIP_3;i++) {//если на пути есть препятсвие то выход из цикла

if(field_gamer[att_x][att_y-i]==BOMB_HERE||field_gamer[att_x][att_y-i]==SHIP_ON_FIRE) break;

		else { comm_att_ok=true;//если же направление атаки логично

			if(field_gamer[att_x][att_y-i]==HERE_SHIP_3) {

field_gamer[att_x][att_y-i]=BOMB_HERE;  m_att_y=att_y-1;//сдвигаемся на клетку и продолжаем атаку в том же направлении

		now_att_direction=choose_att_direction;}

else{field_gamer[att_x][att_y-i]=BOMB_HERE;GameStats.bot_mem_full=true; GameStats.bot_mem[0]=att_x;GameStats.bot_mem[1]=att_y-i;return_coord[0]=att_x;return_coord[1]=att_y-i;return_coord[2]=0;GameStats.bot_last_found=HERE_SHIP_3;return return_coord;}

		}

		}break; 

		case 1://вправо

for(inti=1;i<HERE_SHIP_3;i++) {//если на пути есть препятсвие то выход из цикла

if(field_gamer[att_x][att_y+i]==BOMB_HERE||field_gamer[att_x][att_y-i]==SHIP_ON_FIRE) break;

		else { comm_att_ok=true;

		if(field_gamer[att_x][att_y+i]==HERE_SHIP_3) {

field_gamer[att_x][att_y+i]=SHIP_ON_FIRE; m_att_y=att_y=+i;

		now_att_direction=choose_att_direction;}

else{

field_gamer[att_x][att_y+i]=BOMB_HERE;GameStats.bot_mem_full=true; GameStats.bot_mem[0]=att_x;GameStats.bot_mem[1]=att_y+1;GameStats.bot_last_found=HERE_SHIP_3;}

		}

		}break;

		case 2://вверх

for(inti=1;i<HERE_SHIP_3;i++) {//если на пути есть препятсвие то выход из цикла

if(field_gamer[att_x-i][att_y]==BOMB_HERE || field_gamer[att_x][att_y-i]==SHIP_ON_FIRE)

break;

		else { comm_att_ok=true;

field_gamer[att_x-i][att_y]=BOMB_HERE; att_x=-i;

		now_att_direction=choose_att_direction;}

		}break;	

		case 3://вниз			

for(inti=1;i<HERE_SHIP_3;i++) {//если на пути есть препятсвие то выход из цикла

if(field_gamer[att_x-i][att_y]==BOMB_HERE||field_gamer[att_x][att_y-i]==SHIP_ON_FIRE )

 break;

else { comm_att_ok=true;

field_gamer[att_x+i][att_y]=BOMB_HERE; att_x=+i;

		now_att_direction=choose_att_direction; }	

		}break;

		}

		}while(!comm_att_ok);//совершаем атаку в выбранном направлении

		} 

		}

if(field_gamer[att_x][att_y]==0||field_gamer[att_x][att_y]>HERE_SHIP_4)  field_gamer[att_x][att_y]=BOMB_HERE;

		else field_gamer[att_x][att_y]=SHIP_ON_FIRE;

		return_coord[0]=att_x; 

		return_coord[1]=att_y;

		return_coord[2]=0;

		return return_coord;}

}




BattleView.java

package ru.ship.game;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.Rect;

import android.view.MotionEvent;

import android.view.View;

import android.widget.Toast;

class ViewBattle extends View {

privatefinal OppRound oppRound;

privatestaticfinalintRESULT_OK = -1;

	privateintheight;

	privateintwidth;

	privateintselX;       // X index of selection

	privateintselY;       // Y index of selection

	privatefinal Rect selRect = new Rect();

	privatefinal Rect attackedRect = new Rect();

	privatefinal Rect ship4Rect = new Rect();

	privatefinal Rect ship3Rect = new Rect();

	privatefinal Rect ship2Rect = new Rect();

	privatefinal Rect ship1Rect = new Rect();

	privateintattack_coord[]=newint[3];

	publicintattack_result=5;

		public ViewBattle(Context context) {

		super(context);

		setFocusable(true);

		this.oppRound = (OppRound) context;

		setId(43);//устанавливаемномервьюва

		}

	publicvoid onDraw(Canvas canvas) {

		Paint background=newPaint();

		background.setColor(getResources().getColor(R.color.backBattle));//рисуемизакрашиваемзадник

canvas.drawRect(0, 0, getWidth(), getHeight(), background);//рисуемсетку

Paint grid = newPaint();

grid.setColor(getResources().getColor(R.color.grid_color));

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

canvas.drawLine(0, i * height, getWidth(), i * height,grid);//горизонатльные

canvas.drawLine(i * width, 0, i * width, getHeight(),grid); }//вертикальные

		 //выделяемвыбраннуюклетку

Paint selected=newPaint();

selected.setColor(getResources().getColor(R.color.grid_color));

canvas.drawRect(selRect, selected);

 Paint attacked=newPaint();

attacked.setColor(getResources().getColor(R.color.attacked));//краскадляатакованногокорабля

 Paint empty=newPaint();

		empty.setColor(getResources().getColor(R.color.no_choose));//краскадляклеткиатакованнойнопустой

		  Paint ship_4=newPaint();

		  ship_4.setColor(getResources().getColor(R.color.ship_4));

		  Paint ship_3=newPaint();

		  ship_3.setColor(getResources().getColor(R.color.ship_3));

		  Paint ship_2=newPaint();

		  ship_2.setColor(getResources().getColor(R.color.ship_2));

		  Paint ship_1=newPaint();

		  ship_1.setColor(getResources().getColor(R.color.ship_1));

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

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

if(Battle.field_gamer[i][j]==Battle.BOMB_HERE) {//еслинашлинаместеатаки 4 корабль

attackedRect.set(i*width, j*height,i*width+50,j*height+50);

canvas.drawRect(attackedRect,  empty);}

if(Battle.field_gamer[i][j]==Battle.SHIP_ON_FIRE) {//еслинашлинаместеатакикорабль

attackedRect.set(i*width, j*height,i*width+50,j*height+50);

canvas.drawRect(attackedRect,  attacked);}

if(Battle.field_gamer[i][j]==Battle.HERE_SHIP_4) {//еслинашлинаместеатаки 4 корабль

ship4Rect.set(i*width, j*height,i*width+50,j*height+50);

canvas.drawRect(ship4Rect,  ship_4);}

if(Battle.field_gamer[i][j]==Battle.HERE_SHIP_3) {//еслинашлинаместеатаки 4 корабль

ship3Rect.set(i*width, j*height,i*width+50,j*height+50);

canvas.drawRect(ship3Rect,  ship_3);}

if(Battle.field_gamer[i][j]==Battle.HERE_SHIP_2) {//еслинашлинаместеатаки 4 корабль

ship2Rect.set(i*width, j*height,i*width+50,j*height+50);

canvas.drawRect(ship2Rect,  ship_2); }

if(Battle.field_gamer[i][j]==Battle.HERE_SHIP_1) {//еслинашлинаместеатаки 4 корабль

ship1Rect.set(i*width, j*height,i*width+50,j*height+50);

canvas.drawRect(ship1Rect,  ship_1);   }}}}

publicboolean onTouchEvent(MotionEvent event) {

if (event.getAction() != MotionEvent.ACTION_DOWN)

returnsuper.onTouchEvent(event);

attack_coord=Battle.autoAttack(Battle.field_gamer);

select(attack_coord[0], attack_coord[1]);

if(attack_coord[2]==0) {//если промахнулся то завершаем активити

Toast.makeText( getContext(), "Промах", Toast.LENGTH_SHORT).show();

		oppRound.setResult(RESULT_OK);

		oppRound.finish();}		

		else {

Toast.makeText( getContext(), "Прямоепопадание!", Toast.LENGTH_SHORT).show();	}

invalidate();

		returntrue; }

	

@Override

protectedvoid onSizeChanged(int w,int h,int oldw,int oldh) {

	width = w /10;

	height = h /10;

	getRect(selX, selY, selRect);

	getRect(selX,selY,ship1Rect);

	getRect(selX,selY,ship3Rect);

	getRect(selX,selY,attackedRect);

	getRect(selX,selY,ship2Rect);

	getRect(selX,selY,ship4Rect);

	super.onSizeChanged(w, h, oldw, oldh);}

	privatevoid getRect(int x, int y, Rect rect) {

	rect.set((int) (x * width), (int) (y * height), (int) (x

* width + width), (int) (y * height + height)); }

privatevoid select(int x, int y) {

	invalidate(selRect);

	selX = Math.min(Math.max(x, 0), 9);

	selY = Math.min(Math.max(y, 0), 9);

	if(Battle.field_gamer[selX][selY]>0 && Battle.field_gamer[selX][selY]<5) { getRect(selX, selY, attackedRect); invalidate(attackedRect);}

	getRect(selX, selY, selRect);

	invalidate(selRect);

	}

	

}










39