언어 자료구조 알고리즘/디딤돌 C++

[C++] 87. 최종 실습 - 소스 코드

언제나휴일 2016. 5. 1. 19:52
반응형

[C++] 87. 최종 실습 - 소스 코드


68. 최종 실습 - 개발 공정 및 시나리오

69. 최종 실습 - 요구 분석 및 정의

70. 최종 실습 - 설계1(클래스 다이어그램)

71. 최종 실습 - EHNARA 뼈대

72. 최종 실습 - 프로토 타이핑

73. 최종 실습 - 확장 가능한 순차 배열

74. 최종 실습 - 클래스 추가하기

75. 최종 실습 - 초기화 및 해제화

76. 최종 실습 - 학생 생성

77. 최종 실습 - 학생 이동

78. 최종 실습 - 전체 보기

79. 최종 실습 - 학생 복귀

80. 최종 실습 - 강의 시작

81. 최종 실습 - 도서관 가기

82. 최종 실습 - 소등

83. 최종 실습 - 거실로 가기

84. 최종 실습 - 파티

85. 최종 실습 - 노래방 가기

86. 최종 실습 - 다이어그램


클래스 다이어그램

//ehglobal.h

#pragma once

enum keydata //기능 키에 사용할 상수 열거

{

    NO_DEFINED,F1,F2,F3,F4,F5,F6,F7,F8, ESC

};

 

class ehglobal

{

public:

    static void clrscr();         //콘솔 화면 클리어

    static keydata getkey();   //기능 키 입력

    static void waitkey(); //아무 키나 누를 때까지 대기

private:

    ehglobal(void)

    {

    }

    ~ehglobal(void)

    {

    }     

};

 

--------------------------------------------------------------------------------

 

//ehglobal.cpp

#include "ehglobal.h" 

#pragma warning(disable:4996)

#include <conio.h>

#include <windows.h>

 

void ehglobal::clrscr()

{

    system("cls");   

}

keydata ehglobal::getkey()

{

    int key = getch();

    if(key == 27)//key 27이면 ESC를 누른 것입니다.

    {

        return ESC;

    }

    if(key == 0) //key 0이면 기능 키를 누른 것입니다.

    {

        key = getch();//다시 한 번 getkey를 호출해야 합니다.

        switch(key)//key의 값에 따라 기능 키를 정의한 열거형의 상수를 반환합니다.

        {

        case 59: return F1;     case 60: return F2;

        case 61: return F3;     case 62: return F4;

        case 63: return F5;     case 64: return F6;

        case 65: return F7;     case 66: return F8;

        }

             }

    return NO_DEFINED;

}

void ehglobal::waitkey()

{

    getkey();

}

 

--------------------------------------------------------------------------------

 

//SeqArray.h

#pragma once

template <typename data>

class SeqArray

{

    data *base; //저장소

    size_t capacity; //저장소 크기

    size_t size; //보관 개수

public:

    SeqArray()

    {

        base = 0;

        capacity = 0;

        size = 0;

    }

    ~SeqArray(void)

    {

        if(base)//저장소가 있을 때

        {

            delete[] base;//저장소 해제

        }

    }

    void PushBack(data value)//순차 보관

    {

        if(IsFull())//꽉차면

        {

            if(capacity)//저장소의 개수가 참일 때

            {

                Reserve(capacity *2);//두 배로 확장

            }

            else//아닐 때(0일 때)

            {

                Reserve(1);//1로 확장

            }

        }

        base[size] = value;//보관

        size++;//보관 개수 1 증가

    }

    void RemoveAt(size_t index)//특정 인덱스 요소 삭제

    {

        if(IsAvailIndex(index)==false)//인덱스가 유효하지 않을 때

        {

            return;

        }

        size--;//보관 개수 1 감소

        for(   ;index<size;index++)

        {

            base[index] = base[index+1];//한 칸씩 앞으로 이동

        }

    }

    template <typename find_if>

    int FindIf(find_if fun)//특정 알고리즘이 처음으로 참인 위치 찾기

    {

        for(size_t i = 0; i<size; ++i)

        {

            if(fun(base[i]))//알고리즘에 적용하였을 때 참이면

            {

                return i; //인덱스 반환

            }

        }

        return -1;//-1 반환

    }

    data &operator[](size_t index)//인덱서

    {

        if(IsAvailIndex(index)==false)//유효하지 않은 인덱스일 때

        {

            throw "유효하지 않은 인덱스를 사용하였습니다.";//예외 던짐

        }

        return base[index];//인덱스의 원소 반환

    }

    bool IsAvailIndex(size_t index)const//유효한 인덱스인지 판별

    {

        return (index>=0)&&(index<size);

    }

    size_t GetSize()const

    {

        return size;

    }

private:

    bool IsFull()const//꽉 찼는지 판별

    {

        return size == capacity;

    }

    void Reserve(int ncapacity)//저장소 확장

    {

        data *tbuf = base;//저장소 위치를 tbuf로 설정

        base = new data[ncapacity];//저장소 동적 할당

        capacity = ncapacity;//저장소 크기 설정

        if(tbuf)//이전 저장소가 참이면

        {

            for(size_t i=0; i<size;++i)

            {

                base[i] = tbuf[i];//이전 저장소에 보관한 값을 새로운 저장소로 이동

            }

            delete[] tbuf;//이전 저장소 메모리 해제

        }

    }

};

 

 

--------------------------------------------------------------------------------

 

//IPlay.h

#pragma once

#ifndef interface

#define interface struct

#endif

 

interface IPlay

{

    virtual void Drink();

    virtual void Sing();

};

 

--------------------------------------------------------------------------------

 

//IRelax.h

#pragma once

#ifndef interface

#define interface struct

#endif

 

interface IRelax

{

    virtual void Sleep()=0;

    virtual void Relax()=0;

};

 

--------------------------------------------------------------------------------

 

//IStudy.h

#pragma once

#ifndef interface

#define interface struct

#endif

 

interface IStudy

{

    virtual void ListenLecture()=0;

    virtual void Study()=0;

};

 

--------------------------------------------------------------------------------

 

//Man.h

#pragma once

#include <iostream>

#include <string>

using namespace std;

class Man

{

    static int last_pn;

    const int pn;

    string name;

    int snum;//학번

public:

    Man(string name);

    int GetPN()const;

    string GetName()const;

    int GetSNum()const;//학번 접근자

    void SetSNum(int snum); //학번 설정자

    virtual void View()const=0;//정보보기

};

 

--------------------------------------------------------------------------------

 

//Man.cpp

#include "Man.h"

int Man::last_pn;

   

Man::Man(string name):pn(++last_pn)

{

    this->name = name;

    snum = 0;

}

int Man::GetPN()const

{

    return pn;

}

string Man::GetName()const

{

    return name;

}

int Man::GetSNum()const//학번 접근자

{

    return snum;

}

void Man::SetSNum(int snum) //학번 설정자

{

    this->snum = snum;

}

 

--------------------------------------------------------------------------------

 

//IComeBack.h

#pragma once

#ifndef interface

#define interface struct

#endif

#include "Man.h"

interface IComeBack

{

    virtual void ComeBack(Man *man)=0;

};

 

--------------------------------------------------------------------------------

 

//StuConst.h

#pragma once

class StuConst

{

public:

    static const int def_iq;

    static const int max_iq;

    static const int min_iq;

 

    static const int def_hp;

    static const int max_hp;

    static const int min_hp;

 

    static const int def_stress;

    static const int max_stress;

    static const int min_stress;

 

    static const int def_scnt;

    static const int max_scnt;

    static const int min_scnt;

   

private://개체를 생성할 수 없게 함

    StuConst(void);   

};

 

--------------------------------------------------------------------------------

 

//StuConst.cpp

#include "StuConst.h"

const int StuConst::def_iq = 100;

const int StuConst::max_iq=200;

const int StuConst::min_iq=0;

            

const int StuConst::def_hp=100;

const int StuConst::max_hp=200;

const int StuConst::min_hp=0;

            

const int StuConst::def_stress=0;

const int StuConst::max_stress=100;

const int StuConst::min_stress=0;

            

const int StuConst::def_scnt=0;

const int StuConst::max_scnt=5;

const int StuConst::min_scnt=0;

 

StuConst::StuConst(void)

{

}

 

--------------------------------------------------------------------------------

 

//Student.h

#pragma once

#include "Man.h"

#include "IPlay.h"

#include "IRelax.h"

#include "IStudy.h"

#include "StuConst.h"

 

using namespace std;

class Student:public Man, public IStudy, public IRelax, public IPlay

{

    int iq;

    int hp;

    int stress;

    int scnt;

public:   

    friend class StuFactory;

    virtual void Study();

    virtual void ListenLecture();

    virtual void Sleep();

    virtual void Relax();

    virtual void Drink();

    virtual void Sing();

    virtual void View()const;

    int GetIQ()const;

    int GetHP()const;

    int GetStress()const;

    int GetSCnt()const;

protected:

    Student(string name);

    void SetIQ(int iq);

    void SetHP(int hp);

    void SetStress(int stress);

    void SetSCnt(int scnt);   

};

 

--------------------------------------------------------------------------------

 

//Student.cpp

#include "Student.h"

#define SC StuConst //간략하게 사용할 수 있게 매크로 정의

 

Student::Student(string name):Man(name)

{ 

    SetIQ(SC::def_iq);

    SetHP(SC::def_hp);   

    SetStress(SC::def_stress);

    SetSCnt(SC::def_scnt);

}

void Student::View()const

{

    cout<<"주민 번호:"<<GetPN()<<" 이름:"<<GetName()<<endl;

    cout<<"  IQ:"<<iq<<" HP:"<<hp<<" Stress:"<<stress<<endl;

    cout<<연속으로 공부한 횟수:"<<scnt<<endl;

}

int Student::GetIQ()const

{

    return iq;

}

int Student::GetHP()const

{

    return hp;

}

int Student::GetStress()const

{

    return stress;

}

int Student::GetSCnt()const

{

    return scnt;

}

 

void Student::SetIQ(int iq)

{

    if(iq>SC::max_iq)

    {

        iq = SC::max_iq;

    }

    if(iq<SC::min_iq)

    {

        iq = SC::min_iq;

    }

    this->iq = iq;

}

void Student::SetHP(int hp)

{

    if(hp>SC::max_hp)

    {

        hp = SC::max_hp;

    }

    if(hp<SC::min_hp)

    {

        hp = SC::min_hp;

    }

    this->hp = hp;

}

void Student::SetStress(int stress)

{

    if(stress>SC::max_stress)

    {

        stress = SC::max_stress;

    }

    if(stress<SC::min_stress)

    {

        stress = SC::min_stress;

    }

    this->stress = stress;

}

void Student::SetSCnt(int scnt)

{

    if(scnt>SC::max_scnt)

    {

        scnt = SC::max_scnt;

    }

    if(scnt<SC::min_scnt)

    {

        scnt = SC::min_scnt;

    }

    this->scnt = scnt;

}

void Student::ListenLecture()

{

    cout<<GetName()<<" 강의받다."<<endl;

}

void Student::Study()

{

    cout<<GetName()<<" 공부하다."<<endl;

}

void Student::Sleep()

{

    cout<<GetName()<<" 잠을 자다."<<endl;

}

void Student::Relax()

{

    cout<<GetName()<<" 휴식하다."<<endl;

}

void Student::Drink()

{

    cout<<GetName()<<" 음료를 마시다."<<endl;

}

void Student::Sing()

{

    cout<<GetName()<<" 노래하다."<<endl;

}

 

--------------------------------------------------------------------------------

 

//MStudent.h

#pragma once

#include "Student.h"

class MStudent :

    public Student

{

    int stick;

public:   

    friend class StuFactory;

    virtual void Study();

    virtual void ListenLecture();

    virtual void Sleep();

    virtual void Relax();

    virtual void Drink();

    virtual void Sing();

    virtual void View()const;

    void Travel();

private:

    MStudent(string name);

};

 

--------------------------------------------------------------------------------

 

//MStudent.cpp

#include "MStudent.h"

 

MStudent::MStudent(string name):Student(name)

{

    stick=0;//지팡이는 생성 시 0

}

 

void MStudent::Study()

{   

    Student::Study();

    Student::ListenLecture();

    SetHP(GetHP()-3);//체력 3소모

    SetIQ(GetIQ()+GetSCnt());//지력: scnt 증가

    SetStress(GetStress()+3);//스트레스: 3증가

    SetSCnt(GetSCnt()+1);   

}

void MStudent::ListenLecture()

{

    SetHP(GetHP()-2); //체력 2소모

    SetIQ(GetIQ()+GetSCnt());//지력: scnt 증가

    SetStress(GetStress()+5);// 스트레스: 5증가

    SetSCnt(0);

}

void MStudent::Sleep()

{

    Student::Sleep();

    SetHP(GetHP()+10); //체력 10회복   

    SetStress(GetStress()-5); //스트레스: 5감소

    SetSCnt(0);

}

void MStudent::Relax()

{

    Student::Relax();

    SetHP(GetHP()+3); //체력 3회복   

    SetStress(GetStress()-25); //스트레스: 25감소

    SetSCnt(0);

}

void MStudent::Drink()

{

    Student::Drink();

    SetHP(GetHP()+5+stick); //체력 5+지팡이 회복

    SetIQ(GetIQ()-(10-stick));//지력:  10-지팡이 감소

    SetStress(GetStress()-2);//스트레스: 2감소

    SetSCnt(0);   

}

void MStudent::Sing()

{

    Student::Sing();

    SetHP(GetHP()-(10-stick)); //체력 10-지팡이 소모

    SetIQ(GetIQ()-5);//지력: 5감소

    SetStress(GetStress()-5);//스트레스: 5감소

    SetSCnt(0);   

}

void MStudent::View()const

{

    cout<<"마법 학생";

    Student::View();

    cout<<" 지팡이:"<<stick<<endl;

}

void MStudent::Travel()

{

    cout<<GetName()<<" 여행하다."<<endl;

    stick++;//지팡이 1증가   

}

 

--------------------------------------------------------------------------------

 

//PStudent.h

#pragma once

#include "Student.h"

class PStudent :

    public Student

{

    int air;

public:   

    friend class StuFactory;

    virtual void Study();

    virtual void ListenLecture();

    virtual void Sleep();

    virtual void Relax();

    virtual void Drink();

    virtual void Sing();

    virtual void View()const;

    void Dance();

private:

    PStudent(string name);

};

 

--------------------------------------------------------------------------------

 

//PStudent..cpp

#include "PStudent.h"

 

PStudent::PStudent(string name):Student(name)

{

    air=0;//air는 생성 시 0

}

void PStudent::Study()

{   

    Student::Study();

    SetHP(GetHP()-2);//체력 2소모

    SetIQ(GetIQ()+GetSCnt()/2);//지력: scnt/2 증가

    air-=3;

    SetStress(GetStress()-air*3);//스트레스: air*3감소

    SetSCnt(GetSCnt()+1);   

}

void PStudent::ListenLecture()

{

    Student::ListenLecture();

    SetHP(GetHP()-1); //체력 1소모

    SetIQ(GetIQ()+GetSCnt()/2);//지력: scnt/2 증가

    air-=5;

    SetStress(GetStress()-air*3);// 스트레스: air*3 감소

    SetSCnt(0);

}

void PStudent::Sleep()

{

    Student::Sleep();

    SetHP(GetHP()+10); //체력 10회복   

    SetStress(GetStress()-5); //스트레스: 5감소

    SetSCnt(0);

}

void PStudent::Relax()

{

    Student::Relax();

    SetHP(GetHP()+8); //체력 8회복   

    SetStress(GetStress()-25); //스트레스: 25감소

    SetSCnt(0);

}

void PStudent::Drink()

{

    Student::Drink();

    SetHP(GetHP()+5); //체력 5 회복

    SetIQ(GetIQ()-3);//지력:  3 감소

    SetStress(GetStress()-2);//스트레스: 2감소

    SetSCnt(0);   

}

void PStudent::Sing()

{

    Student::Sing();

    SetHP(GetHP()-5); //체력 5 소모

    SetIQ(GetIQ()+2);//지력: 5증가

    SetStress(GetStress()-5);//스트레스: 5감소

    SetSCnt(0);   

}

void PStudent::View()const

{

    cout<<"운동 학생";

    Student::View();

    cout<<" air:"<<air<<endl;

}

void PStudent::Dance()

{   

    cout<<GetName()<<" 춤을 추다."<<endl;

    SetHP(GetHP()-5); //체력 5 소모

    SetIQ(GetIQ()+3);//지력: 3증가

    air++;//air 1증가   

}

 

--------------------------------------------------------------------------------

 

//SStudent.h

#pragma once

#include "Student.h"

class SStudent :

    public Student

{

    int dummy;

    int total_scnt;

public:   

    friend class StuFactory;

    virtual void Study();

    virtual void ListenLecture();

    virtual void Sleep();

    virtual void Relax();

    virtual void Drink();

    virtual void Sing();

    virtual void View()const;

    void Reading();

private:

    SStudent(string name); 

};

 

--------------------------------------------------------------------------------

 

//SStudent..cpp

#include "SStudent.h"

 

SStudent::SStudent(string name):Student(name)

{

    dummy = 0;//더미 뇌는 생성 시 0

    total_scnt = 0;

}

 

void SStudent::Study()

{

    Student::Study();

    SetHP(GetHP()-5);//체력 5소모

    SetIQ(GetIQ()+GetSCnt()+dummy);//지력: scnt+더미 뇌 증가

    SetStress(GetStress()-2);//스트레스: 2감소

    SetSCnt(GetSCnt()+1);

    total_scnt++;

    if(total_scnt%5 == 0)//더미 뇌는 공부한 회수가 5의 배수가 될 때마다 1씩 증가

    {

        dummy++;

    }

}

void SStudent::ListenLecture()

{

    Student::ListenLecture();

    SetHP(GetHP()-3); //체력 3소모

    SetIQ(GetIQ()+GetSCnt());//지력: scnt 증가

    SetStress(GetStress()+GetSCnt());// 스트레스: scnt증가

    SetSCnt(0);

}

void SStudent::Sleep()

{

    Student::Sleep();

    SetHP(GetHP()+10); //체력 10회복   

    SetStress(GetStress()-5); //스트레스: 5감소

    SetSCnt(0);

}

void SStudent::Relax()

{

    Student::Relax();

    SetHP(GetHP()+3); //체력 3회복   

    SetStress(GetStress()-25); //스트레스: 25감소

    SetSCnt(0);

}

void SStudent::Drink()

{

    Student::Drink();

    SetHP(GetHP()+5); //체력 5회복

    SetIQ(GetIQ()-10);//지력:  10감소

    SetStress(GetStress()+2);//스트레스: 2증가

    SetSCnt(0);   

}

void SStudent::Sing()

{

    Student::Sing();

    SetHP(GetHP()-10); //체력 10 소모

    SetIQ(GetIQ()-(5-GetSCnt()));//지력: 5-scnt감소

    SetStress(GetStress()+(5-GetSCnt()));//스트레스: 5-scnt증가

    SetSCnt(0);   

}

void SStudent::View()const

{

    cout<<"학사 학생";

    Student::View();

    cout<<" 더미 뇌:"<<dummy<<"연속으로 공부한 횟수:"<<total_scnt<<endl;

}

void SStudent::Reading()

{

    cout<<GetName()<<" 독서하다."<<endl;

    dummy++;//더미 뇌 1증가

    SetStress(GetStress()-5);//스트레스: 5감소

}

 

--------------------------------------------------------------------------------

 

//StuFactory.h

#pragma once

#include "SeqArray.h"

#include "Student.h"

class StuFactory

{

    SeqArray<Student *> base;

public:

    StuFactory(void);

    ~StuFactory(void);

    Student *MakeStudent(int stype,string name);//학생 생성

};

 

//StuFactory.cpp

#include "StuFactory.h"

#include "SStudent.h"

#include "MStudent.h"

#include "PStudent.h"

StuFactory::StuFactory(void)

{

}

StuFactory::~StuFactory(void)

{

    //보관 개수를 얻어온다.

    size_t size = base.GetSize();

    for(size_t i = 0; i<size; ++i)//i 0~size-1까지 증가

    {

        delete base[i];//학생 개체 소멸

    }

}

Student *StuFactory::MakeStudent(int stype,string name)//학생 생성

{

    Student *stu = 0;

    //stype에 따라 적절한 학생 개체 생성

    switch(stype)

    {

    case 1: stu = new SStudent(name); break;

    case 2: stu = new MStudent(name); break;

    case 3: stu = new PStudent(name); break;

    default: throw "학생 타입 범위를 벗어났습니다.";

    }

    base.PushBack(stu);//생성한 학생 개체를 컬렉션에 보관

    return stu;//생성한 학생 개체 반환

}

 

--------------------------------------------------------------------------------

 

//Place.h

#pragma once

#include "IComeBack.h"

#include "Man.h"

#include "SeqArray.h"

#include "ehglobal.h"

 

class Place

{

    IComeBack &ic;

    SeqArray<Man *> base;

public:

    Place(IComeBack &ic);

    ~Place(void);

    void Run();

    virtual void InStudent(Man *man);//유닛 이동

    virtual void View();//장소 정보 출력

protected:

    int SelectMenu();

    virtual void ViewMenu()const;

    void ComeBackStu();//학생 복귀

    virtual void DoItByKey(int key)=0;//키에 따라 기능 수행

    Man *SelectMan();//학생 선택

    size_t GetCount()const;//학생 수

    Man *GetAt(size_t index);//index 위치 학생 반환

private:

    void EraseMan(Man *man);//학생 제거

};

 

--------------------------------------------------------------------------------

 

//Place.cpp

#include "Place.h"

 

Place::Place(IComeBack &ic):ic(ic)

{

}

Place::~Place(void)

{

}

void Place::Run()

{

    int key = 0;

    while((key = SelectMenu())!=ESC)

    {

        if(key == F1)

        {

            ComeBackStu();//학생 복귀

        }

        else

        {

            DoItByKey(key);//키에 따라 기능 수행

        }

        cout<<"아무 키나 누르세요."<<endl;

        ehglobal::getkey();

    }

}

int Place::SelectMenu()

{

    ehglobal::clrscr();

    ViewMenu();

    return ehglobal::getkey();

}

void Place::ViewMenu()const

{

    cout<<"ESC:초점 종료"<<endl;

    cout<<"F1: 이에이치 나라로 학생 복귀"<<endl;

}

void Place::ComeBackStu()//유닛 복귀

{    

    Man *man = SelectMan();//이동할 유닛 선택   

    if(man == 0)

    {

        cout<<"잘못 선택하였습니다."<<endl;

        return;

    }

    EraseMan(man);//유닛 제거

    ic.ComeBack(man);//학생 복귀   

}

 

Man *Place::SelectMan()//유닛 선택

{

    cout<<"선택할 학생의 주민번호:";

    int pn=0;

    cin>>pn;

 

    size_t size = base.GetSize();//보관한 학생 수 구하기

    for(size_t i=0;i<size;++i)

    {

        if(base[i]->GetPN() == pn)//학생 주민번호와 입력한 주민번호가 같을 때

        {

            return base[i];

        }

    }

    return 0;

}

void Place::EraseMan(Man *man)//유닛 제거

{

    size_t size = base.GetSize();//보관한 학생 수 구하기

    for(size_t i=0;i<size;++i)

    {

        if(base[i]==man)//보관한 학생과 입력 인자로 받은 학생이 같을 때

        {

            base.RemoveAt(i);//해당 인덱스에 보관한 개체 지우기

            return;

        }

    }   

}

void Place::InStudent(Man *man)//유닛 이동

{

    base.PushBack(man);

}

 

void Place::View()//장소 정보 출력

{

    size_t size = base.GetSize();//보관 개수를 얻어온다.

    for(size_t i = 0; i<size; ++i)//i 0~size-1까지 증가

    {

        base[i]->View();//학생 정보 출력

    }   

}

 

size_t Place::GetCount()const//학생 수

{

    return base.GetSize();

}

Man *Place::GetAt(size_t index)//index 위치 학생 반환

{

    return base[index];

}

 

--------------------------------------------------------------------------------

 

//Downtown.h

#pragma once

#include "Place.h"

#include "PStudent.h"

#include "IPlay.h"

class Downtown:

        public Place

{

public:

    Downtown(IComeBack &ic);

    ~Downtown(void);

    virtual void View();//장소 정보 출력

private:

    virtual void ViewMenu()const;  //메뉴 출력

    virtual void DoItByKey(int key);//키에 따라 기능 수행

    void Party();//파티

    void GoToSing();//노래방으로 가기

};

 

--------------------------------------------------------------------------------

 

//Downtown.cpp

#include "Downtown.h"

Downtown::Downtown(IComeBack &ic):Place(ic)

{

}

Downtown::~Downtown(void)

{

}

void Downtown::ViewMenu()const  //메뉴 출력

{

    Place::ViewMenu();

    cout<<"F2: 파티"<<endl;

    cout<<"F3: 노래방으로 가기"<<endl;

}

void Downtown::DoItByKey(int key)//키에 따라 기능 수행

{

    switch(key)

    {

    case F2: Party(); break; //파티

    case F3: GoToSing(); break; //노래방으로 가기

    default: cout<<"잘못 선택하였습니다."<<endl;

    }

}

void Downtown::Party()//파티

{

    cout<<"파티"<<endl;

 

    size_t max = GetCount();//학생 수 구하기

    for(size_t index = 0; index<max; ++index)

    {

        IPlay *iplay = dynamic_cast<IPlay *>(GetAt(index));

        if(iplay)

        {

            iplay->Drink();

        }

        else

        {

            throw "장소에 있는 개체가 IPlay 형식으로 하향 캐스팅을 할 수 없습니다.";

        }

    }

}

void Downtown::GoToSing()//노래방으로 가기

{

    cout<<"노래방으로 가기"<<endl;

    Man *man = SelectMan();

    if(man==0)

    {

        cout<<"잘못 선택하였습니다."<<endl;

        return;

    }

    IPlay *iplay = dynamic_cast<IPlay *>(man);

    if(iplay)

    {

        iplay->Sing();

        PStudent *pstu = dynamic_cast<PStudent *>(iplay);

        if(pstu)

        {

            pstu->Dance();

        }

    }

    else

    {

        throw "IPlay 형식으로 하향 캐스팅을 하지 못하였습니다.";

    }

}

void Downtown::View()//장소 정보 출력

{

    cout<<"다운타운 "<<endl;

    Place::View();

}

 

--------------------------------------------------------------------------------

 

//School.h

#pragma once

#include "Place.h"

#include "IStudy.h"

#include "SStudent.h"

class School :

    public Place

{

    int last_snum;//가장 최근에 부여한 학생 번호

public:

    School(IComeBack &ic);

    ~School(void);

    virtual void InStudent(Man *man);//유닛 이동

    virtual void View();//장소 정보 출력

private:

    virtual void ViewMenu()const;  //메뉴 출력

    virtual void DoItByKey(int key);//키에 따라 기능 수행       

    void StartLecture();//강의 시작

    void GoToLibrary();//도서관으로 가기

};

 

--------------------------------------------------------------------------------

 

//School.cpp

#include "School.h"

School::School(IComeBack &ic):Place(ic)

{

    last_snum = 0;

}

School::~School(void)

{

}

void School::ViewMenu()const  //메뉴 출력

{

    Place::ViewMenu();

    cout<<"F2: 강의 시작"<<endl;

    cout<<"F3: 도서관으로 가기"<<endl;

}

void School::DoItByKey(int key)//키에 따라 기능 수행

{

    switch(key)

    {

    case F2: StartLecture(); break; //강의 시작

    case F3: GoToLibrary(); break; //도서관으로 가기

    default: cout<<"잘못 선택하였습니다."<<endl;

    }

}

void School::StartLecture()//강의 시작

{

    cout<<"강의 시작"<<endl;

    size_t max = GetCount();//학생 수 구하기

    for(size_t index = 0; index<max; ++index)

    {

        IStudy *istudy = dynamic_cast<IStudy *>(GetAt(index));

        if(istudy)

        {

            istudy->ListenLecture();

        }

        else

        {

            throw "장소에 있는 개체가 IStudy 형식으로 하향 캐스팅을 할 수 없습니다.";

        }

    }

}

void School::GoToLibrary()//도서관으로 가기

{

    cout<<"도서관으로 가기"<<endl;

    Man *man = SelectMan();

    if(man==0)

    {

        cout<<"잘못 선택하였습니다."<<endl;

        return;

    }

    IStudy *istudy = dynamic_cast<IStudy *>(man);

    if(istudy)

    {

        istudy->Study();

        SStudent *sstu = dynamic_cast<SStudent *>(istudy);

        if(sstu)

        {

            sstu->Reading();

        }

    }

    else

    {

        throw "IStudy 형식으로 하향 캐스팅을 하지 못하였습니다.";

    }

}

void School::InStudent(Man *man)//유닛 이동

{

    Place::InStudent(man);//기반 형식 Place InStudent를 호출(컬렉션에 보관)

    if(man->GetSNum()==0)//처음 온 학생이면

    {

        last_snum++;

        man->SetSNum(last_snum);//학번 부여       

    }

}

void School::View()//장소 정보 출력

{

    cout<<"학교 "<<endl;

    Place::View();

}

 

--------------------------------------------------------------------------------

 

//Village.h

#pragma once

#include "Place.h"

#include "IRelax.h"

#include "MStudent.h"

class Village :

    public Place

{

public:

    Village(IComeBack &ic);

    ~Village(void);

    virtual void View();//장소 정보 출력

private:

    virtual void ViewMenu()const;  //메뉴 출력

    virtual void DoItByKey(int key);//키에 따라 기능 수행

    void TurnOff();//소등

    void GoToLivingRoom();//거실로 가기

};

 

--------------------------------------------------------------------------------

 

//Village.cpp

#include "Village.h"

Village::Village(IComeBack &ic):Place(ic)

{

}

Village::~Village(void)

{

}

void Village::ViewMenu()const  //메뉴 출력

{

    Place::ViewMenu();

    cout<<"F2: 소등"<<endl;

    cout<<"F3: 거실로 가기"<<endl;

}

void Village::DoItByKey(int key)//키에 따라 기능 수행

{

    switch(key)

    {

    case F2: TurnOff(); break; //강의 시작

    case F3: GoToLivingRoom(); break; //도서관으로 가기

    default: cout<<"잘못 선택하였습니다."<<endl;

    }

}

void Village::TurnOff()//소등

{

    cout<<"소등"<<endl;

 

    size_t max = GetCount();//학생 수 구하기

    for(size_t index = 0; index<max; ++index)

    {

        IRelax *irelax = dynamic_cast<IRelax *>(GetAt(index));

        if(irelax)

        {

            irelax->Sleep();

        }

        else

        {

            throw "장소에 있는 개체가 IRelax 형식으로 하향 캐스팅을 할 수 없습니다.";

        }

    }

}

void Village::GoToLivingRoom()//거실로 가기

{

    cout<<"거실로 가기"<<endl;

 

    Man *man = SelectMan();

    if(man==0)

    {

        cout<<"잘못 선택하였습니다."<<endl;

        return;

    }

    IRelax *irelax = dynamic_cast<IRelax *>(man);

    if(irelax)

    {

        irelax->Relax();

        MStudent *mstu = dynamic_cast<MStudent *>(irelax);

        if(mstu)

        {

            mstu->Travel();

        }

    }

    else

    {

        throw "IRelax 형식으로 하향 캐스팅을 하지 못하였습니다.";

    }

}

void Village::View()//장소 정보 출력

{

    cout<<"주거지 "<<endl;

    Place::View();

}

 

--------------------------------------------------------------------------------

 

//EhNara.h

#pragma once

#include "SeqArray.h"

#include "StuFactory.h"

#include "IComeBack.h"

#include "Place.h"

#include "Student.h"

class EhNara:public IComeBack

{

    static EhNara app;//단일체

    enum PIndex//장소 인덱스

    {

        PI_SCHOOL, PI_DOWNTOWN, PI_VILLAGE, PI_MAX

    };

 

    Place *places[PI_MAX];

    StuFactory *sf;

    SeqArray<Student *> base;

public:

    static void Start();//응용 시작 - 진입점에서 호출하는 정적 메서드

    virtual void ComeBack(Man *man);//학생 복귀

private:

    EhNara(void);

    ~EhNara(void);

    void Initialize(); //초기화

    void Run(); //사용자와 상호 작용

    void Exit(); //해제화

 

    int SelectMenu(); //메뉴 출력 및 선택

    void MakeStudent(); //학생 생성

    void MoveFocus(); //초점 이동

    void MoveStudent(); //학생 이동

    void ViewAll(); //전체 보기

 

    Place *SelectPlace();//장소 선택

    Student *SelectStudent();//이동할 학생 선택   

    void EraseStudent(Student *stu);//학생 제거   

    void ViewStudents();//전체 학생 정보 보기

    void ViewPlaces();//전체 장소 정보 보기

};

 

--------------------------------------------------------------------------------

 

//EhNara.cpp

#include "EhNara.h"

#include "School.h"

#include "Downtown.h"

#include "Village.h"

EhNara EhNara::app;//단일체

void EhNara::Start()//응용 시작 - 진입점에서 호출하는 정적 메서드

{

    app.Initialize();

    app.Run();

    app.Exit();

}

EhNara::EhNara(void)

{

}

EhNara::~EhNara(void)

{

}

void EhNara::Initialize()

{

     sf = new StuFactory();//학생 공장 생성

    //장소 개체 생성

    places[PI_SCHOOL] = new School(*this);

    places[PI_DOWNTOWN] = new Downtown(*this);

    places[PI_VILLAGE] = new Village(*this);

}

 

void EhNara::Run()

{

    int key = 0;

    while((key = SelectMenu())!=ESC)

    {

        switch(key)

        {

            case F1: MakeStudent(); break;

            case F2: MoveFocus();  break;

            case F3: MoveStudent(); break;

            case F4: ViewAll(); break;

            default: cout<<"잘못 선택하였습니다."<<endl; break;

        }

        cout<<"아무 키나 누르세요."<<endl;

        ehglobal::getkey();

    }

}

 

void EhNara::Exit() //해제화

{

    for(int i = 0; i<PI_MAX; i++)//모든 장소 개체 해제

    {

        delete places[i];

    }

    delete sf;//학생 공장 개체 소멸

}

 

int EhNara::SelectMenu() //메뉴 출력 및 선택

{

    ehglobal::clrscr();

    cout<<"이에이치 나라 메뉴"<<endl;

    cout<<"F1: 학생 생성 F2: 초점 이동 F3: 학생 이동 F4: 전체 보기 ESC: 프로그램 종료"<<endl;

    return ehglobal::getkey();

}

void EhNara::MakeStudent() //학생 생성

{   

    cout<<"생성할 학생 유형을 선택하세요. [1]:학사학생 [2]:마법학생 [3]:운동학생"<<endl;

    int stype;

    cin>>stype;

    if((stype<1)||(stype>3))//잘못 선택하였을 때

    {

        cout<<"잘못 선택하였습니다."<<endl;

        return;

    }

    cout<<"학생 이름:";

    string name;

    cin>>name;

    Student *stu = sf->MakeStudent(stype,name);//학생 생성 요청

    base.PushBack(stu);//생성한 학생 보관

}

void EhNara::MoveFocus() //초점 이동

{

    Place *place = SelectPlace();//장소 선택

    if(place==0)

    {

        cout<<"잘못 선택하였습니다."<<endl;

        return;

    }

    place->Run();//장소의 상호 작용

}

void EhNara::MoveStudent() //학생 이동

{

    Place *place = SelectPlace();//이동할 장소 선택

    if(place==0)//잘못 선택하였을 때

    {

        cout<<"잘못 선택하였습니다."<<endl;

        return;

    }

    Student *stu = SelectStudent();//이동할 학생 선택

    if(stu == 0)

    {

        cout<<"잘못 선택하였습니다."<<endl;

        return;

    }

    EraseStudent(stu);//학생 제거

    place->InStudent(stu);//선택한 장소로 학생 이동

}

void EhNara::ViewAll() //전체 보기

{

    ViewStudents();//전체 학생 정보 보기

    ViewPlaces();//전체 장소 정보 보기

}

void EhNara::ViewStudents()//전체 학생 정보 보기

{   

    size_t size = base.GetSize();//보관 개수를 얻어온다.

    for(size_t i = 0; i<size; ++i)//i 0~size-1까지 증가

    {

        base[i]->View();//학생 정보 출력

    }

}

void EhNara::ViewPlaces()//전체 장소 정보 보기

{

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

    {

        places[i]->View();//장소 정보 출력

    }

}

Place *EhNara::SelectPlace()//장소 선택

{

    cout<<"장소를 선택하세요."<<endl;

    cout<<"1: 학교 2: 다운타운 3: 주거지"<<endl;

    int pi=0;

    cin>>pi;

    if((pi<1)&&(pi>PI_MAX))//유효한 선택이 아닐 때

    {

        return 0;

    }

    return places[pi-1];

}

Student *EhNara::SelectStudent()//이동할 학생 선택   

{

    cout<<"선택할 학생의 주민번호:";

    int pn=0;

    cin>>pn;

 

    size_t size = base.GetSize();//보관한 학생 수 구하기

    for(size_t i=0;i<size;++i)

    {

        if(base[i]->GetPN() == pn)//학생 주민번호와 입력한 주민번호가 같을 때

        {

            return base[i];

        }

    }

    return 0;

}

void EhNara::EraseStudent(Student *stu)//학생 제거

{

    size_t size = base.GetSize();//보관한 학생 수 구하기

    for(size_t i=0;i<size;++i)

    {

        if(base[i]==stu)//보관한 학생과 입력 인자로 받은 학생이 같을 때

        {

            base.RemoveAt(i);//해당 인덱스에 보관한 개체 지우기

            return;

        }

    }   

}

void EhNara::ComeBack(Man *man)//학생 복귀

{

    Student *stu = dynamic_cast<Student *>(man);

    if(stu == 0)

    {

        throw "Student 형식이 아닙니다.";

    }

    base.PushBack(stu);//순차 보관

}

 

--------------------------------------------------------------------------------

 

//Program.cpp

#include "EhNara.h"

int main()

{

    EhNara::Start();

    return 0;

}

 

반응형