E-mail: magikgod@mail.ru

Игра Морской Бой (часть 1)
#include <iostream.h>
#include <windows.h>
#include <fstream.h>

#include "field.h"
#include "utils.h"
#include "ships.h"
#include "gameplace.h"
#include "computer.h"
#include "game.h"





using namespace MyField;
using namespace MyUtils;
using namespace MyShips;
using namespace MyComputer;
using namespace GamePlace;
using namespace MyGame;

void main(void)
{
int turn;
char ch;

do
{
cout << "Do you want to move first or second? (1, 2): ";
cin >> turn;

if(turn == 1)
play(PLAYERVSCOMP);
else
play(COMPVSPLAYER);

fill();
cout << endl << "Do you want to continue? (y/n): ";
cin >> ch;

} while (ch == ''y'');

}


//////////////////////////////////////////////////////////
//field.h
//////////////////////////////////////////////////////////


#ifndef __field
#define __field

#define EMPTY 0 //пустая
#define MISSED 1 //мимо
#define WOUNDED 2 //ранен
#define KILLED 3 //убит
#define ZERO 4 //заведомо пустая клетка
#define CSHIP 5 //клетка заняьая кораблем
#define CURSOR 6
#define WITHSHIPS 7
#define WITHOUTSHIPS 8
#define WITHOUTSHIPSANDWOUNDED 9


#define SIDE 10 //длина стороны

#define SHOWSHIPS 11
#define NOSHOWSHIPS 12


namespace MyField{
//структура поле
struct FIELD{
//массив 10х10, которым представленно игровое поле
int field[10][10];
//режим показа поля
int showMode;
};

//функция очистки поля
void clearField(FIELD &field);

//функция прорисовки поля
void drawField(FIELD field, COORD coord);

//функция прорисовки одной клетки
void drawCell(FIELD field, COORD coord, int i, int j);

//функция установки знаков на поле
void setSign(FIELD &field, int x, int y, int sign);

//функция получения знака
int getSign(FIELD field, int x, int y);

//функция установки режима отображения
void setShowMode(FIELD &field, int showMode);

//функция копирования поля
void copyField(FIELD &dfield, const FIELD sfield, int flag);



};


#endif //__field



//////////////////////////////////////////////////////////
//field.cpp
//////////////////////////////////////////////////////////


#include <iostream.h>
#include <windows.h>
#include <fstream.h>
#include <string.h>
#include <stdio.h>
#include "field.h"

//функция очистки поля
void MyField :: clearField(FIELD &field)
{
for(int i = 0; i < SIDE; i++)
for(int j = 0; j < SIDE; j++)
field.field[i][j] = EMPTY;
}

//функция прорисовки поля
void MyField :: drawField(FIELD field, COORD coord)
{
COORD oldCoord = coord;
HANDLE Handle;
LPDWORD lpNumberOfCharsWritten;
LPVOID lpReserved;
Handle = GetStdHandle(STD_OUTPUT_HANDLE);

//нарисовать координаты
SetConsoleCursorPosition(Handle, coord);
WriteConsole(Handle, " A B C D E F G H I J", 33,
lpNumberOfCharsWritten, lpReserved);

char szBuf[3];
int nSize;

for(int i = 0; i < SIDE; i++)
{
coord.Y++;
SetConsoleCursorPosition(Handle, coord);
nSize = sprintf(szBuf, "%d", i + 1);
WriteConsole(Handle, szBuf, nSize,
lpNumberOfCharsWritten, lpReserved);
}

coord = oldCoord;


WORD colour;
char sign[3];
LPDWORD lpdwN;

//просмотреть знака каждой клетки и
//и в зависимости от этого отобразить ее на экране
//в том или ином виде
for(int j = 0; j < SIDE; j++)
{

coord.Y++;
for(int i = 0; i < SIDE; i++)
{
coord.X+=3;

if(field.field[i][j] == CURSOR)
{
colour = BACKGROUND_RED|
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " ");
}


//если клетка занята кораблем
//нарисовать плюсик на голубом фоне
if((field.field[i][j] == CSHIP)&&
(field.showMode == SHOWSHIPS))
{
colour = BACKGROUND_GREEN| BACKGROUND_BLUE |
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " + ");
}


if((field.field[i][j] == CSHIP)
&&(field.showMode == NOSHOWSHIPS))
{
colour = BACKGROUND_GREEN|
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " ");
}

//если клетка пустая, нарисовать ее зеленым цветом
if(field.field[i][j] == EMPTY)
{
colour = BACKGROUND_GREEN|
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " ");

}

//если клетка пустая, поставить точку
if(field.field[i][j] == ZERO)
{
colour = BACKGROUND_GREEN|
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " . ");
}

//если в клетку уже стреляли, но не попали
//поставить кружочек
if(field.field[i][j] == MISSED)
{
colour = BACKGROUND_GREEN|
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " 0 ");
}

//если на клетке находится раненый корабль,
//поставить звездочку
if(field.field[i][j] == WOUNDED)
{
colour = BACKGROUND_BLUE| BACKGROUND_RED|
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " * ");
}

//если на клетке находится убитый корабль,
//нарисовать крестик
if(field.field[i][j] == KILLED)
{
colour = BACKGROUND_RED|
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " X ");
}


SetConsoleCursorPosition(Handle, coord);
WriteConsole(Handle, sign, 3,
lpNumberOfCharsWritten, lpReserved);


FillConsoleOutputAttribute(
Handle,
colour,
3,
coord,
lpdwN
);

}
coord.X-=30;
}
}


void MyField :: drawCell(FIELD field, COORD coord, int i, int j)
{
HANDLE Handle;
LPDWORD lpNumberOfCharsWritten;
LPVOID lpReserved;
Handle = GetStdHandle(STD_OUTPUT_HANDLE);

WORD colour;

char sign[3];
LPDWORD lpdwN;

coord.X += (i + 1)*3;
coord.Y += j + 1;

if(field.field[i][j] == CURSOR)
{
colour = BACKGROUND_RED|
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " ");
}


//если клетка занята кораблем
//нарисовать плюсик на голубом фоне
if((field.field[i][j] == CSHIP)&&
(field.showMode == SHOWSHIPS))
{
colour = BACKGROUND_GREEN| BACKGROUND_BLUE |
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " + ");
}

if((field.field[i][j] == CSHIP)
&&(field.showMode == NOSHOWSHIPS))
{
colour = BACKGROUND_GREEN|
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " ");
}

//если клетка пустая, нарисовать ее зеленым цветом
if(field.field[i][j] == EMPTY)
{
colour = BACKGROUND_GREEN|
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " ");

}

//если клетка пустая, поставить точку
if(field.field[i][j] == ZERO)
{
colour = BACKGROUND_GREEN|
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " . ");
}

//если в клетку уже стреляли, но не попали
//поставить кружочек
if(field.field[i][j] == MISSED)
{
colour = BACKGROUND_GREEN|
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " 0 ");
}

//если на клетке находится раненый корабль,
//поставить звездочку
if(field.field[i][j] == WOUNDED)
{
colour = BACKGROUND_BLUE| BACKGROUND_RED|
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " * ");
}

//если на клетке находится убитый корабль,
//нарисовать крестик
if(field.field[i][j] == KILLED)
{
colour = BACKGROUND_RED|
FOREGROUND_BLUE |
FOREGROUND_GREEN | FOREGROUND_RED;
strcpy(sign, " X ");
}


SetConsoleCursorPosition(Handle, coord);
WriteConsole(Handle, sign, 3,
lpNumberOfCharsWritten, lpReserved);

FillConsoleOutputAttribute(
Handle,
colour,
3,
coord,
lpdwN
);
}


//функция установить знак, характеризующий данную клетку
void MyField :: setSign(FIELD &field, int x, int y, int sign)
{
if((x >= 0)&&(x < 10)&&(y >= 0)&&(y < 10))
field.field[x][y] = sign;
}

//функция узнать знак
int MyField :: getSign(FIELD field, int x, int y)
{
if((x >= 0)&&(x < 10)&&(y >= 0)&&(y < 10))
return field.field[x][y];
else
return ERROR;
}

//функция установить режим отображения поля
void MyField :: setShowMode(FIELD &field, int showMode)
{
field.showMode = showMode;
}

//скопировать поле
void MyField :: copyField(FIELD &dfield, const FIELD sfield, int flag)
{
int i, j;
for(i = 0; i < SIDE; i++)
for(j = 0; j < SIDE; j++)
{
if(flag == WITHSHIPS)
dfield.field[i][j] = sfield.field[i][j];
else
if(flag == WITHOUTSHIPS)
{
if(sfield.field[i][j] == CSHIP)
dfield.field[i][j] = EMPTY;
else
dfield.field[i][j] = sfield.field[i][j];
}
else
if(flag == WITHOUTSHIPSANDWOUNDED)
{
if((sfield.field[i][j] == CSHIP)||
(sfield.field[i][j] == WOUNDED))
dfield.field[i][j] = EMPTY;
else
dfield.field[i][j] = sfield.field[i][j];
}
}

dfield.showMode = sfield.showMode;
}



//////////////////////////////////////////////////////////
//ships.h
//////////////////////////////////////////////////////////

#ifndef __ships
#define __ships


#include "field.h"

#define VERTICAL 21
#define HORIZONTAL 22
#define FAILED 0
#define SUCCEEDED 1
#define DESTROYED 23
#define LIVE 24


using namespace MyField;

namespace MyShips{
//структура корабль
struct SHIP {
//количество палуб
int size;
//координаты каждой палубы
COORD coord[4];
//статус корабля (живой, живой, но раненый или убитый
int shipStatus;

};

//поставить корабль на поле в определенную точку
//и в определенном направлении
int setShip(SHIP &ship, FIELD &field, COORD coord,
int size, int direction);

//поставить корабль определенного в случайное место
int setShipToRandomPlace(SHIP &ship, FIELD &feld, int size);

//установить статус корабля
void setShipStatus(SHIP &ship, int shipStatus);

//узнать статус корабля
int getShipStatus(SHIP ship);

//узнать размер корабля
int getShipSize(SHIP ship);

//узнать координаты палубы корабля по ее номеру
COORD getShipCoord(SHIP ship, int deck);

//убить корабль - выполнить все действия связанные с уничтожением
//корабля (установить статус корабля, статус клетки поля и т. д.)
void killShip(SHIP &ship, FIELD &field);


//
//вспомогательные функции проверки
//
//находится ли клетка с такими координатами внутри пол
int IsInside(int x, int y);
//помечена ли данная клетка как "промах"
int IsMissed(FIELD field, int x, int y);
//пуста ли данная клетка
int IsEmpty(FIELD field, int x, int y);

};

#endif




//////////////////////////////////////////////////////////
//ships.cpp
//////////////////////////////////////////////////////////

#include <iostream.h>
#include <windows.h>
#include <stdlib.h>
#include "ships.h"
#include "field.h"



//функция установки корабля на заданную клетку
int MyShips :: setShip(SHIP &ship, FIELD &field, COORD coord,
int size, int direction)
{
int x, y;

for(int i = 0; i < size; i++)
{
if(direction == VERTICAL)
{
x = coord.X;
y = coord.Y + i;
//если на данную клетку нельзя поставить корабль,
//выйти из функции
if(!(IsEmpty(field, x, y)&&IsInside(x, y)
&&!IsMissed(field, x, y)))
return FAILED;
if(!(IsEmpty(field, x - 1, y - 1)&&
IsEmpty(field, x - 1, y )&&
IsEmpty(field, x - 1, y + 1)&&
IsEmpty(field, x , y - 1)&&
IsEmpty(field, x , y + 1)&&
IsEmpty(field, x + 1, y - 1)&&
IsEmpty(field, x + 1, y )&&
IsEmpty(field, x + 1, y + 1)))
return FAILED;
}
else
{
x = coord.X + i;
y = coord.Y;
//если на данную клетку нельзя поставить корабль,
//выйти из функции
if(!(IsEmpty(field, x, y)&&IsInside( x, y)
&&!IsMissed(field, x, y)))
return FAILED;
if(!(IsEmpty(field, x - 1, y - 1)&&
IsEmpty(field, x - 1, y )&&
IsEmpty(field, x - 1, y + 1)&&
IsEmpty(field, x , y - 1)&&
IsEmpty(field, x , y + 1)&&
IsEmpty(field, x + 1, y - 1)&&
IsEmpty(field, x + 1, y )&&
IsEmpty(field, x + 1, y + 1)))
return FAILED;

Hosted by uCoz