Программа "Морской бой"

Общее описание и условия применения языка программирования Си. Основные этапы создания игры с искусственным интеллектом "Морской бой" в программе Code Blocks. Правила игры и разработка инструкции пользователя. Принцип реализации программного кода.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 18.02.2019
Размер файла 690,3 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

Программа «Морской бой»

Введение

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

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

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

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

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

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

программа игра пользователь

2. Реализация программного кода с комментариями

В программе используются библиотеки:

#include <SDL2/SDL.h>

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

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

Рисунок 1. Разделение исходного кода

Описание файлов:

mwindows.h - здесь размещены объявление структур и функций используемых в программе.

mbutton.h и mbutton.c - программная реализация кнопок на экране, структуры и функции, поддерживающие их функциональность.

main.c - реализация главной функции

init.c - инициализации SDL, ресурсов, подготовка игрового поля

load.c - загрузка текстур в программу из растровых рисунков

coursePlayer.c - проверка хода игрока, обновление поля

mainLoop.c - игровой цикл, обработка событий, вывод изображения

pageWindow.c - инициализация кнопок в окне

computer_ai.c - функции хода компьютера

Основные функции

Функция, которая реализует размещение кораблей на поле.

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

void spawnBoat(player* pl)

{

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

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

pl->field[i][j]=Wasser;

//4, 3, 2 палубные корабли

int k;

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

{

//определение длинны текущего корабля и размещение

if(i==0)

k=4;

else

if(i<3)

k=3;

else

if(i<6)

k=2;

else

k=1;

if(boatHelp(&pl->field[0],k))

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

{

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

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

pl->field[i][j]=Wasser;

i=-1;

}

}

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

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

if(pl->field[i][j]!=Boat)

pl->field[i][j]=Wasser;

}

Листинг 1. Функция расстановки всех кораблей

Функция, которая проверяет ход игрока

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

int coursePlayer(char mass[10][10],int x,int y)

//проверяет на попадание, передает ход, удаляет поля вокруг уничтоженного корабля

{

if(mass[y][x]==Wasser)

{

mass[y][x] = Not;

if(res->xod==1) //передача хода

res->xod = 2;

else

res->xod = 1;

return 0;

}

if(mass[y][x]==Boat)

{

mass[y][x] = Kill;

//проверка на полное уничтожение корабля

//если уничтожен, то вокруг нельзя ставить корабли...

int bcount =0;

int kcount =1;

char type =HORIZONT;//

int begX,begY; //начальные кординаты размещения коробля

begX = x;begY = y;

//Определение начальных координат корабля и его длинны

if(bcount>0)//корабль подбит не до конца

{

return 1;

}else

{

//корабль подбит, нужно показать вокруг него мёртвую зону

killBoat(mass,begX,begY,type,kcount);

return 2;

}

}

return 0;

}

Листинг 2. Обработка хода игрока

Функция, которая выводит размещение кораблей на экран

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

void renderField()

{

#define size_title 48

SDL_Rect size;//расположение в текстуре

SDL_Rect field;//рассположение на поле

size.h = 80;

size.w = 80;

field.h = size_title;

field.w = size_title;

field.x = 20;

field.y = 20;

player*p = &res->p1;

char ch;

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

{

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

{

ch = p->field[i][j];

if(res->lvl == lGame1vs1)

{

if(ch == Boat)

{

ch = Wasser;

}

}

size.x = ch*80; //меняеться на расположение в текстуре

size.y = 0;

SDL_RenderCopy(gRenderer,res->titleset,&size,&field);

field.x+=size_title;

}

field.x = 20;

field.y+=size_title;

}

#define offset size_title*10 + 30

p = &res->p2;

field.x = 20 + offset;

field.y = 20;

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

{

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

{

ch = p->field[i][j];

if(ch == Boat)

{

ch = Wasser;

}

size.x = ch*80; //меняеться на расположение в текстуре

size.y = 0;

SDL_RenderCopy(gRenderer,res->titleset,&size,&field);

field.x+=size_title;

}

field.x = 20 + offset;

field.y+=size_title;

}

}

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

Функция, для выбора атакуемой координаты поля компьютером

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

void courseAI()

{

SDL_Delay(100);

int r;

int x,y;

int count=0;

if(res->compSTR.isAttack)

{

attackBoat(&y,&x);

}else

{

if(res->compSTR.hp[1]) //2,3 -палубные корабли

{

r = 1+rand()%res->compSTR.hp[1];//range 1 -50

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

{

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

{

if(res->compSTR.field[i][j]==Wasser)

{

if(i%2==0&&j%2==0)

{

++count;

}else if(i%2==1&&j%2==1)

{

++count;

}

if(count==r)

{

y = i;

x = j;

i=10;

j=10;

}

}

}

}

res->compSTR.hp[1]--;

res->compSTR.hp[2]--;

}else if(res->compSTR.hp[2])//1-палубные

{

r = 1+rand()%res->compSTR.hp[2];//range 1 -100

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

{

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

{

if(res->compSTR.field[i][j]==Wasser)

{

++count;

if(count==r)

{

y = i;

x = j;

i=10;

j=10;

}

}

}

}

res->compSTR.hp[2]--;

}

}

int l = coursePlayer(res->p1.field,x,y);

//этап добивания корабля

if(l==1)

{ res->compSTR.field[y][x] = Kill;

res->compSTR.isAttack = 1;

res->compSTR.x = x;

res->compSTR.y = y;

}

if(l==2)

{

//необходимо обновить поле компьтера

//для того чтобы он не ходил по мертвым полям

res->compSTR.x = x;

res->compSTR.y = y;

res->compSTR.field[y][x] = Kill;

res->compSTR.isAttack = 0;

updateBoard();

}

if(l==0)

res->compSTR.field[y][x] = Not;

return;

}

Листинг 4. Функция хода компьютера

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

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

Рисунок 2. Меню выбора

После выбора режима игры с компьютером игрок видит два поля. Левое поле - это поле с кораблями игрока. Правое поле - поле с кораблями противника.

Рисунок 3.Начало игры

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

Рисунок 4. Стрельба по полю

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

Рисунок 5. Обновление клеток вокруг сбитого корабля

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

Рисунок 6. Окончание игры

Рисунок 7. Конец игры

Заключение

программа игра пользователь

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

Библиографический список

1. Керниган Б. Язык программирования Си 2-е издание / Б. Керниган Д. Ричи М.: Издательский дом "Вильямс", 2012. 272 с.

2. Статья о алгоритмах в морском бое [Электронный ресурс]: https://habrahabr.ru/post/180995/

3. Статьи про графическую библиотеку SDL [Электронный ресурс]:http://lazyfoo.net/tutorials/SDL/index.php

Приложение

Код программы

Файл main.c

#include "mwindow.h"

#include <SDL2/SDL.h>

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

int main(int argc, char* args[])

{

srand(time(NULL));

init();

loadMedia();

eventLoop();

close();

return 0;

}

Файл mwindows.h

#ifndef MWINDOW_H_INCLUDED

#define MWINDOW_H_INCLUDED

#include <stdio.h>

#include <SDL2/SDL.h>

#define WINDOW_COUNT 3

#define HORIZONT 0

#define VERTICAL 1

enum buttonName{bStart1vs1,bStart1vsComp,bExit};

enum levelMenu{lMenu,lGame1vs1,lGame1vsComp,lWin,lFail};

enum type_title{Wasser,Boat,Not,Kill,Anim};

typedef struct __Player_Field

{

char field[10][10];

int countBoats;//пока не 0 -> еще есть корабли

} player;

typedef struct __Copm_Strategy

{

/*

комп знает текущее кол-во различных типов

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

от этого выстраивает стратегию

*/

char field[10][10]; //проверка на битые корабли

char hp[3];

char isAttack; //подбит ли корабль

char x,y; //местоположение последнего верного удара

}CompSTR;

typedef struct __Resurse

{

int quit;

int winHeight;

Листинг А.1, лист 1

int winWidth;

enum levelMenu lvl;

int xod; //1 -1,_player 2 - 2_player

//Pags

//Menu

SDL_Texture *menu;//backround

SDL_Rect btnSize[3]; //размеры кнопок в текстуре

SDL_Rect btnField[3];//расположнение в окне

SDL_Texture *button;

//Field

SDL_Texture *field;

SDL_Texture *titleset;

SDL_Rect btnExitSize; //размеры кнопок в текстуре

SDL_Rect btnExitField;//расположнение в окне

//Win

SDL_Texture* win;

SDL_Texture* players;

//Fail

SDL_Texture* fail;

//player struct

player p1,p2;

CompSTR compSTR;

}Resurse;

void firstInit();

void init();

void initResurse();

void initPageMenu();

void initPageG1vs1();

void loadMedia();

void close();

void eventLoop();

void mouseEvent();

void render();

SDL_Texture* loadTexture(char* path);

void preGame();//подготовка к игре

void spawnBoat(player* pl); //размещение всех кораблей

int boatHelp(char mass[10][10],int n); //размещение одного корабля

void initAI(); //инициализация структуры аи

void courseAI(); //ход компьтера

int coursePlayer(char mass[10][10],int x,int y); //обработка хода

void killBoat(char mass[10][10],int f,int z,int or,int n);

//создание мертвой зоны вокруг корабля

void initPageMenu(void);

void initPageG1vs1(void);

#endif // MWINDOW_H_INCLUDED

Листинг А.1, лист 2

Файл mainLoop.c

#include "mwindow.h"

#include "mbutton.h"

static SDL_Rect rec1 = {0,0,100,20};

static SDL_Rect rec2 = {250,450,440,80};

extern SDL_Renderer *gRenderer;

extern Resurse *res;

extern SDL_Window *mwin;

extern stackWidget *stWidget[WINDOW_COUNT];

static SDL_Event event;

void WinFailEvent()//прогрыш анимации

{

//анимация окончания игры

if(res->lvl==lGame1vsComp||res->lvl==lGame1vs1)

if(res->p1.countBoats==0||res->p2.countBoats==0)

{

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

{

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

{

if(res->p1.countBoats==0)

{

res->p1.field[i][j] = Anim;

res->p1.field[i][j] = Anim;

}else

{

res->p2.field[i][j] = Anim;

res->p2.field[i][j] = Anim;

}

render();

SDL_Delay(50);

}

}

}

if(res->lvl==lGame1vs1)

{

if(res->p1.countBoats==0||res->p2.countBoats==0)

{

res->lvl = lWin;

}

}

if(res->lvl==lGame1vsComp)

{

if(res->p1.countBoats==0)

{

res->lvl = lFail;

}

if(res->p2.countBoats==0)

{

res->lvl = lWin;

}

}

if(res->lvl==lWin||res->lvl==lFail)

{

Листинг А.1, лист 2

render();

SDL_Delay(500);

while(SDL_PollEvent(&event)!= 0);

SDL_Delay(500);

}

}

void eventLoop()

{

while(!res->quit)

{

while(SDL_PollEvent(&event)!= 0)

{

switch (event.type)

{

case SDL_QUIT:

res->quit = 1;

break;

case SDL_KEYDOWN:

if(event.key.keysym.sym ==SDLK_ESCAPE)

if(res->lvl!=lMenu)

res->lvl=lMenu;

break;

case SDL_MOUSEBUTTONDOWN:

mouseEvent();

break;

default:

;

}

}

if(res->lvl==lGame1vsComp)

if(res->xod==2)

courseAI();

render();

if(res->lvl==lGame1vsComp||res->lvl==lGame1vs1)

WinFailEvent();

}

}

void mouseEvent()

{

if(res->lvl == lWin||res->lvl == lFail)

{

SDL_Delay(300);

res->lvl = lMenu;

}else

{

clickMouse(stWidget[res->lvl],event.button.x,event.button.y);

}

}

void renderField()

{

#define size_title 48

SDL_Rect size;//расположение в текстуре

SDL_Rect field;//рассположение на поле

size.h = 80;

size.w = 80;

field.h = size_title;

field.w = size_title;

Листинг А.1, лист 3

field.x = 20;

field.y = 20;

player*p = &res->p1;

char ch;

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

{

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

{

ch = p->field[i][j];

if(res->lvl == lGame1vs1)

{

if(ch == Boat)

{

ch = Wasser;

}

}

size.x = ch*80; //меняеться на расположение в текстуре

size.y = 0;

SDL_RenderCopy(gRenderer,res->titleset,&size,&field);

field.x+=size_title;

}

field.x = 20;

field.y+=size_title;

}

#define offset size_title*10 + 30

p = &res->p2; //можно было выделить в отдельную функцию, но копипаст проще

field.x = 20 + offset;

field.y = 20;

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

{

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

{

ch = p->field[i][j];

if(ch == Boat)

{

ch = Wasser;

}

size.x = ch*80; //меняеться на расположение в текстуре

size.y = 0;

SDL_RenderCopy(gRenderer,res->titleset,&size,&field);

field.x+=size_title;

}

field.x = 20 + offset;

field.y+=size_title;

}

}

void render()

{

SDL_RenderClear(gRenderer);

switch(res->lvl)

{

case lMenu:

SDL_RenderCopy(gRenderer, res->menu, NULL, NULL);//backround

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

Листинг А.1, лист 4

SDL_RenderCopy(gRenderer,res->button,&res->btnSize[i],&res->btnField[i]);//button

break;

case lGame1vs1: //поле для игры одно и то же

case lGame1vsComp:

SDL_RenderCopy(gRenderer, res->field, NULL, NULL);//backround

SDL_RenderCopy(gRenderer,res->button,&res->btnExitSize,&res->btnExitField);

renderField();

break;

case lWin:

if(res->p2.countBoats==0)

{

rec1.y=20;

}

SDL_RenderCopy(gRenderer, res->win, NULL, NULL);//backround

if(res->lvl==lGame1vs1)

SDL_RenderCopy(gRenderer, res->players, &rec1, &rec2);

break;

case lFail:

SDL_RenderCopy(gRenderer, res->fail, NULL, NULL);//backround

break;

default:

;

}

Листинг А.1, лист 5

Размещено на Allbest.ru


Подобные документы

  • Проектирование игры "Морской бой" путем составления диаграмм UML, IDEF0, DFD, моделирующих требования к программе. Разработка программы с использованием языка C# и фреймворка.NETFramework 3.5. Тестирование белого ящика и альфа-тестирование продукта.

    курсовая работа [3,9 M], добавлен 24.10.2013

  • Приемы практического использования объектно-ориентированного подхода в создании законченного программного продукта. Разработка кроссплатформенной компьютерной игры "Морской бой". Принципы "хорошего стиля программирования C++/Qt". Описание классов игры.

    курсовая работа [2,7 M], добавлен 12.08.2014

  • Разработка функционирующей базы данных для игры с искусственным интеллектом. Составление таблицы лидеров игры. Исследование концептуального и логического проектирования. Сущность и основные типы SQL-запросов. Анализ процедур, триггеров и транзакций.

    курсовая работа [1,3 M], добавлен 01.11.2022

  • Описание алгоритма хода ЭВМ в режиме "пользователь-компьютер" в игре "Морской бой". Описание совокупности классов, их полей и методов. Разработка интерфейса и руководства пользователя по проведению игры. Листинг программы, написанной на языке Java.

    курсовая работа [645,0 K], добавлен 26.03.2014

  • Описание правил игры "Морской бой". Особенности современных компьютеров и искусственного интеллекта. Создание общей блок-схемы программы, ее внешний вид. Необходимые переменные, процедуры и функции. Характеристика объектов, используемых в приложении.

    курсовая работа [950,1 K], добавлен 05.11.2012

  • Особенности программирования аркадных игр в среде Python. Краткая характеристика языка программирования Python, его особенности и синтаксис. Описание компьютерной игры "Танчики" - правила игры, пояснение ключевых строк кода. Демонстрация работы программы.

    курсовая работа [160,3 K], добавлен 03.12.2014

  • Приемы программирования в Delphi. Алгоритм поиска альфа-бета отсечения, преимущества. Описание программного средства. Разработка программы, реализующая алгоритм игры "реверси". Руководство пользователя. Листинг программы. Навыки реализации алгоритмов.

    курсовая работа [357,1 K], добавлен 28.02.2011

  • Изучение объектно-ориентированного языка программирования Java, его функциональные возможности. Создание программного кода. Описание классов и методов, использованных в программе. Руководство пользователя, запуск сервера и клиентского приложения.

    курсовая работа [1,8 M], добавлен 16.09.2015

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

    курсовая работа [1,5 M], добавлен 17.01.2011

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

    курсовая работа [3,5 M], добавлен 11.12.2012

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.