Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
5 / 6 / 2
Регистрация: 26.10.2012
Сообщений: 126
1

Паттерны проектирования (Фабрики)

17.01.2015, 16:13. Просмотров 1690. Ответов 5
Метки нет (Все метки)

Добрый вечер. Есть игра "Морской бой" из учебника Павловской Т.А .
Задача: добавить в ней какой-либо шаблон проектирования.

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

Есть заголовочный файл:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//////////////////////////////////////////////////////////////////////////// Navy.h
#include "Ship.h"
#include <assert.h>
#define DECK '+' // исправная клетка-палуба
#define DAMAGE 'X' // разрушенная клетка-палуба
#define MISS 'o' // пустая клетка, в к-рую упал снаряд
typedef unsigned char Field[N][N]; // игровое поле
typedef std::map<Cell, int> ShipMap; // словарь
// ассоциаций "клетка - индекс корабля"
enum CurrentState { Miss, Damage, Kill }; // результат попадания в цель
 
 
struct Space { // ------------ Класс Space - информационное пространство для обмена
public: // информацией между игроками
static Cell u_fire; // огонь от пользователя
static Cell r_fire; // огонь от робота (компьютера)
static CurrentState u_state; // состояние пользователя
static CurrentState r_state; // состояние робота
static int step;
};
 
enum Navy_ID { UserNavy_ID=0, RobotNavy_ID };
 
 
 
class Navy : public Space { //---------------------------------- Базовый класс Navy
 
public:
    virtual ~Navy() {}
    static Navy* createNavy( Navy_ID id );
Navy();
void AllocShip( int, int, std::string ); // разместить корабль
void Show() const; // показать поля ownField и enemyField
int GetInt(); // ввод целого числа
bool IsLive() { return ( nLiveShip > 0 ); } // мы еще живы?
Rect Shell( Rect ) const; /* вернуть "оболочку" для заданного прямоугольника
(сам прямоугольник плюс пограничные клетки) */
void AddToVetoSet( Rect ); // добавить клетки прямоугольника
// в множество vetoSet.
protected:
Ship ship[10]; // корабли флота
Field ownField; // мое игровое поле
Field enemyField; // игровое поле неприятеля
ShipMap shipMap; // словарь ассоциаций "клетка - индекс корабля"
CellSet vetoSet; // множество "запрещенных" клеток
CellSet crushSet; // множество "уничтоженных" клеток
int nLiveShip; // количество боеспособных кораблей
 
 
 
};
 
 
class UserNavy : public Navy { //---------------------------------- Класс UserNavy
public:
UserNavy() { Allocation(); }
void Allocation();
void FireOff(); // выстрел по неприятелю
void ResultAnalys(); // анализ результатов выстрела
void GetFire(); // "прием" огня противника
void FillDeadZone( Rect r, Field& ); // заполнить
// пробелами пограничные клетки для r
};
 
 
class RobotNavy : public Navy { // -------------------------------- Класс RobotNavy
public:
RobotNavy();
void Allocation();
void FireOff(); // выстрел по неприятелю
void ResultAnalys(); // анализ результатов выстрела
void GetFire(); // "прием" огня противника
private:
bool isCrushContinue; // предыдущий выстрел был успешным
bool upEmpty; // у поврежденного корабля противника
// нет "живых" клеток в верхнем направлении
};
 
 
Navy* Navy::createNavy( Navy_ID id )
{
    Navy * p;
    switch (id)
    {
        case UserNavy_ID:
            p = new UserNavy();           
            break;      
        case RobotNavy_ID:
            p = new RobotNavy();           
            break;                  
        default:
            assert( false);
    }
    return p;
}
 
class Singleton
{
    public:
        static Singleton& instance();
        void print(char*);
    
    protected:
        static Singleton Instance;
        
    private:
        Singleton();
        ~Singleton();
    
};
Так вот, т.к классы usernavy и RobotNavy наследуются от класса navy я подумал, что можно было бы сделать из них фабрику. Пробовал уже по разному задавать, но в конечном итоге я не могу наладить использование этой фабрики в главном файле.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include "Navy.h"
#include <locale>
#include <vector>
using namespace std;
int main() {
setlocale(LC_ALL,"Russian");
 
UserNavy userNavy; // Начальная позиция
RobotNavy robotNavy;
userNavy.Show();
while ( userNavy.IsLive() && robotNavy.IsLive() ) {
if ( Space::u_state != Miss ) { // ----------------- Выстрел пользователя
cout << "пропускается...: <Enter>" << endl;
cin.get(); }
else {
userNavy.FireOff();
robotNavy.GetFire();
userNavy.ResultAnalys();
if ( !robotNavy.IsLive() ) { userNavy.Show(); break; }
}
if ( Space::r_state != Miss ) // ------------------ Выстрел робота
cout << "\nВыстрел неприятеля: пропускается..." << endl;
else {robotNavy.FireOff();
userNavy.GetFire();
robotNavy.ResultAnalys();
}
userNavy.Show();
}
if ( userNavy.IsLive() ) cout << "\n:-))) Ура! Победа!!! :-)))" << endl;
else { cout << "\n:-((( Увы. Непрятель оказался сильнее." << endl;
}
cin.get();
}

Подскажите пожалуйста как тут поступить или мб есть паттерны по-проще и более уместные.

П,С Цель просто вставить шаблон, пусть он там и не будет особо нужен.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.01.2015, 16:13
Ответы с готовыми решениями:

С чего начать изучать паттерны проектирования?
С чего лучше всего начать изучение паттернов проектирования новичку? Большинство говорят, что надо...

Паттерны проектирования, нужен код на С++ и UML диаграмма
Декоратор (Decorator) или Оболочка (Wrapper) - GoF Итератор (Iterator) или Курсор (Cursor) - GoF...

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

Создание фабрики по созданию объектов
Здорова! Тут вычитал, что создание объектов лучше поручать отдельному классу который называют...

5
Эксперт С++
4962 / 3068 / 456
Регистрация: 10.11.2010
Сообщений: 11,159
Записей в блоге: 10
17.01.2015, 17:24 2
Не вижу у тебя никакой фабрики, вижу только синглтон, который не используется.
0
5 / 6 / 2
Регистрация: 26.10.2012
Сообщений: 126
17.01.2015, 18:20  [ТС] 3
Цитата Сообщение от castaway Посмотреть сообщение
Не вижу у тебя никакой фабрики, вижу только синглтон, который не используется.
Синглтон там вставлен так как я пытаюсь воткнуть разные шаблоны, и когда копировал код пытался сделать синглтон, но с ним я , в итоге, ещё сильнее запутался.

А фабрику я пытался инициализировать через:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Navy* Navy::createNavy( Navy_ID id )
{
    Navy * p;
    switch (id)
    {
        case UserNavy_ID:
            p = new UserNavy();           
            break;      
        case RobotNavy_ID:
            p = new RobotNavy();           
            break;                  
        default:
            assert( false);
    }
    return p;
}
Делал я это по примерам, так что вполне могу ошибаться. С паттернами столкнулся вообще впервые и пытаюсь понять по примерам, но слабо получается.
0
510 / 272 / 60
Регистрация: 14.12.2010
Сообщений: 548
18.01.2015, 13:44 4
Цитата Сообщение от Lotus34 Посмотреть сообщение
П,С Цель просто вставить шаблон, пусть он там и не будет особо нужен.
По паттернам есть книжка Приемы объектно-ориентированного проектирования. Паттерны проектирования.

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

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <memory>
#include <random>
 
enum class EPlayer{ UserPlayer, RobotPlayer };
 
class Move
{
public:
    Move(int _x, int _y) :x(_x), y(_y){}
    int x;
    int y;
};
 
 
class Player{
public:
    virtual Move move() = 0;
    //сюда можно добавить методы инициализации поля и взаимодействия с игрой
};
 
 
class UserPlayer :public Player{
    Move move()override{ std::cout << "I'm User player" << std::endl; return Move(0, 0); }
};
 
class RobotPlayer :public Player{
    Move move()override{ std::cout << "I'm Robot player" << std::endl; return Move(std::rand(), std::rand()); }
};
 
std::unique_ptr<Player> createPlayer(EPlayer _player)
{
    switch (_player)
    {
    case EPlayer::UserPlayer:
        return std::make_unique<UserPlayer>();
    default:
    case EPlayer::RobotPlayer:
        return std::make_unique<RobotPlayer>();
    }
}
 
 
int main() {
    auto player1 = createPlayer(EPlayer::UserPlayer);
    auto player2 = createPlayer(EPlayer::RobotPlayer);
 
    auto move = player1->move();
    move = player2->move();
 
    system("pause");
}
0
Пес войны
111 / 88 / 22
Регистрация: 23.02.2012
Сообщений: 653
18.01.2015, 14:39 5
пару строк тебе подкину
C++
1
2
3
UserNavy userNavy = Navy::createNavy(0); // Начальная позиция
RobotNavy robotNavy = Navy::createNavy(1);
userNavy->Show();
стоить обратить внимание, на айдишники(их следуеть поменять на соответствующие)
и на то, как вызываются функции теперь
0
Эксперт С++
8325 / 6077 / 604
Регистрация: 10.12.2010
Сообщений: 28,209
Записей в блоге: 27
18.01.2015, 15:08 6
Цитата Сообщение от NeonLost Посмотреть сообщение
на айдишники(их следуеть поменять на соответствующие)
на enum поменять...
Ну и не
C++
1
2
UserNavy userNavy = Navy::createNavy(0); // Начальная позиция
RobotNavy robotNavy = Navy::createNavy(1);
А
C++
1
2
BaseNavy* userNavy =  createNavy(ntUser); 
BaseNavy *robotNavy = createNavy(ntRobot);
- Указатели на базовый/абстрактный класс.

Добавлено через 1 минуту
Цитата Сообщение от EVP Посмотреть сообщение
C++
1
2
3
4
5
class Player
{ 
   public: 
      virtual Move move() = 0; 
}
Виртуальный деструктор забыт.
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.01.2015, 15:08

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

Использование фабрики для шаблонного класса
Вот класс template &lt;class T&gt; class ConcreteConverter { T _value; long long _maxValue;...

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

Списки. Смоделировать работу отдела выдачи мебельной фабрики
Добрый день. У меня такой вопрос. Есть задание что то типа &quot;Смоделировать работу отдела выдачи...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.