[C++] 87. 최종 실습 - 소스 코드
//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 ⁣
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;
}
'언어 자료구조 알고리즘 > 디딤돌 C++' 카테고리의 다른 글
[C++] 86. 최종 실습 - 다이어그램 (0) | 2016.05.01 |
---|---|
[C++] 85. 최종 실습 - 노래방 가기 (0) | 2016.05.01 |
[C++] 84. 최종 실습 - 파티 (0) | 2016.05.01 |
[C++] 83. 최종 실습 - 거실로 가기 (0) | 2016.05.01 |
[C++] 82. 최종 실습 - 소등 (0) | 2016.05.01 |
[C++] 81. 최종 실습 - 도서관 가기 (0) | 2016.05.01 |
[C++] 80. 최종 실습 - 강의 시작 (0) | 2016.05.01 |
[C++] 79. 최종 실습 - 학생 복귀 (0) | 2016.05.01 |
[C++] 78. 최종 실습 - 전체 보기 (0) | 2016.05.01 |
[C++] 77. 최종 실습 - 학생 이동 (0) | 2016.05.01 |