빌더패턴 --------------------------------------------------------------------------------------------------

  당신은 게임중 스테이지를 생성하는 파트를 만들고 있습니다.

  스테이지는 수중맵, 공중맵, 그리고 지상맵으로 나뉩니다. 

  파일을 입력받아서 스테이지를 만드는것에 있어서 단계는 세가지로 나눕니다

  1. 지형및 배경생성.

  2. 몬스터생성.

  3. 오브젝트 생성.

  그런데 스테이지를 만듬에 있어서 세가지 스테이지는 전혀 다른 방식의 함수와 과정을 거쳐서 생성되어야 합니다.

  각 지형마다 특색을 주기 위해서 몬스터나 전반적인 생성방식이 다를 경우 생성하기위한 클래스나 코드가 비대해질수가 있습니다. 그것을 방지하기 위한 패턴이라고 생각해 주시면 됩니다.



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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#include "stdafx.h"
#include <iostream>
#include <time.h>
#include <list>
 
using namespace std;
 
template <typename T>
void SAFE_DELETE(T& pointer)
{
    if(pointer)
    {
        delete pointer;
        pointer = NULL;
    }
}
 
enum STAGE_TYPE
{
    STAGE_TYPE_SKY,
    STAGE_TYPE_SEA,
    STAGE_TYPE_LAND
};
 
enum STAGE_COUNT
{
    STAGE_COUNT_MAXMONSTER = 10,
    STAGE_COUNT_MAXMONSTERTYPE = 20,
    STAGE_COUNT_MAXTERRAIN = 10,
    STAGE_COUNT_MAXTERRAINTYPE = 10
};
 
typedef struct tagStageFile
{
    STAGE_TYPE  eStageType;
    int            iBackGround;
    int            listMonster[STAGE_COUNT_MAXMONSTER];
    int            listTerrain[STAGE_COUNT_MAXTERRAIN];
 
public:
    tagStageFile(void)    
    { 
        eStageType = (STAGE_TYPE)(rand() % 3); 
        iBackGround = rand() % 10;
 
        memset(listMonster, -1, sizeof(int)*STAGE_COUNT_MAXMONSTER);
        memset(listTerrain, -1, sizeof(int)*STAGE_COUNT_MAXMONSTER);
 
        for (int i = 0; i < (rand() % 10) ; ++i)
        {
            listMonster[i] = rand() % STAGE_COUNT_MAXMONSTERTYPE;
            listTerrain[i] = rand() % STAGE_COUNT_MAXTERRAINTYPE;
        }
    }
 
}STAGEFILE;
 
class CStage
{
private:
    STAGE_TYPE  eStageType;
    int            iBackGround;
    list<int>    listMonster;
    list<int>    listTerrain;
 
public:
    void SetStageType(STAGE_TYPE& _eStageType) { eStageType = _eStageType; }
    void SetBackGround(int& _iBackGround) { iBackGround = _iBackGround; }
    void SetMonster(int& _MonsterType) { listMonster.push_back(_MonsterType); }
    void SetTerrain(int& _TerrainType) { listTerrain.push_back(_TerrainType); }
 
public:
    CStage(void) {}
    ~CStage(void) {}
};
 
class CStageBuilder
{
protected:
    CStage    m_Stage;
 
public:
    CStage GetStage(void) { return m_Stage; }
    
    virtual void CreBackGround(int _BackGroundIndex) = 0;
    virtual void CreMonster(int _MonsterType) = 0;
    virtual void CreTerrain(int _TerrrainType) = 0;
 
public:
    CStageBuilder(void) {}
    virtual ~CStageBuilder(void) {}
};
 
class CSkyBuilder
    : public CStageBuilder
{
    virtual void CreBackGround(int _BackGroundIndex) 
    { cout << _BackGroundIndex << " 번 하늘이미지 배경으로 선택" << endl; m_Stage.SetBackGround(_BackGroundIndex); }
    virtual void CreMonster(int _MonsterType) 
    { if(_MonsterType != -1) cout << _MonsterType << " 타입 공중몬스터 생성" << endl; m_Stage.SetMonster(_MonsterType); }
    virtual void CreTerrain(int _TerrrainType) 
    { if(_TerrrainType != -1) cout << _TerrrainType << " 타입 공중지형지물생성" << endl; m_Stage.SetMonster(_TerrrainType); }
 
public:
    CSkyBuilder(void) {}
    virtual ~CSkyBuilder(void) {}
};
 
class CSeaBuilder
    : public CStageBuilder
{
    virtual void CreBackGround(int _BackGroundIndex) 
    { cout << _BackGroundIndex << " 번 바다이미지 배경으로 선택" << endl; m_Stage.SetBackGround(_BackGroundIndex); }
    virtual void CreMonster(int _MonsterType) 
    { if(_MonsterType != -1) cout << _MonsterType << " 타입 바다몬스터 생성" << endl; m_Stage.SetMonster(_MonsterType); }
    virtual void CreTerrain(int _TerrrainType) 
    { if(_TerrrainType != -1) cout << _TerrrainType << " 타입 바다지형지물 생성" << endl; m_Stage.SetMonster(_TerrrainType); }
 
public:
    CSeaBuilder(void) {}
    virtual ~CSeaBuilder(void) {}
};
 
class CLandBuilder
    : public CStageBuilder
{
    virtual void CreBackGround(int _BackGroundIndex) 
    { cout << _BackGroundIndex << " 번 하늘이미지 배경으로 선택" << endl; m_Stage.SetBackGround(_BackGroundIndex); }
    virtual void CreMonster(int _MonsterType) 
    { if(_MonsterType != -1) cout << _MonsterType << " 타입 땅몬스터 생성" << endl; m_Stage.SetMonster(_MonsterType); }
    virtual void CreTerrain(int _TerrrainType) 
    { if(_TerrrainType != -1) cout << _TerrrainType << " 타입 땅지형지물생성" << endl; m_Stage.SetMonster(_TerrrainType); }
 
public:
    CLandBuilder(void) {}
    virtual ~CLandBuilder(void) {}
};
 
class CStageDirector
{
private:
    STAGEFILE       m_tStageFile;
    CStageBuilder* m_cStageBuilder;
 
public:
    void CreStage (STAGEFILE _tStageFile)
    {
        cout << "---스테이지 타입 확인---" << endl;
        switch(_tStageFile.eStageType)
        {
        case STAGE_TYPE_SKY:
            cout << "하늘 스테이지생성시작" << endl;
            m_cStageBuilder = new CSkyBuilder;
            break;
        case STAGE_TYPE_SEA:
            cout << "해저 스테이지생성시작" << endl;
            m_cStageBuilder = new CSeaBuilder;
            break;
        case STAGE_TYPE_LAND:
            cout << "지상 스테이지생성시작" << endl;
            m_cStageBuilder = new CLandBuilder;
            break;
        }
 
        cout << "---스테이지 배경 생성---" << endl;
        m_cStageBuilder->CreBackGround(m_tStageFile.iBackGround);
 
        cout << "---스테이지 몬스터 생성---" << endl;
        for(int i = 0 ; i < STAGE_COUNT_MAXMONSTER ; ++i)
        { m_cStageBuilder->CreMonster(m_tStageFile.listMonster[i]); }
 
        cout << "---스테이지 지형지물 생성---" << endl;
        for(int i = 0 ; i < STAGE_COUNT_MAXTERRAIN ; ++i)
        { m_cStageBuilder->CreTerrain(m_tStageFile.listTerrain[i]); }
    }
 
public:
    CStage GetResultStage(void) { m_cStageBuilder->GetStage(); }
 
public:
    CStageDirector(void) {}
    ~CStageDirector(void) {    SAFE_DELETE(m_cStageBuilder); }
};
 
int _tmain(int argc, _TCHAR* argv[])
{
 
    srand((unsigned)time(NULL));
    STAGEFILE StageFile;
    CStageDirector StageDirector;
 
    StageDirector.CreStage(StageFile);
 
    return 0;
}
 

실행결과

Posted by JJOREG