fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <list>
  4. #include <vector>
  5. #include <random>
  6. #include <algorithm>
  7.  
  8. using namespace std;
  9.  
  10. enum eJob
  11. {
  12. eVillager = 1, // 마을사람
  13. eSeer = 2, // 점쟁이
  14. eMedium = 4, // 영매자
  15. eGuard = 8, // 사냥꾼
  16. eFreemasons = 16, // 초능
  17. eWerewolf = 32, // 인랑
  18. ePossessed = 64, // 광인
  19. };
  20.  
  21. struct ObjDelete
  22. {
  23. template <typename T>
  24. void operator () (T& Temp)
  25. {
  26. if (Temp)
  27. {
  28. delete Temp;
  29. Temp = nullptr;
  30. }
  31. }
  32. };
  33.  
  34. enum eMaxApply
  35. {
  36. eFirst,
  37. eSecond,
  38. eMaxApplyEnd
  39. };
  40.  
  41. struct tagApply
  42. {
  43. int iApply;
  44. int iWeight;
  45. int iCoin;
  46.  
  47. tagApply() : iApply(0), iWeight(0), iCoin(0) {}
  48. };
  49. class CMentor
  50. {
  51. private:
  52. string m_szMyName;
  53. tagApply m_tApply[eMaxApplyEnd];
  54.  
  55. string m_szMenteeName;
  56.  
  57. private:
  58. static bool m_bFreemasons; // 초능이 있는지 없는지
  59.  
  60. private:
  61. static int countBit(int value);
  62. public:
  63.  
  64. const string& GetMyName() { return m_szMyName; }
  65. const tagApply& GetApply(eMaxApply _eType) { return m_tApply[_eType]; }
  66. const string& GetMenteeName() { return m_szMenteeName; }
  67.  
  68. bool SetApply(const int _iJob, eMaxApply _eType);
  69. void SetMenteeName(const string& _szName) { m_szMenteeName = _szName; }
  70.  
  71. public:
  72. void static SetFreemason(bool _bFreemason) { m_bFreemasons = _bFreemason; }
  73.  
  74. public:
  75. CMentor(const string& _szName, int _FirstJob = 0, int _SecondJob = 0);
  76. ~CMentor();
  77. };
  78.  
  79. bool CMentor::m_bFreemasons = false;
  80.  
  81. CMentor::CMentor(const string& _szName, int _FirstJob /*= 0*/, int _SecondJob /*= 0*/)
  82. : m_szMyName(_szName)
  83. , m_szMenteeName("None")
  84. {
  85. if (_FirstJob)
  86. SetApply(_FirstJob, eFirst);
  87. if (_SecondJob)
  88. SetApply(_SecondJob, eSecond);
  89. }
  90.  
  91. CMentor::~CMentor()
  92. {
  93. }
  94.  
  95. bool CMentor::SetApply(const int _iJob, eMaxApply _eType)
  96. {
  97. // 2017/01/16 Moo : 초능이 없는 마을에서 초능 지원하면 뺌
  98. if (m_bFreemasons == true)
  99. {
  100. m_tApply[_eType].iApply = _iJob & ~eFreemasons;
  101. }
  102. else
  103. m_tApply[_eType].iApply = _iJob;
  104.  
  105. m_tApply[_eType].iWeight = countBit(_iJob);
  106. // 2017/01/16 Moo : 100의 코인값을 비중으로 나눈다.
  107. m_tApply[_eType].iCoin = 100 / m_tApply[_eType].iWeight;
  108. return true;
  109. }
  110. int CMentor::countBit(int value)
  111. {
  112. int count = 0;
  113.  
  114. while (value)
  115. {
  116. count += (value & 1);
  117. value = value >> 1;
  118. }
  119.  
  120. return count;
  121. }
  122.  
  123. struct tagMentee
  124. {
  125. string szMyName;
  126. eJob eMyJob;
  127. string szMentorName;
  128. };
  129.  
  130. struct tagRandom
  131. {
  132. int iValue;
  133. string szMentorName;
  134.  
  135. tagRandom(const int& _value, const string& _szName) : iValue(_value), szMentorName(_szName)
  136. {}
  137. };
  138.  
  139. class CMentor;
  140. class CMenMenMgr
  141. {
  142. private:
  143. static CMenMenMgr* m_pInst;
  144.  
  145. public:
  146. static inline CMenMenMgr* GetInst()
  147. {
  148. if (m_pInst == nullptr)
  149. m_pInst = new CMenMenMgr;
  150.  
  151. return m_pInst;
  152. }
  153. void inline Destroy()
  154. {
  155. if (m_pInst)
  156. {
  157. delete m_pInst;
  158. m_pInst = nullptr;
  159. }
  160. }
  161. private:
  162. vector<CMentor*> m_vecReadyMentor;
  163. vector<CMentor*> m_vecCompleteMentor;
  164.  
  165. vector<tagMentee*> m_vecReadyMentee;
  166. vector<tagMentee*> m_vecCompleteMentee;
  167.  
  168. vector<tagRandom> m_vecRandom;
  169.  
  170. public:
  171. bool Init();
  172.  
  173. void PreRender();
  174.  
  175. void Matching();
  176. void Render();
  177. private:
  178. eJob GetMyJob(string _strJob);
  179. string GetMyJob(const eJob _ejob);
  180. private:
  181. CMenMenMgr();
  182. ~CMenMenMgr();
  183. };
  184.  
  185. int g_iSeed = 19880429;
  186. int g_iSeed_second = 26;
  187.  
  188. CMenMenMgr* CMenMenMgr::m_pInst = nullptr;
  189. string g_Mentee[15][2] =
  190. {
  191. { "ㅇㅁㅈ", "인랑" },
  192. { "기다린", "인랑" },
  193. { "반월", "광인" },
  194. { "taewan", "초능력자" },
  195. { "닥터", "점쟁이" },
  196. { "맬리", "영매자" },
  197. { "piece", "사냥꾼" },
  198. { "지나가던 정신병자", "초능력자" },
  199. { "어린씨앗", "마을사람" },
  200. { "네르", "마을사람" },
  201. { "프리지아", "마을사람" },
  202. { "뤼넨", "마을사람" },
  203. { "짜장면", "마을사람" },
  204. };
  205.  
  206. CMentor g_Mentor[] =
  207. {
  208. CMentor("필그림", eVillager, eFreemasons),
  209. CMentor("믹형", eWerewolf, ePossessed),
  210. CMentor("암흑시대", eFreemasons, eVillager),
  211. CMentor("bandy", eVillager),
  212. CMentor("빵글이", ePossessed, eWerewolf),
  213. CMentor("아카유키", eGuard),
  214. CMentor("앙팡", eGuard | eWerewolf | eFreemasons),
  215. CMentor("루이", eVillager | eGuard | eFreemasons),
  216. CMentor("자칼린", eVillager),
  217. CMentor("월광", eWerewolf),
  218. CMentor("크레센트", eWerewolf, eVillager),
  219. CMentor("Splitmilk", eVillager | eGuard, eMedium),
  220. CMentor("졸린개")
  221. };
  222.  
  223. CMenMenMgr::CMenMenMgr()
  224. {
  225.  
  226. }
  227.  
  228.  
  229. CMenMenMgr::~CMenMenMgr()
  230. {
  231. for_each(m_vecReadyMentee.begin(), m_vecReadyMentee.end(), ObjDelete());
  232. m_vecReadyMentee.clear();
  233. for_each(m_vecReadyMentor.begin(), m_vecReadyMentor.end(), ObjDelete());
  234. m_vecReadyMentor.clear();
  235.  
  236. for_each(m_vecCompleteMentee.begin(), m_vecCompleteMentee.end(), ObjDelete());
  237. m_vecCompleteMentee.clear();
  238. for_each(m_vecCompleteMentor.begin(), m_vecCompleteMentor.end(), ObjDelete());
  239. m_vecCompleteMentor.clear();
  240. }
  241.  
  242. bool CMenMenMgr::Init()
  243. {
  244. default_random_engine generator(g_iSeed);
  245.  
  246. for (int i = 0; i < 15; ++i)
  247. {
  248. if (g_Mentee[i][0] == "")
  249. break;
  250.  
  251. tagMentee* pMentee = new tagMentee;
  252. pMentee->szMyName = g_Mentee[i][0];
  253. pMentee->eMyJob = GetMyJob(g_Mentee[i][1]);
  254.  
  255. m_vecReadyMentee.push_back(pMentee);
  256. }
  257. shuffle(m_vecReadyMentee.begin(), m_vecReadyMentee.end(), generator);
  258.  
  259. for (auto var : g_Mentor)
  260. {
  261. CMentor *pMentor = new CMentor(var);
  262. m_vecReadyMentor.push_back(pMentor);
  263. }
  264. shuffle(m_vecReadyMentor.begin(), m_vecReadyMentor.end(), generator);
  265. return true;
  266. }
  267.  
  268. void CMenMenMgr::PreRender()
  269. {
  270. cout << "======ReadyMentee======" << endl;
  271. for (auto var : m_vecReadyMentee)
  272. {
  273. cout << var->szMyName << "\t\t" << GetMyJob(var->eMyJob) << endl;
  274. }
  275. cout << "=================" << endl;
  276.  
  277. cout << "======ReadyMentor======" << endl;
  278. for (auto var : m_vecReadyMentor)
  279. {
  280. cout << var->GetMyName() << "\t\t" << endl;
  281. }
  282. cout << "=================" << endl;
  283. }
  284.  
  285. void CMenMenMgr::Matching()
  286. {
  287. default_random_engine generator(g_iSeed_second);
  288. cout << "===============Matching===============" << endl;
  289.  
  290. for (int eCount = eFirst; eCount < eMaxApplyEnd; ++eCount)
  291. {
  292. for (auto Mentee = m_vecReadyMentee.begin(); Mentee != m_vecReadyMentee.end();)
  293. {
  294. m_vecRandom.clear();
  295. int iCurrentCoin = 0;
  296. eJob MenteeJob = (*Mentee)->eMyJob;
  297.  
  298. for (auto Mentor : m_vecReadyMentor)
  299. {
  300. // 2017/01/19 Moo : 밴...
  301. if (Mentor->GetMyName() == "빵글이")
  302. {
  303. if ((*Mentee)->szMyName == "반월")
  304. continue;
  305. }
  306. // 2017/01/17 Moo : 해당한다면 넣는다
  307. if (Mentor->GetApply(eMaxApply(eCount)).iApply & MenteeJob)
  308. {
  309. tagRandom tempRandom(iCurrentCoin + Mentor->GetApply(eMaxApply(eCount)).iCoin, Mentor->GetMyName());
  310. iCurrentCoin += Mentor->GetApply(eMaxApply(eCount)).iCoin;
  311. m_vecRandom.push_back(tempRandom);
  312. }
  313. }
  314. if (iCurrentCoin == 0)
  315. {
  316. ++Mentee;
  317. continue;
  318. }
  319. // 2017/01/17 Moo : 다 넣음.
  320. int iRandom = generator() % iCurrentCoin;
  321. string TargetString = "";
  322. for (auto Random : m_vecRandom)
  323. {
  324. if (Random.iValue > iRandom)
  325. {
  326. TargetString = Random.szMentorName;
  327. break;
  328. }
  329. }
  330. if (TargetString != "")
  331. {
  332. (*Mentee)->szMentorName = TargetString;
  333. for (auto iter = m_vecReadyMentor.begin(); iter != m_vecReadyMentor.end(); ++iter)
  334. {
  335. if ((*iter)->GetMyName() == TargetString)
  336. {
  337. (*iter)->SetMenteeName((*Mentee)->szMyName);
  338. m_vecCompleteMentor.push_back(*iter);
  339. m_vecReadyMentor.erase(iter);
  340. break;
  341. }
  342. }
  343. m_vecCompleteMentee.push_back(*Mentee);
  344. Mentee = m_vecReadyMentee.erase(Mentee);
  345. }
  346. else
  347. {
  348. ++Mentee;
  349. }
  350. }
  351. }
  352. // 2017/01/20 Moo : 다시 섞음
  353. shuffle(m_vecReadyMentee.begin(), m_vecReadyMentee.end(), generator);
  354. shuffle(m_vecReadyMentor.begin(), m_vecReadyMentor.end(), generator);
  355. for (auto Mentee = m_vecReadyMentee.begin(); Mentee != m_vecReadyMentee.end();)
  356. {
  357. (*Mentee)->szMentorName = (m_vecReadyMentor[0])->GetMyName();
  358. (m_vecReadyMentor[0])->SetMenteeName((*Mentee)->szMyName);
  359. m_vecCompleteMentee.push_back(*Mentee);
  360. m_vecCompleteMentor.push_back(m_vecReadyMentor[0]);
  361.  
  362. Mentee = m_vecReadyMentee.erase(Mentee);
  363. m_vecReadyMentor.erase(m_vecReadyMentor.begin());
  364. }
  365. }
  366.  
  367. void CMenMenMgr::Render()
  368. {
  369. cout << "======CompleteMentee======" << endl;
  370. for (auto var : m_vecCompleteMentee)
  371. {
  372. cout << var->szMyName << "\t\t" << GetMyJob(var->eMyJob) << "\t\t" << var->szMentorName << endl;
  373. }
  374. cout << "=================" << endl;
  375.  
  376. cout << "======CompleteMentor======" << endl;
  377. for (auto var : m_vecCompleteMentor)
  378. {
  379. cout << var->GetMyName() << "\t\t" << var->GetMenteeName() << endl;
  380. }
  381. cout << "=================" << endl;
  382. }
  383.  
  384. eJob CMenMenMgr::GetMyJob(string _strJob)
  385. {
  386. if (_strJob == "마을사람")
  387. return eVillager;
  388. else if (_strJob == "점쟁이")
  389. return eSeer;
  390. else if (_strJob == "영매자")
  391. return eMedium;
  392. else if (_strJob == "사냥꾼")
  393. return eGuard;
  394. else if (_strJob == "초능력자")
  395. {
  396. CMentor::SetFreemason(true);
  397. return eFreemasons;
  398. }
  399. else if (_strJob == "인랑")
  400. return eWerewolf;
  401. else if (_strJob == "광인")
  402. return ePossessed;
  403.  
  404. cout << "Error!" << endl;
  405. return eVillager;
  406. }
  407.  
  408. string CMenMenMgr::GetMyJob(const eJob _ejob)
  409. {
  410. string strName;
  411. if (_ejob == eVillager)
  412. strName = "마을사람";
  413. else if (_ejob == eSeer)
  414. strName = "점쟁이";
  415. else if (_ejob == eMedium)
  416. strName = "영매자";
  417. else if (_ejob == eGuard)
  418. strName = "사냥꾼";
  419. else if (_ejob == eFreemasons)
  420. strName = "초능력자";
  421. else if (_ejob == eWerewolf)
  422. strName = "인랑";
  423. else if (_ejob == ePossessed)
  424. strName = "광인";
  425.  
  426. return strName;
  427. }
  428.  
  429.  
  430. int main() {
  431. // your code goes here
  432. CMenMenMgr::GetInst()->Init();
  433.  
  434. CMenMenMgr::GetInst()->PreRender();
  435. CMenMenMgr::GetInst()->Matching();
  436.  
  437. CMenMenMgr::GetInst()->PreRender();
  438. CMenMenMgr::GetInst()->Render();
  439. CMenMenMgr::GetInst()->Destroy();
  440. return 0;
  441. }
Success #stdin #stdout 0s 3484KB
stdin
Standard input is empty
stdout
======ReadyMentee======
ㅇㅁㅈ		인랑
지나가던 정신병자		초능력자
기다린		인랑
짜장면		마을사람
반월		광인
닥터		점쟁이
taewan		초능력자
어린씨앗		마을사람
프리지아		마을사람
뤼넨		마을사람
맬리		영매자
네르		마을사람
piece		사냥꾼
=================
======ReadyMentor======
빵글이		
크레센트		
월광		
Splitmilk		
루이		
bandy		
암흑시대		
아카유키		
졸린개		
믹형		
앙팡		
자칼린		
필그림		
=================
===============Matching===============
======ReadyMentee======
=================
======ReadyMentor======
=================
======CompleteMentee======
ㅇㅁㅈ		인랑		크레센트
지나가던 정신병자		초능력자		앙팡
기다린		인랑		월광
짜장면		마을사람		필그림
taewan		초능력자		암흑시대
어린씨앗		마을사람		자칼린
프리지아		마을사람		bandy
뤼넨		마을사람		Splitmilk
네르		마을사람		루이
piece		사냥꾼		아카유키
반월		광인		믹형
닥터		점쟁이		빵글이
맬리		영매자		졸린개
=================
======CompleteMentor======
크레센트		ㅇㅁㅈ
앙팡		지나가던 정신병자
월광		기다린
필그림		짜장면
암흑시대		taewan
자칼린		어린씨앗
bandy		프리지아
Splitmilk		뤼넨
루이		네르
아카유키		piece
믹형		반월
빵글이		닥터
졸린개		맬리
=================