Скачиваний:
0
Добавлен:
09.09.2026
Размер:
165 Кб
Скачать

МИНОБРНАУКИ РОССИИ

Санкт-Петербургский государственный

электротехнический университет

«ЛЭТИ» им. В. И. Ульянова (Ленина)

Кафедра МО ЭВМ

отчет

по лабораторной работе №3

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

Тема: Полиморфизм

Студентка гр. 2383

Бараева Е. Н.

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

Жангиров Т. Р.

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

2023

Цель работы.

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

Задание.

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

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

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

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

Примечания:

  • События должны быть такими, чтобы был сценарий проигрыша игрока.

  • В событиях и клетках не должно быть полей сообщающих информацию о типе события

Выполнение работы.

Class Interface

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

Class GoodEvent

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

Class BadEvent

В данном классе есть виртуальный метод DispatchEvent, который отрицательно влияет на характеристики игрока.

Class MovementEvent

В данном классе есть виртуальный метод DispatchEvent, который влияет на положение игрока (передвигает его на 1 клетку вправо).

Class CreationLevels

Этот класс создает 2 уровня. У него есть приватные поля level_1 и level_2 – это будущие поле игрока, а также есть 2 шаблона для 1 и 2 уровней. В конструкторе класса проходимся по каждому символу шаблона и устанавливаем проходимость клетки и событие в ней. Так проделывается для 2 уровней. Также в классе есть 2 метода GetLevel1 и GetLevel2. Они возвращают экземпляр класса Field для уровня 1 и 2 соответственно. Также есть метод SetCell, который в зависимости от передаваемого символа из шаблона устанавливает событие и проходимость клетки.

Class Controller

В этом классе была реализована еще 1 метод CheckEvent, который проверяет наличие события и срабатывает его, если он есть.

Class Cell

В данном классе были созданы 3 метода SetGoodEvent, SetBadEvent, SetMovementEvent, они устанавливают события в передающуюся клетку.

Разработанный программный код см. в приложении А.

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

Результаты тестирования представлены в табл. 1.

Таблица 1 – Результаты тестирования

№ п/п

Входные данные

Выходные данные

Комментарии

1.

Field p1(110, 110);

Field p2(120, 120);

Field p3 = p1; // конструктор копирования

p2 = p1; // оператор копирования

Field p4(140, 140);

Field p5 = std::move(p4); // конструктор перемещения

Field p6(160, 160);

p6 = Field(); // оператор перемещения

Проверка конструкторов копирования и перемещения, а также соответствующие им операторы присваивания.

Верно.

Вывод.

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

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

Название файла: Field.h

#ifndef OOP_FIELD_H

#define OOP_FIELD_H

#include <iostream>

#include "Cell.h"

struct CellCoordinates{

int x;

int y;

};

class Field {

private:

Cell** game_field = nullptr;

int height;

int length;

CellCoordinates entry;

CellCoordinates exit;

public:

Field(int height = 100, int length = 100);

~Field();

Field(const Field& x) noexcept;

Field& operator=(Field& x);

Field(Field&& other) noexcept;

Field& operator=(Field&& other) noexcept;

void CheckSize(int height, int length) const;

Cell& GetCell(int x, int y) const;

};

#endif //OOP_FIELD_H

Название файла: Field.cpp

#include "Field.h"

#include <iostream>

#define MIN_FIELD 10

#define MAX_FIELD 500

Field::Field(int height, int length): height{height}, length{length}, entry({0, 0}), exit({height - 1, length - 1}){

CheckSize(height, length);

game_field = new Cell*[height];

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

game_field[i] = new Cell[length];

}

Field::~Field(){

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

delete[] game_field[i];

delete[] game_field;

game_field = nullptr;

}

Field::Field(const Field& x) noexcept: height{x.height}, length{x.length}, entry{x.entry}, exit{x.exit}, game_field{new Cell*[x.height]} {

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

game_field[i] = new Cell[length];

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

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

game_field[i][j] = x.game_field[i][j];

}

}

Field& Field::operator=(Field& x){

if (this != &x){

delete[] game_field;

height = x.height;

length = x.length;

entry = x.entry;

exit = x.exit;

game_field = new Cell*[height];

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

game_field[i] = new Cell[length];

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

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

game_field[i][j] = x.game_field[i][j];

}

}

return *this;

}

Field::Field(Field&& other) noexcept{

game_field = other.game_field;

height = other.height;

length = other.length;

entry = other.entry;

exit = other.exit;

other.game_field = nullptr;

other.height = 0;

other.length = 0;

other.entry = {-1, -1};

other.exit = {-1, -1};

}

Field& Field::operator=(Field&& other) noexcept{

if (this != &other){

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

delete[] game_field[i];

delete[] game_field;

game_field = other.game_field;

height = other.height;

length = other.length;

entry = other.entry;

exit = other.exit;

other.game_field = nullptr;

other.height = 0;

other.length = 0;

other.entry = {-1, -1};

other.exit = {-1, -1};

}

return *this;

}

void Field::CheckSize(int checked_height, int checked_length) const{

if (checked_length <= MIN_FIELD || checked_height <= MIN_FIELD || checked_length > MAX_FIELD || checked_height > MAX_FIELD)

throw std::invalid_argument("Размеры поля заданы неверно");

}

Cell& Field::GetCell(int x, int y) const{

if (x >= 0 && x < length && y >= 0 && y < height)

return game_field[y][x];

else

throw std::out_of_range("Координаты клетки выходят за границы поля");

}

Название файла: Cell.h

#ifndef OOP_CELL_H

#define OOP_CELL_H

#include "Interface.h"

#include "GoodEvent.h"

#include "BadEvent.h"

#include "MovementEvent.h"

class Cell {

private:

bool passability;

Interface* interface;

public:

explicit Cell(bool passab = true);

void SetPassability(bool value);

bool GetPassability() const;

Interface* GetEvent() const;

void SetGoodEvent();

void SetBadEvent();

void SetMovementEvent();

~Cell();

Cell& operator=(Cell& x);

Cell(const Cell& x) noexcept;

};

#endif //OOP_CELL_H

Название файла: Cell.cpp

#include "Cell.h"

#include <iostream>

Cell::Cell(bool passab) : passability{passab}, interface(nullptr) {}

void Cell::SetPassability(bool value){

passability = value;

}

bool Cell::GetPassability() const{

return passability;

}

Interface* Cell::GetEvent() const{

return interface;

}

Cell::~Cell(){

interface = nullptr;

}

void Cell::SetGoodEvent(){

interface = new GoodEvent;

}

void Cell::SetBadEvent(){

interface = new BadEvent;

}

void Cell::SetMovementEvent(){

interface = new MovementEvent;

}

Cell::Cell(const Cell& x) noexcept{

passability = x.passability;

if(x.interface == nullptr)

interface = nullptr;

else

interface = x.interface->Copy();

}

Cell& Cell::operator=(Cell& x){

if (this != &x){

passability = x.passability;

if(x.interface == nullptr)

interface = nullptr;

else

interface = x.interface->Copy();

}

return *this;

}

Название файла: Interface.h

#ifndef OOP_INTERFACE_H

#define OOP_INTERFACE_H

class Controller;

class Interface {

public:

virtual void DispatchEvent(Controller *controller) = 0;

virtual Interface* Copy() = 0;

};

#endif //OOP_INTERFACE_H

Название файла: GoodEvent.h

#ifndef OOP_GOODEVENT_H

#define OOP_GOODEVENT_H

#include "Interface.h"

class GoodEvent : public Interface {

public:

void DispatchEvent(Controller* controller) override;

Interface* Copy() override;

};

#endif //OOP_GOODEVENT_H

Название файла: GoodEvent.cpp

#include "GoodEvent.h"

#include "Controller.h"

void GoodEvent::DispatchEvent(Controller* controller){

controller->ShiftHealth(10);

controller->ShiftStrength(10);

}

Interface* GoodEvent::Copy() {

return new GoodEvent;

}

Название файла: BadEvent.h

#ifndef OOP_BADEVENT_H

#define OOP_BADEVENT_H

#include "Interface.h"

class BadEvent : public Interface {

public:

void DispatchEvent(Controller* controller) override;

Interface* Copy() override;

};

#endif //OOP_BADEVENT_H

Название файла: BadEvent.cpp

#include "BadEvent.h"

#include "Controller.h"

void BadEvent::DispatchEvent(Controller* controller){

controller->ShiftHealth(-10);

controller->ShiftEndurance(-10);

}

Interface* BadEvent::Copy(){

return new BadEvent;

}

Название файла: MovementEvent.h

#ifndef OOP_MOVEMENTEVENT_H

#define OOP_MOVEMENTEVENT_H

#include "Interface.h"

class MovementEvent : public Interface {

public:

void DispatchEvent(Controller* controller) override;

Interface* Copy() override;

};

#endif //OOP_MOVEMENTEVENT_H

Название файла: MovementEvent.cpp

#include "MovementEvent.h"

#include "Controller.h"

void MovementEvent::DispatchEvent(Controller* controller){

controller->Move(right);

controller->Move(right);

}

Interface *MovementEvent::Copy() {

return new MovementEvent;

}

11

Соседние файлы в папке Лабы по ООП 2023