Разработка программного продукта, реализующего классическую версию настольной игры 'Морской бой'

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    2,83 Мб
  • Опубликовано:
    2013-10-24
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Разработка программного продукта, реализующего классическую версию настольной игры 'Морской бой'

Министерство образования и науки российской федерации

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

Санкт-Петербургский национальный исследовательский университет информационных технологий, механики и оптики







ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

К КУРСОВОМУ ПРОЕКТУ

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

на тему: Разработка программного продукта, реализующего классическую версию настольной игры "Морской бой"


Программное обеспечение вычислительной

техники и  автоматизированных систем (230105)




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

КРАТКОЕ СОДЕРЖАНИЕ РАБОТЫ И ОСНОВНЫЕ ВЫВОДЫ

·        Целью является проектирование и разработка программного продукта, реализующего игру «морской бой».

Задачи:

1.      Анализ предметной области

.        Обзор аналогов продукта

.        Составление требований

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

.        Проектированиепрограммного продукта

.        Разработка программного продукта

.        Тестирование программного продукта

.        Составление документации

·        Исследовательская часть

Были рассмотрены различные аналоги программного продукта и их основной функционал.

·        Проектная часть

Проектирование производилось путём составления диаграмм UML, IDEF0, DFD, моделирующих требования к программному продукту.

·        Часть реализации

Программный продукт разработан с использованием языка C# ифреймворка.NETFramework 3.5.

·        Тестирование компонентов

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

Практическая ценность работы. Рекомендации по внедрению

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

Оглавление

ВВЕДЕНИЕ

1. ПОСТАНОВКА ЗАДАЧИ

1.1 Анализ предметной области

1.2 Обзор аналогов

1.3 Постановка задачи

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

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

2.2 Планирование

2.3 Описание выполняемого технического задания

3. ПРОЕКТИРОВАНИЕ

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

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

3.2.1 Компоненты системы

3.2.2 Классы системы

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

3.3.1 Диаграмма деятельности

3.3.2 Диаграмма состояний

3.3.3 Диаграмма коммуникаций

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

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

5. ВЕРИФИКАЦИЯ И АТТЕСТАЦИЯ

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

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

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

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

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

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

ЗАКЛЮЧЕНИЕ

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

Приложение 1 - Диаграммы

Приложение 2 - Техническое задание

Приложение 3 - Исходный код

ВВЕДЕНИЕ

Данная работа посвящена разработке программного продукта, реализующего классическую версию настольной игры «морской бой».

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

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

1. ПОСТАНОВКА ЗАДАЧИ

 

.1 Анализ предметной области


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

Всего кораблей в игре 10: 1 четырёхпалубный, 2 трёхпалубных, 3 двухпалубных и 4 однопалубных. Между кораблями должно быть расстояние как минимум 1 пустая клетка.

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

Целевую аудиторию составляют люди, которые хотят играть в «морской бой».Игроки будут иметь возможность играть с искусственным интеллектом на любом из предложенных уровней сложности.

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

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

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

 

.2 Обзораналогов


Battleships - GeneralQuartersII.

Игра «Морской бой», выполненная не в классической форме. Всего можно расставить 5 кораблей: один на 2 клетки, два на 3 клетки, один на 4 клетки и один на 5 клеток. Корабли можно расставлять вплотную друг к другу. После каждого попадания на короткое время появляется комментарий от капитана.

Ссылка на официальную веб-страницу: #"656653.files/image001.gif">

Рисунок 1.

 

.3 Описание выполняемого технического задания


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

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

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

.        Автоматическая расстановка кораблей.

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

.        Стрельба по полю.

Без этого требования игра теряет смысл, оно является основным при разработке проекта. Включает выбор клетки и её обработку.

.        Искусственный интеллект.

Для данной разработки также является необходимым требованием. Содержит 3 различных алгоритма работы в зависимости от уровня сложности.

.        Выбор уровня сложности.

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

3. ПРОЕКТИРОВАНИЕ

 

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


Модель системы данного проекта описана на диаграмме компонентов, которая представлена в приложении 1 на рисунке 9.

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

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

 

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

 

.2.1 Компоненты системы

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

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

Компонент обработки выстрела по клетке проверяет корректность выбранной клетки (т.е. проверка на то, не было ли по это клетке выстрела раньше, либо проверка на своё/чужое поле), а также определяет, есть ли по этой клетке попадание или нет.

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

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

 

.2.2 Классы системы

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

Основной класс - класс SeaBattle. Содержит основные функции игрового процесса и координирует работу всех функциональных классов.

Класс AI - класс искусственного интеллекта. Содержит алгоритмы работы ИИ, поля, используемые для работы этих алгоритмов, например, поля для сохранения координат первого попадания по кораблю, состояние уничтожения корабля, количество промахов для высокого уровня сложности.

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

Класс FormStatistic - окно статистики, которое содержит метод отображения результатов (show_result), метод сброса статистики и методы определения какую статистику надо выводить в зависимости от нажатой кнопки.

Классы Label (метка), Button (кнопка) и PictureBox (изображения) наследуются от базового класса для элементов управления Control, включённый в .NET Framework.

 

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


Логика работы программы отображена на следующих диаграммах.

 

.3.1 Диаграмма деятельности

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

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

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

 

.3.2 Диаграмма состояний

Состояния, в которых может находиться система, отображены на диаграмме состояний, представленной в приложении 1 на рисунке 12.

Система может находиться в шести различных состояниях.

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

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

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

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

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

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

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

3.3.3 Диаграмма коммуникаций.

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

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

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

Установка корабля взаимодействует с объектами класса Ship для обновления информации в них касательно размерности кораблей и их координат и объектом класса PictureBox, полем, для отображения корабля на поле

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

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

 

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

программа настольный игра

Первый экран - меню выбора уровня сложности. Он представлен на рисунке 2. Верхняя надпись просто текст, а элементы «Лёгкий», «Нормальный» и «Сложный» - кнопки, нажатие по которым сохраняет выбранный уровень сложности и происходит переход к следующему экрану. Также тут присутствует кнопка «Статистика», которая вызывает новое окно, содержащее статистику.

Фон у главного окна: текстура воды.

Рисунок 2

Экран расстановки кораблей представлен на рисунке 3. Слева расположено поле, на которое игрок должен расставить корабли. Сами корабли расположены справа от поля и счётчиками оставшихся кораблей. Корабль выбирается простым нажатием по нему. Под полем присутствуют две кнопки: «Сбросить» - сбрасывает все расставленные корабли, и «Случайно» - автоматически расставляет корабли. Кнопка «Статистика» присутствует на всех экранах главного окна.

Экран игрового процесса содержит поле игрока слева и поле компьютера справа. Под каждым полем подписано чьё это поле. Оба поля постоянно подсвечены, однако цвет подсветки зависит от того, по какому полю идёт стрельба. Голубым подсвечивается поле, по которому стреляют, а серым поле, которое находится в ожидании хода.Клетки, по которым было попадания отмечены красным, а по которым промах - белым. Экран игрового процесса представлен на рисунке 4.

Рисунок 3

Рисунок 4

Окно статистики представлено на рисунке 5. Пользователь выбирает уровень сложности, для которого он хочет посмотреть статистику. Для этого он должен нажать на одну из 3-х соответствующих кнопок. Также, нажав на кнопку «Сбросить», можно сбросить статистику. На кнопку «Закрыть» окно статистики закрывается.

Рисунок 5

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


Для разработки программного кода был выбран язык программирования C# с использованием среды разработки VisualStudio 2010.# - это язык программирования, предназначенный для разработки самых разнообразных приложений, предназначенных для выполнения в среде .NET Framework. Язык C# прост, строго типизирован и объектно-ориентирован. Благодаря множеству нововведений C# обеспечивает возможность быстрой разработки приложений, но при этом сохраняет выразительность и элегантность, присущую языкам C.C# является реализацией языка C# корпорацией Майкрософт. Visual Studio поддерживает Visual C# с полнофункциональным редактором кода, компилятором, шаблонами проектов, конструкторами, мастерами кода, мощным и простым в использовании отладчиком и многими другими средствами.

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

5. ВЕРИФИКАЦИЯ И АТТЕСТАЦИЯ

 

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


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

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

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

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

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

Для тестирование ПО были выбраны следующие методы: функциональное тестирование, тестирование белого ящика, ручное тестирование и альфа-тестирование.

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

Выделение требований из ТЗ

.        Пользовать должен иметь возможность начать игру.

.        Пользовать должен иметь возможность выбрать сложность ИИ.

.        Пользователь должен иметь возможность расставить корабли вручную.

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

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

.        ИИ должен быть 3-х уровней: легкий, средний, сложный.

.        После хода должна производиться проверка на попадание.

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

.        Пользователь не должен видеть на поле противника его корабли.

Оценка качества выполнения требованийпредставлена в таблице 3.

Таблица 3

Требование

Оценка

Комментарий

Пользовать должен иметь возможность начать игру

5

Отображено на всех диаграммах

Пользовать должен иметь возможность выбрать сложность ИИ

5

Отображено на всех диаграммах

Пользователь должен иметь возможность расставить корабли вручную

5

Отображено на всех диаграммах

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

5

Очень подробно рассмотрена в StateMachineDiagram

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

4

Присутствует на Activity Diagram

ИИ должен быть 3-х уровней: легкий, средний, сложный

5

Отображено на всех диаграммах

После хода должна производиться проверка на попадание

5

Отображено на всех диаграммах

Игра должна прекращаться после уничтожения всех кораблей

5

Отображено на всех диаграммах

Пользователь не должен видеть на поле противника его корабли

5

Не указано явно, но подразумевается


Оценка требований ТЗ по правильности формулировок представлена в таблице 4.

Таблица 4

Тип требования

Оценка

Комментарии

Описание классов пользователей

5

Указан один класс пользователя

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

5

Дано полное описание функций, их реализация и условия проверки

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

5

Входные и выходные данные подробно описаны для каждой функции

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

5

Скрытие кораблей противника

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

4

Указаны требования к программному комплексу


Комплексная оценка

Сделаны подробные диаграммы, содержащие все поставленные требования; требования ТЗ сформулированы грамотно и лаконично. Склоняюсь к комплексной оценке - 10 баллов.

 

.3 Тестирование


Функциональное тестирование.

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

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

Рисунок 6

Рисунок 7

При нажатии на кнопку «Случайно» корабли расставляются корректно, а при нажатии на кнопку «Сброс» поле очищается. Результат авто расстановки можно увидеть на рисунке 8, а очистки на рисунке 9.

Рисунок 8

Рисунок 9

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

Рисунок 10

По окончанию игры выводится соответствующее сообщение и происходит запись в статистику. Результат при победе отображён на рисунке 11.

Рисунок 11

Окно статистики приведено на рисунке 12. При нажатии на кнопки выбора уровня сложности данные выводятся правильно. После нажатия на кнопку сброс статистика сбрасывается (рисунок 13).

Рисунок 12

Рисунок 13

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

При проведении тестирования по методу «белого ящика» были проверены все функции и все возможные ветки программного кода. Ошибок обнаружено не было.

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

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

 

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


Для установки приложения достаточно просто сохранить файл SeaBattle.exe в любое удобное для пользователя места.

Для работы приложения должна быть установлена программная платформа .NET Framework версии 3.5 и выше. Скачать её можно бесплатнос официального сайта Microsoft.

Минимальные требования:

Операционная система WindowsXPи выше, разрядностью 32 или 64 бита.

Процессор с частотой 400 МГц.

ОЗУ 96 МБ.

Место на жёстком диске: 300 МБ для 32-х разрядной системы и 620 МБ для 64-х разрядной.

 

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


Для запуска нужно запустить файл SeaBattle.exe.

В первую очередь необходимо выбрать уровень сложности. Нужно просто кликнуть по любому пункту и произойдёт переход к экрану расстановки кораблей. В центре экрана представлены корабли разных типов и разного направления. Нужный корабль выбирается кликом по нему. Дальше нужно установить корабль на поле слева. При этом при наведении на поле будет отображаться контур корабля, привязанный к курсору и отображающий возможность установки в выбранном месте. В любой момент можно поменять корабль на любой другой кликнув на нём. При этом курсор изменится согласно выбранному кораблю. Если установка прошла корректно, счётчик у соответствующего типа корабля уменьшится на 1. Если пользователь не желает устанавливать корабли вручную, он может сделать это автоматически кликнув по кнопке «Случайно». В любой момент игрок может сбросить установку, нажав на кнопку «Сбросить». Когда все корабли будут установлены, появится кнопка «BATTLE», при нажатии на которую произойдёт начало игры с изменением текущего экрана и генерацией поля противника справа.

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

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

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

ЗАКЛЮЧЕНИЕ


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

·        различные уровни сложности игры;

·        автоматическая расстановка кораблей;

·        искусственный интеллект;

·        визуализация интерфейса;

·        статистика.

Помимо этого, в программе реализован дополнительный функционал:

·        подсвечивание полей, в зависимости от того, чей в данный момент ход;

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

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

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

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

.        Базарная Е.Г. Создание Windows приложений на языке С# / Е.Г. Базарная, В.В. Изварина - СПб.: УЦВТ, 2007.

.        Программирование на платформе .NET Framework в Visual Studio, Web: #"656653.files/image014.gif">

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

Рисунок 2 - Развёрнутая диаграмма основного процесса

Рисунок 3 - Развёрнутая диаграмма процесса расстановки кораблей

Рисунок 4 - Диаграмма процесса игры

Рисунок 5 -Диаграмма хода игрока

Рисунок 6 -Диаграмма проверки на победу и следующего хода

Рисунок 7. Диаграмма Use-Case

Рисунок 8. Component Diagram

Рисунок 9. Class Diagram

Рисунок 10. Activity Diagram

Рисунок 11. State Machine Diagram

Рисунок 12. Communication Diagram

Рисунок 13. Sequence Diagram

Приложение 2 - Техническое задание

1 Назначение разработки

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

Цель и задачи

Цель: разработать программный продукт, реализующий игру «Морской бой».

Задачи:

.        Реализовать оформление приложения, расположить элементы управления.

.        Разработать функцию генерации поля.

.        Разработать функции навигации и стрельбы по полю.

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

.        Реализовать работу со статистикой.

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

.1 Описание классов пользователей

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

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

Список функций:

Функция 1.

Имя: Начало игры.

Описание: Начать игру необходимо для того, чтобы играть в «Морской бой».

Реализация: Нажать кнопку «Новая игра».

Проверка: Произошёл переход в следующее меню.

Функция 2.

Имя: Уровень сложности.

Описание: Необходимо выбрать уровень сложности ИИ и подтвердить выбор. Дальше произойдёт переход в следующее меню.

Реализация: Выбрать соответствующее значение из вариантов.

Проверка: Слежение за поведением ИИ.

Функция 3.

Имя: Расстановка кораблей вручную.

Описание: Перед началом игры необходимо расставить корабли.

Реализация: Выбирается корабль и размещается в свободное место с учётом ограничений расстановки кораблей. После размещения происходит проверка на корректность выбора места расстановки (расстояние между кораблями не может быть меньше 1 клетки, корабль должен полностью находиться в пределах поля). Таким образом генерируется поле. Это поле хранится в виде массива. Когда все корабли будут размещены, станет активна кнопка начала игры.

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

Функция 4.

Имя: Автоматическая расстановка кораблей.

Описание: Перед началом игры необходимо расставить корабли. Можно выбрать автоматическую расстановку, нажав на соответствующую кнопку.

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

Проверка: Все корабли должны быть расставлены корректно. Возможность начала игры после расстановки всех кораблей.

Функция 5.

Имя: Выстрел.

Описание: Необходимо после каждого хода проверять было ли попадание.

Реализация: Поля организовываются следующим образом: двумерный массив со значениями 0 (пустая клетка), 1 (находится корабль), 2 (промах) и 3 (было попадание). После каждого выстрела происходит проверка на попадание (в указанной клетке стоит значение “1”). Если это так, то значение меняется на “3” и даётся ещё один ход стрелявшему. Если попадания не было (выстрел по клетке “0”), передать ход противнику и изменить значение на “2”. Если по выбранной клетке уже был выстрел (значения “2” или “3”), необходимо соответственно предупредить об этом. После каждого выстрела массив обновляется и обновляется визуальное поле.

Проверка: Все выстрелы отмечаются корректно.

Функция 6.

Имя: Искусственный интеллект.

Описание: Реализация искусственного интеллекта с учётом уровня сложности.

Реализация: При вызове этой функции передаётся массив с полем игрока. При обработке значение “1” определяется наравне с “0”, кроме сложного уровня сложности при определённых условиях.

В зависимости от уровня сложности определяется поведение ИИ.

Лёгкий уровень: ИИ стреляет абсолютно случайно после каждого хода.

Средний уровень: ИИ стреляет случайно до попадания. После, если корабль не уничтожен, стреляет по ближайшим клеткам с учётом того, чтобы попадание было наиболее вероятно.

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

Проверка: ИИ должен себя вести себя корректно.

Функция 7.

Имя: Конец игры.

Описание: Окончание игры после уничтожения всех кораблей.

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

Проверка: После уничтожение всех кораблей правильно выводится сообщение.

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

Описание входных и выходных данных представлено в таблице 1.

Таблица 1

Функция

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

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

Начало игры

-

Уровень сложности

Значение уровня сложности

Вывод следующего меню

Расстановка кораблей вручную

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

Сгенерированное поле (массив)

Автоматическая расстановка кораблей

-

Сгенерированное поле (массив)

Выстрел

Поле, позиция на поле

Поле

Искусственный интеллект

Поле

Поле

Конец игры

Оставшиеся корабли, уничтоженные корабли

Кораблей не осталось: победа Иначе: false


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

Требования к надёжности не предъявляются.

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

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

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

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

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

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

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

Требования к аппаратному обеспечению:

.        Оперативная память: от 256МБ.

2.      Процессор: 1 ГГц и выше.

.        Места на жёстком диске: 300 МБ для 32-х разрядной системы и 620 МБ для 64-х разрядной.

Требования к программному обеспечению:

.        Операционная система WindowsXP/Vista/7/8.

.        Программная платформа .NET Framework версии 3.5 и выше.

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

Программныйкомплекс: MicrosoftVisualStudio 2010 (C#).

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

Не определены.

Приложение3 - Исходный код


Файл Form1.cs

using System;System.Collections.Generic;System.ComponentModel;System.Data;System.Drawing;System.Linq;System.Text;System.Windows.Forms;WMPLib;System.Diagnostics;System.IO;SeaBattle

{partial class SeaBattle : Form

{SeaBattle()

{();

}.WindowsMediaPlayer audio = new WMPLib.WindowsMediaPlayer();[,] field_player = new int[11, 11];[,] field_enemy = new int[11, 11];ship_count_p = 0;ship_count_e = 0;[] ships = new Ship[10];[] ships_e = new Ship[10];ArtInt = new AI();dir = 1;

int cur_stat = 0; //размер выбранного корабля

PictureBox[,] pictureBox = new PictureBox[11, 11];count4 = 1;count3 = 2;count2 = 3;count1 = 4;difficult; //1 - easy, 2 - normal, 3 - hardFrmStat = new FormStatistic(); //Формаправилvoid Wait(int value)

{sw = new Stopwatch();.Start();(sw.ElapsedMilliseconds < value).DoEvents();

} //функцияожиданияint[] get_coord(PictureBox pic)

{n_1, n_2;[] ret = new int[2];dot_name = pic.Name.Remove(0, 4); //обрезкавименичасти p_x_(dot_name.Length == 3) //еслидлина = 3

if (dot_name[1] == '0') //определение клетки (первый номер 10)

{_1 = Convert.ToInt32(dot_name.Remove(2, 1));_2 = Convert.ToInt32(dot_name.Remove(0, 2));

}//определение клетки (второй номер 10)

{_1 = Convert.ToInt32(dot_name.Remove(1, 2));_2 = Convert.ToInt32(dot_name.Remove(0, 1));

}if (dot_name.Length == 2) //определение клетки (две цифры)

{_1 = Convert.ToInt32(dot_name.Remove(1, 1));_2 = Convert.ToInt32(dot_name.Remove(0, 1));

}//определение клетки (10 10)

{_1 = 10;_2 = 10;

}[0] = n_1;[1] = n_2;ret;

} //функция определения координат клетки по PictureBox

public void draw_field(string side)

{i, j;[,] field = new int[11, 11];(side == "p_a_")= field_player;if (side == "p_b_")= field_enemy;(i = 1; i < 11; i++)(j = 1; j < 11; j++)(field[i, j])

{0: (Controls[side + i + j] as PictureBox).Image = Properties.Resources.dot2; break;1:

{(side == "p_b_")

(Controls[side + i + j] as PictureBox).Image = Properties.Resources.dot2;

(Controls[side + i + j] as PictureBox).Image = Properties.Resources.dot_ship_set;;

}2: (Controls[side + i + j] as PictureBox).Image = Properties.Resources.dot_miss; break;3: (Controls[side + i + j] as PictureBox).Image = Properties.Resources.hit; break;4: (Controls[side + i + j] as PictureBox).Image = Properties.Resources.dot_ship_destroyed; break;5: (Controls[side + i + j] as PictureBox).Image = Properties.Resources.dot_ship_contur; break;6: (Controls[side + i + j] as PictureBox).Image = Properties.Resources.dot2; break;7:8:9: (Controls[side + i + j] as PictureBox).Image = Properties.Resources.dot_ship_set_err; break;

}

} //перерисовкаполяint ai_hit(int n1, int n2, Ship shp)

{pic = Controls["p_a_" + n1 + n2] as PictureBox;(int i = 0; i < shp.get_n(); i++)

{(pic.Name == "p_a_" + shp.sq[i].x.ToString() + shp.sq[i].y.ToString())

{.sq[i].stat = 0;_player[shp.sq[i].x, shp.sq[i].y] = 3;.Tag = "3";_player = shp.ship_check(field_player);1;

}

}0;

} //обработкапопаданияИИvoid turn()

{i;[] crd = new int[1]; //массив, содержащий 2 координаты выбранной ИИ клетки

glow_enemy.Image = Properties.Resources.glow_gray;_player.Image = Properties.Resources.glow_blue;.set_turn(true);(ArtInt.get_turn()) //покаходитИИ

{(difficult) //получение координат выбранной ИИ клетки

{1: crd = ArtInt.select_dot_1(field_player); //лёгкийуровень;2: crd = ArtInt.select_dot_2_3(field_player,2); //среднийуровень;3: crd = ArtInt.select_dot_2_3(field_player, 3); //среднийуровень;

}(field_player[crd[0], crd[1]] == 1) //еслиИИпопал

{(i = 0; ai_hit(crd[0], crd[1], ships[i]) == 0; i++) ; //цикл по всем кораблям, пока не будет найден тот, в который было попадание

if (ships[i].destr == 1) //еслиИИуничтожилкорабль

{.set_turn(true);.hit = false;.destr_in_proc = 0;.dir = 0;

}if (ships[i].destr == 0) //еслиИИнеуничтожилкорабль

{.set_turn(true);.hit=true;(ArtInt.destr_in_proc == 0)

{.destr_in_proc = 1;.set_last(crd[0], crd[1]);

}

}

}//еслиИИпромахнулся

{_player[crd[0], crd[1]] = 2; //отметкаклеткикакпромах.set_turn(false); //передачаходаигроку

}

draw_field("p_a_"); //перерисовка поля игрока(500); //приостановка_win(); //проверка на победу

glow_enemy.Image = Properties.Resources.glow_blue;_player.Image = Properties.Resources.glow_gray;

}

}void auto_set(string side)

{i, count_4_e = 1, count_3_e = 2, count_2_e = 3, count_1_e = 4, number1, number2, num_dir;[,] field = new int[11, 11];(side == "p_a_")= field_player;if (side == "p_b_")= field_enemy;rnd = new Random();= rnd.Next(1, 11); //x= rnd.Next(1, 11); //y_dir = rnd.Next(1, 3); //ось= num_dir;

cur_stat = 4;(i = 1; i < 11; i++) //установка кораблей противника

{(ship_set_check(field, number1, number2, side) != 1) //пока выбранное место для установки корабля некорректно

{= rnd.Next(1, 11);= rnd.Next(1, 11);_dir = rnd.Next(1, 3);= num_dir;

}_ship(field, Controls[side + number1 + number2] as PictureBox, 3, side);(cur_stat)

{4: { count_4_e--; cur_stat = 3; break; }3:

{_3_e--;(count_3_e == 0)_stat = 2;;

}2:

{_2_e--;(count_2_e == 0)_stat = 1;;

}1:

{_1_e--;(count_1_e == 0)_stat = 0;;

}

}

}

}int ship_set_check(int[,] field, int n_1, int n_2, string side) //функцияпроверкикорректностирасстановкикорабля

{ //dir: 1 - horiz, 2 - vertvert = 0, horiz = 0;(int i = 0; i < cur_stat; i++)

{ //цикл по размеру корабля(dir == 1) horiz = i; //сдвиг по горизонтали

else if (dir == 2) vert = i; //сдвигповертикали

if ((n_2 + horiz) < 11 && (n_1 + vert) < 11) //если клетка не выходит за пределы поля

{(field[n_1 + vert, n_2 + horiz] == 1 || field[n_1 + vert, n_2 + horiz] == 6 || field[n_1 + vert, n_2 + horiz] == 9) //в выбранной клетке стоит корабль (1) или рядом с ним (6)0; //проверка не прошла (корабль)

}return 2; //проверка не прошла (границы)

}1; //возврат результата проверки

}void move_ship(int[,] field, PictureBox pic, int act, string side) //визуальное перемещение корабля

{

//act 1 - отображение наведения 2 - снять наведение 3 - клик

string dot_name = pic.Name.Remove(0, 4); //обрезкавименичасти p_x_i, n_1, n_2, vert = 0, horiz = 0;_1 = get_coord(pic)[0];_2 = get_coord(pic)[1];shp_all = ship_set_check(field, n_1, n_2, side);

// if (act == 3 && shp_all == 1) ships[ship_count] = new Ship(4,10);

for (i = 0; i < cur_stat; i++) //визуальное отображение корабля вместо курсора

{(dir == 1) horiz = i;if (dir == 2) vert = i;(n_1 + vert < 11 && n_2 + horiz < 11) if (field[n_1 + vert, n_2 + horiz] != 1)(act == 1)

{(shp_all == 1 && field[n_1 + vert, n_2 + horiz] != 1 && field[n_1 + vert, n_2 + horiz] != 6) //если проверка на корректность установки прошла

field[n_1 + vert, n_2 + horiz] = 5;if (shp_all == 0) //если не прошла (корабль)

if (field[n_1 + vert, n_2 + horiz] == 6) //клеткаоколокорабля[n_1 + vert, n_2 + horiz] = 9;field[n_1 + vert, n_2 + horiz] = 7;

else //если не прошла (границы)

field[n_1 + vert, n_2 + horiz] = 8;

// (Controls[side + (n_1 + vert) + (n_2 + horiz)] as PictureBox).Tag = "5"; хззачемэтотутбыло

}if (act == 2)

{(field[n_1 + vert, n_2 + horiz])

{5:8: field[n_1 + vert, n_2 + horiz] = 0; break;7: field[n_1 + vert, n_2 + horiz] = 0; break;9: field[n_1 + vert, n_2 + horiz] = 6; break;

}

}if (act == 3)

{(field[n_1 + vert, n_2 + horiz])

{5:8: field[n_1 + vert, n_2 + horiz] = 0; break;7: field[n_1 + vert, n_2 + horiz] = 0; break;9: field[n_1 + vert, n_2 + horiz] = 6; break;

}(shp_all == 1) //если проверка на корректность установки прошла

{(i == 0)

{(cur_stat)

{4: { count4--; lbl1.Text = "x" + count4.ToString(); break; }3: { count3--; lbl2.Text = "x" + count3.ToString(); break; }2: { count2--; lbl3.Text = "x" + count2.ToString(); break; }1: { count1--; lbl4.Text = "x" + count1.ToString(); break; }

}(count1 == 0 && count2 == 0 && count3 == 0 && count4 == 0)_Battle.Visible = true;(side == "p_a_")

{[ship_count_p] = new Ship(cur_stat);_count_p++;

}if (side == "p_b_")

{_e[ship_count_e] = new Ship(cur_stat);_count_e++;

}

}[n_1 + vert, n_2 + horiz] = 1;(side == "p_a_")

{[ship_count_p - 1].sq[i].x = n_1 + vert;[ship_count_p - 1].sq[i].y = n_2 + horiz;

}(side == "p_b_")

{_e[ship_count_e - 1].sq[i].x = n_1 + vert;_e[ship_count_e - 1].sq[i].y = n_2 + horiz;

}

(Controls[side + (n_1 + vert) + (n_2 + horiz)] as PictureBox).Tag = "1";((n_1 + 1 + vert) < 11)(field[n_1 + 1 + vert, n_2 + horiz] == 0)[n_1 + 1 + vert, n_2 + horiz] = 6; //низ((n_2 + 1 + horiz) < 11)(field[n_1 + vert, n_2 + 1 + horiz] == 0)[n_1 + vert, n_2 + 1 + horiz] = 6; //право((n_1 - 1 + vert) > 0)(field[n_1 - 1 + vert, n_2 + horiz] == 0)[n_1 - 1 + vert, n_2 + horiz] = 6; //верх((n_2 - 1 + horiz) > 0)(field[n_1 + vert, n_2 - 1 + horiz] == 0)[n_1 + vert, n_2 - 1 + horiz] = 6; //лево((n_2 - 1 + horiz) > 0 && (n_1 - 1 + vert) > 0)(field[n_1 - 1 + vert, n_2 - 1 + horiz] == 0)[n_1 - 1 + vert, n_2 - 1 + horiz] = 6; //лево-верх((n_2 - 1 + horiz) > 0 && (n_1 + 1 + vert) < 11)(field[n_1 + 1 + vert, n_2 - 1 + horiz] == 0)[n_1 + 1 + vert, n_2 - 1 + horiz] = 6; //лево-низ((n_2 + 1 + horiz) < 11 && (n_1 - 1 + vert) > 0)(field[n_1 - 1 + vert, n_2 + 1 + horiz] == 0)[n_1 - 1 + vert, n_2 + 1 + horiz] = 6; //право-верх((n_2 + 1 + horiz) < 11 && (n_1 + 1 + vert) < 11)(field[n_1 + 1 + vert, n_2 + 1 + horiz] == 0)[n_1 + 1 + vert, n_2 + 1 + horiz] = 6; //право-низ

}

}

}

// if (act == 3 && shp_all == 1) { cur_stat = 0; ship_count++; };

}void generate_field(int x, int y, string side)

{i, j, min_dist = 19;(i = 1; i < 11; i++)

{(j = 1; j < 11; j++)

{[i, j] = new PictureBox();[i, j].Name = side + j + i;[i, j].Image = Properties.Resources.dot2;[i, j].Location = new Point(min_dist * (i - 1) + x, min_dist * (j - 1) + y);[i, j].Size = new Size(20, 20);

//pictureBox[i, j].Tag = String.Format("{0} {1}", j, i);[i, j].Tag = "0";[i, j].BringToFront();[i, j].Click += new EventHandler(click);[i, j].MouseEnter += new EventHandler(mas_MouseMove);[i, j].MouseLeave += new EventHandler(mas_MouseLeave);.Controls.Add(pictureBox[i, j]);_player.SendToBack();_enemy.SendToBack();

}

}

} //генерацияполяvoid check_dot(PictureBox pic, Ship shp) //проверкаклетки

{dot_name = pic.Name.Remove(0, 4); //обрезкавименичасти p_x_side = pic.Name.Remove(4, pic.Name.Length - 4);[,] field = new int[11, 11];n_1, n_2;(side == "p_a_")= field_player;if (side == "p_b_")= field_enemy;_1 = get_coord(pic)[0];_2 = get_coord(pic)[1];(int i = 0; i < shp.get_n(); i++)

{(pic.Name == side + shp.sq[i].x.ToString() + shp.sq[i].y.ToString())

{.sq[i].stat = 0;[shp.sq[i].x, shp.sq[i].y] = 3;.Tag = "3";_enemy = shp.ship_check(field_enemy);_field("p_b_");_win();;

}(pic.Tag.ToString() == "0")

{.Tag = 2;[n_1, n_2] = 2;_field("p_b_");();

}

}

}void statistic_edit(int side, int diff) //side 1 - игрок, 2 - ИИ

{[] stat = new int[6];sr = new StreamReader("stat");(int i = 0; i < 6; i++)[i] = Convert.ToInt32(sr.ReadLine());.Close();(diff)

{1:(side == 1)[0]++;[1]++;;2:(side == 1)[2]++;[3]++;;3:(side == 1)[4]++;[5]++;;

}sw = new StreamWriter("stat");(int i = 0; i < 6; i++).WriteLine(stat[i]);.Close();

}_win() //проверканапобеду

{victory=1;(int i = 0; i < ship_count_e; i++)(ships_e[i].destr == 0)= 0;(victory == 1)

{_edit(1, difficult);result = MessageBox.Show("Вывыиграли! Хотитесыгратьещёраз?", "Победа!", MessageBoxButtons.YesNo);(result == System.Windows.Forms.DialogResult.Yes)

{.Restart();.Exit(0);

}.Exit(0);

}= 1;(int i = 0; i < ship_count_p; i++)(ships[i].destr == 0)= 0;(victory == 1)

{_edit(0, difficult);result = MessageBox.Show("Выпроиграли. Хотитесыгратьещёраз?", "Поражение", MessageBoxButtons.YesNo);(result == System.Windows.Forms.DialogResult.Yes)

{.Restart();.Exit(0);

}.Exit(0);

}

}void btn_Battle_Click(object sender, EventArgs e)

{i;_Battle.Visible = false;_reset.Visible = false;_auto.Visible = false;

// pic_x.Visible = true;

// pic_dualshock.Visible = true;(i = 1; i <= 7; i++)["pic_ship" + i].Visible = false;(i = 1; i <= 4; i++)["lbl" + i].Visible = false;_field(400, 115, "p_b_");_set("p_b_");_field("p_b_");_enemy.Visible = true;_player.Visible = true;_field.Visible = true;_field.Visible = true;

}click(object sender, EventArgs e) //кликпополю

{(sender is PictureBox)

{(cur_stat != 0) //есливыбранкорабль_ship(field_player, sender as PictureBox, 3, "p_a_");

{n_1, n_2;_1 = get_coord(sender as PictureBox)[0];_2 = get_coord(sender as PictureBox)[1];(!ArtInt.get_turn())((sender as PictureBox).Name.Remove(4, (sender as PictureBox).Name.Length - 4) == "p_b_" && field_enemy[n_1,n_2]!=2)

{(int i = 0; i < ship_count_e; i++)_dot(sender as PictureBox, ships_e[i]);_field("p_b_");

}

}

}_stat = 0;_field("p_a_");

}void SeaBattle_Load(object sender, EventArgs e)

{_Battle.MouseEnter += (a_sender, a_args) =>

{pic = a_sender as PictureBox;.Image = Properties.Resources.btn_Battle_1;

};_Battle.MouseLeave += (a_sender, a_args) =>

{pic = a_sender as PictureBox;.Image = Properties.Resources.btn_Battle_pressed;

};(!System.IO.File.Exists("stat"))

{sw = File.CreateText("stat");(int i = 0; i < 6; i++).WriteLine("0");.Close();

}_ship7.MouseDown += new MouseEventHandler(MouseDown_ship);_ship6.MouseDown += new MouseEventHandler(MouseDown_ship);_ship5.MouseDown += new MouseEventHandler(MouseDown_ship);_ship4.MouseDown += new MouseEventHandler(MouseDown_ship);_ship3.MouseDown += new MouseEventHandler(MouseDown_ship);_ship2.MouseDown += new MouseEventHandler(MouseDown_ship);_ship1.MouseDown += new MouseEventHandler(MouseDown_ship);_reset.MouseEnter += new EventHandler(mouse_e);_reset.MouseLeave += new EventHandler(mouse_l);_auto.MouseEnter += new EventHandler(mouse_e);_auto.MouseLeave += new EventHandler(mouse_l);_easy.MouseEnter += new EventHandler(mouse_enter_diff);_easy.MouseLeave += new EventHandler(mouse_leave_diff);_easy.Click += new EventHandler(mouse_click_diff);_normal.MouseEnter += new EventHandler(mouse_enter_diff);_normal.MouseLeave += new EventHandler(mouse_leave_diff);_normal.Click += new EventHandler(mouse_click_diff);_hard.MouseEnter += new EventHandler(mouse_enter_diff);_hard.MouseLeave += new EventHandler(mouse_leave_diff);_hard.Click += new EventHandler(mouse_click_diff);_statistic.MouseEnter += new EventHandler(mouse_enter_stat);_statistic.MouseLeave += new EventHandler(mouse_leave_stat);_statistic.Click += new EventHandler(mouse_click_stat);

}void mas_MouseMove(object sender, EventArgs e) //наведениенаклетку

{n_1, n_2;name = (sender as PictureBox).Name.Remove(4, (sender as PictureBox).Name.Length - 4);_1 = get_coord(sender as PictureBox)[0];_2 = get_coord(sender as PictureBox)[1];((sender as PictureBox).Tag.ToString() == "0" || (name == "p_b_") && (sender as PictureBox).Tag.ToString() == "1")

{(cur_stat != 0)

{_ship(field_player, sender as PictureBox, 1, "p_a_");_field("p_a_");

}try

{((name == "p_a_" && field_player[n_1, n_2] != 2) || (name == "p_b_" && field_enemy[n_1, n_2] != 2))

(sender as PictureBox).Image = Properties.Resources.dot_target;

}{ };

}

}void mas_MouseLeave(object sender, EventArgs e)

{n_1, n_2;name = (sender as PictureBox).Name.Remove(4, (sender as PictureBox).Name.Length - 4);_1 = get_coord(sender as PictureBox)[0];_2 = get_coord(sender as PictureBox)[1];_ship(field_player, sender as PictureBox, 2, "p_a_");((sender as PictureBox).Tag.ToString() == "0" || (name == "p_b_") && (sender as PictureBox).Tag.ToString() == "1")((name == "p_a_" && field_player[n_1, n_2] != 2) || (name == "p_b_" && field_enemy[n_1, n_2] != 2))

(sender as PictureBox).Image = Properties.Resources.dot2;

} //выходизклеткиvoid MouseDown_ship(object sender, EventArgs e) //кликпоиконкамкораблей

{((sender as PictureBox).Name.ToString())

{"pic_ship1": if (count1 > 0) { cur_stat = 1; dir = 1; } break;"pic_ship2": if (count2 > 0) { cur_stat = 2; dir = 1; } break;"pic_ship3": if (count3 > 0) { cur_stat = 3; dir = 1; } break;"pic_ship4": if (count4 > 0) { cur_stat = 4; dir = 1; } break;"pic_ship5": if (count4 > 0) { cur_stat = 4; dir = 2; } break;"pic_ship6": if (count3 > 0) { cur_stat = 3; dir = 2; } break;"pic_ship7": if (count2 > 0) { cur_stat = 2; dir = 2; } break;: break;

}

}void mouse_e(object sender, EventArgs e)

{((sender as PictureBox).Name.ToString())

{"pic_reset": (sender as PictureBox).Image = Properties.Resources.btn_Reset2; break;"pic_auto": (sender as PictureBox).Image = Properties.Resources.btn_auto2; break;

}

}void mouse_l(object sender, EventArgs e)

{((sender as PictureBox).Name.ToString())

{"pic_reset": (sender as PictureBox).Image = Properties.Resources.btn_Reset; break;"pic_auto": (sender as PictureBox).Image = Properties.Resources.btn_auto; break;

}

}void pic_reset_Click(object sender, EventArgs e)

{i, j;.Text = "x1";.Text = "x2";.Text = "x3";.Text = "x4";(i = 1; i < 11; i++)(j = 1; j < 11; j++)

{

(Controls["p_a_" + i + j] as PictureBox).Tag = 0;_player[i, j] = 0;

}= 1;= 2;= 3;= 4;_count_p = 0;_field("p_a_");_Battle.Visible = false;

}void pic_auto_Click(object sender, EventArgs e)

{_reset_Click(sender, e);(count1 != 0 || count2 != 0 || count3 != 0 || count4 != 0)

{_reset_Click(sender, e);_set("p_a_");

}_field("p_a_");

}void mouse_enter_diff(object sender, EventArgs e)

{((sender as PictureBox).Name.ToString())

{"pic_easy": (sender as PictureBox).Image = Properties.Resources.btn_easy_2; break;"pic_normal": (sender as PictureBox).Image = Properties.Resources.btn_normal_2; break;"pic_hard": (sender as PictureBox).Image = Properties.Resources.btn_hard_2; break;

}

} //наведениенакнопкууровнясложностиvoid mouse_leave_diff(object sender, EventArgs e)

{((sender as PictureBox).Name.ToString())

{"pic_easy": (sender as PictureBox).Image = Properties.Resources.btn_easy; break;"pic_normal": (sender as PictureBox).Image = Properties.Resources.btn_normal; break;"pic_hard": (sender as PictureBox).Image = Properties.Resources.btn_hard; break;

}

} //выходизкнопкиуровнясложностиvoid mouse_click_diff(object sender, EventArgs e) //нажатиенакнопкууровнясложности

{_easy.Visible = false;_normal.Visible = false;_hard.Visible = false;_reset.Visible = true;_auto.Visible = true;_chooseDiff.Visible = false;_field(30, 115, "p_a_");(int i = 1; i <= 7; i++)["pic_ship" + i].Visible = true;(int i = 1; i <= 4; i++)["lbl" + i].Visible = true;((sender as PictureBox).Name.ToString())

{"pic_easy": difficult = 1; break;"pic_normal": difficult = 2; break;"pic_hard": difficult = 3; break;

}

}void mouse_enter_stat(object sender, EventArgs e)

{

(sender as PictureBox).Image = Properties.Resources.btn_statistic2;

}void mouse_leave_stat(object sender, EventArgs e)

{

(sender as PictureBox).Image = Properties.Resources.btn_statistic;

}void mouse_click_stat(object sender, EventArgs e)

{.ShowDialog();

}

}

}.csSystem;System.Collections.Generic;System.Linq;System.Text;SeaBattle

{class AI

{int last_x;int last_y;int dir; //0 - none, 1 - horiz, 2 - vert

public int destr_in_proc; //идёт уничтожение корабля (для установки координат первого попадания)

public bool hit = false; //идётуничтожениекорабляturn = false; //ходИИint miss_count=0; //счётчикпромаховдлясложногоуровняAI()

{_x = 0;_y = 0;= 0;_in_proc = 0;= false;

}void set_turn(bool n)

{= n;

}void set_last(int x, int y)

{_x = x;_y = y;

}bool get_turn()

{turn;

}int[] select_dot_1(int[,] field)

{[] coord = new int[2];x1, y1;rnd = new Random();= true;

{= rnd.Next(1, 11); //x= rnd.Next(1, 11); //y

} while ((field[x1, y1] == 2 || field[x1, y1] == 3 || field[x1, y1] == 4));[0] = x1;[1] = y1;coord;

}int[] select_dot_2_3(int[,] field, int diff)

{[] coord = new int[2];x1, y1;rnd = new Random();= true;(hit == false)

{(diff == 2)

{

{= rnd.Next(1, 11); //x= rnd.Next(1, 11); //y

} while ((field[x1, y1] == 2 || field[x1, y1] == 3 || field[x1, y1] == 4));[0] = x1;[1] = y1;coord;

}

{(miss_count < 2)

{

{= rnd.Next(1, 11); //x= rnd.Next(1, 11); //y

} while ((field[x1, y1] == 2 || field[x1, y1] == 3 || field[x1, y1] == 4));_count++;

}

{

{= rnd.Next(1, 11); //x= rnd.Next(1, 11); //y

} while (field[x1, y1] != 1);_count = 0;

}[0] = x1;[1] = y1;coord;

}

}

{(dir)

{0:

{

{= rnd.Next(-1, 2);(x1 == 0)

{= rnd.Next(-1, 2);((last_x + x1 < 11) && (last_y + y1 < 11) && field[last_x + x1, last_y + y1] == 1)= 2;

}

{= 0;((last_x + x1<11) && (last_y + y1<11) && field[last_x + x1, last_y + y1] == 1)= 1;

}[0] = last_x + x1;[1] = last_y + y1;

} while (coord[0] > 10 || coord[0] < 0 || coord[1] > 10 || coord[1] < 0 || field[coord[0], coord[1]] == 2 || field[coord[0], coord[1]] == 3 || field[coord[0], coord[1]] == 4);

break;

}1:

{ //корабль установлен вертикально

{i=1;(!((last_x + i < 11 && field[last_x + i, last_y] == 1) || (last_x - i > 0 && field[last_x - i, last_y] == 1)))++;

{(rnd.Next(0, 2) == 1)= i;x1 = -i;

} while ((last_x + x1) < 0 || (last_x + x1) > 10 || field[last_x + x1, last_y] != 1);[0] = last_x + x1;[1] = last_y;

} while (coord[0] > 10 || coord[0] < 0 || field[coord[0], coord[1]] == 2 || field[coord[0], coord[1]] == 3 || field[coord[0], coord[1]] == 4);

break;

}2:

{ //корабль установлен горизонтально

{i = 1;(!((last_y + i < 11 && field[last_x, last_y + i] == 1) || (last_y - i > 0 && field[last_x, last_y - i] == 1)))++;

{(rnd.Next(0, 2) == 1)= i;y1 = -i;

} while ((last_y + y1) < 0 || (last_y + y1) > 10 || field[last_x, last_y + y1] != 1);[0] = last_x;[1] = last_y + y1;

} while (coord[1] > 10 || coord[1] < 0 || field[coord[0], coord[1]] == 2 || field[coord[0], coord[1]] == 3 || field[coord[0], coord[1]] == 4);;

}

}coord;

}

}

}

}.csSystem;System.Collections.Generic;System.Linq;System.Text;SeaBattle

{class Ship

{struct squares_stat

{int x;int y;int stat;

}squares_stat[] sq = new squares_stat[4];int n;int destr;Ship(int n)

{.n = n;.destr = 0;(int i = 0; i < n; i++)[i].stat = 1;

}int get_n()

{n;

}int[,] ship_check(int[,] field)

{destroyed=1;(int i = 0; i < n; i++)(sq[i].stat == 1)= 0;(destroyed == 1)

{(int i = 0; i < n; i++)

{[sq[i].x, sq[i].y] = 4;((sq[i].x + 1) < 11 && field[sq[i].x + 1, sq[i].y] == 6) //низ[sq[i].x + 1, sq[i].y] = 2;((sq[i].x - 1) > 0 && field[sq[i].x - 1, sq[i].y] == 6) //верх[sq[i].x - 1, sq[i].y] = 2;((sq[i].y + 1) < 11 && field[sq[i].x, sq[i].y + 1] == 6) //право[sq[i].x, sq[i].y + 1] = 2;((sq[i].y - 1) > 0 && field[sq[i].x, sq[i].y - 1] == 6) //лево[sq[i].x, sq[i].y - 1] = 2;((sq[i].x + 1) < 11 && (sq[i].y + 1) < 11 && field[sq[i].x + 1, sq[i].y + 1] == 6) //низ-право[sq[i].x + 1, sq[i].y + 1] = 2;((sq[i].x + 1) < 11 && (sq[i].y - 1) > 0 && field[sq[i].x + 1, sq[i].y - 1] == 6) //низ-лево[sq[i].x + 1, sq[i].y - 1] = 2;((sq[i].x - 1) > 0 && (sq[i].y + 1) < 11 && field[sq[i].x - 1, sq[i].y + 1] == 6) //верх-право[sq[i].x - 1, sq[i].y + 1] = 2;((sq[i].x - 1) > 0 && (sq[i].y - 1) > 0 && field[sq[i].x - 1, sq[i].y - 1] == 6) //верх-лево[sq[i].x - 1, sq[i].y - 1] = 2;

}= 1;

}field;

}

}

}.csSystem;System.Collections.Generic;System.ComponentModel;System.Data;System.Drawing;System.Linq;System.Text;System.Windows.Forms;System.IO;SeaBattle

{partial class FormStatistic : Form

{FormStatistic()

{();

}void FormStatistic_Load(object sender, EventArgs e)

{_diff.Text = "";_result.Text = "";

}void show_result(int button)

{[] stat = new int[6];sr = new StreamReader("stat");(int i = 0; i < 6; i++)[i] = Convert.ToInt32(sr.ReadLine());.Close();(button)

{1:

{_diff.Text = "Уровень сложности: лёгкий";

lbl_result.Text = "Победигрока: " + stat[0].ToString() + "\n";_result.Text += "ПобедИИ: " + stat[1].ToString() + "\n";

break;

}2:

lbl_result.Text = "Победигрока: " + stat[2].ToString() + "\n";_result.Text += "ПобедИИ: " + stat[3].ToString() + "\n";

break;

}3:

{_diff.Text = "Уровень сложности: высокий";

lbl_result.Text = "Победигрока: " + stat[4].ToString() + "\n";_result.Text += "ПобедИИ: " + stat[5].ToString() + "\n";;

}

}

}void btn_easy_Click(object sender, EventArgs e)

{_result(1);

}void btn_medium_Click(object sender, EventArgs e)

{_result(2);

}void btn_hard_Click(object sender, EventArgs e)

{_result(3);

}void btn_reset_Click(object sender, EventArgs e)

{sw = new StreamWriter("stat");(int i = 0; i < 6; i++).WriteLine("0");.Close();_result(1);

}void btn_exit_Click(object sender, EventArgs e)

{.Close();

}

}

}

Похожие работы на - Разработка программного продукта, реализующего классическую версию настольной игры 'Морской бой'

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!