Advertisement
Guest User

Untitled

a guest
Nov 13th, 2018
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.07 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <conio.h>
  4.  
  5. #define TRUE 1
  6. #define FALSE 0
  7.  
  8. #define MAX_UNIT_WAITING 5 //덱 하나당 최대 적재개수
  9. #define COUNT_BARRACKS 5 //배럭의 수
  10.  
  11. //유닛유형
  12. #define MARINE 1
  13. #define FIREBAT 2
  14. #define GHOST 3
  15. #define MEDIC 4
  16.  
  17. typedef struct DequeNode { // 노드의 타입
  18. int type; //유닛유형
  19. int lefttime; //남은시간
  20. struct DequeNode *llink;
  21. struct DequeNode *rlink;
  22. } DequeNode;
  23.  
  24. typedef struct DequeType { // 덱의 타입
  25. DequeNode *head;
  26. DequeNode *tail;
  27. } DequeType;
  28.  
  29. //배럭 구조체
  30. typedef struct BARRACKS {
  31. int count; //전체 대기열이 어느만큼 채워져 있는지 알기위한 변수
  32. DequeType unitdeque[COUNT_BARRACKS];
  33. } BARRACKS;
  34.  
  35. //
  36. void error(char *message)
  37. {
  38. fprintf(stderr, "%s\n", message);
  39. exit(1);
  40. }
  41. //
  42. void init(DequeType *dq,BARRACKS *br)
  43. {
  44. dq->head = dq->tail = NULL;
  45. br->count = 0;
  46. }
  47. DequeType *create_deque() {
  48. DequeType *dq;
  49. dq = (DequeType *)malloc(sizeof(DequeType));
  50. dq->head = NULL;
  51. dq->tail = NULL;
  52. return dq;
  53. }
  54. //남은시간은 마린, 파이어뱃을 2, 고스트, 메딕을 3으로 계산
  55. int lefttime_calc(int type) {
  56. switch (type)
  57. {
  58. case MARINE:
  59. return 2;
  60. break;
  61. case FIREBAT:
  62. return 2;
  63. break;
  64. case MEDIC:
  65. return 3;
  66. break;
  67. case GHOST:
  68. return 3;
  69. break;
  70. default:
  71. break;
  72. }
  73. }
  74. void unit_display(int unit)
  75. {
  76. switch (unit)
  77. {
  78. case 1:
  79. printf("마린");
  80. break;
  81. case 2:
  82. printf("파이어뱃");
  83. break;
  84. case 3:
  85. printf("고스트");
  86. break;
  87. case 4:
  88. printf("메딕");
  89. break;
  90. default:
  91. break;
  92. }
  93. }
  94. //
  95. int is_empty(DequeType *dq)
  96. {
  97. if (dq->head == NULL) return TRUE;
  98. else return FALSE;
  99. }
  100.  
  101. //유닛생산을 완료할 경우 덱의 Front를 제거
  102. void delete_front(BARRACKS *br)
  103. {
  104. int item;
  105. int i;
  106. DequeNode *removed_node;
  107. for (i = 0; i < COUNT_BARRACKS; i++) {
  108. DequeNode *temp = br->unitdeque[i].head;
  109. if (temp == NULL)
  110. break;
  111. else if (temp->lefttime == 0) {
  112.  
  113. removed_node = br->unitdeque[i].head; // 삭제할 노드
  114. item = removed_node->type; // 데이터 추출
  115. printf("배럭%d에서 ", i);
  116. unit_display(item);
  117. printf("의 생산이 완료됐습니다.");
  118. br->unitdeque[i].head = br->unitdeque[i].head->rlink; // 헤드 포인터 변경
  119. free(removed_node); // 메모리 공간 반납
  120. if (br->unitdeque[i].head == NULL) // 공백상태이면
  121. br->unitdeque[i].tail = NULL;
  122. else // 공백상태가 아니면
  123. {
  124. br->unitdeque[i].head = br->unitdeque[i].head->rlink;
  125. br->unitdeque[i].head->llink = NULL;
  126. }
  127. }
  128. else break;
  129. }
  130.  
  131. }
  132.  
  133. //완료된 유닛 출력필요(생산된 누적 유닛수는 출력할 필요없음)
  134.  
  135.  
  136. //대기열에 유닛추가, type에 따라 lefttime 지정
  137. void add_rear(BARRACKS *br,int type,int index)
  138. {
  139.  
  140. DequeNode *new_node = (DequeNode *)malloc(sizeof(DequeNode));
  141. new_node->type = type;
  142. new_node->lefttime = lefttime_calc(type);
  143. if (is_empty(&br->unitdeque[index])) {
  144. br->unitdeque[index].head = new_node;
  145. br->unitdeque[index].tail = new_node;
  146. return;
  147. }
  148. else {
  149. br->unitdeque[index].tail->rlink = new_node;
  150. new_node->rlink = NULL;
  151. new_node->llink = br->unitdeque[index].tail;
  152. br->unitdeque[index].tail = new_node;
  153. }
  154.  
  155. }
  156.  
  157. //유닛생산을 취소할 경우 Rear에서 제거
  158. void delete_rear(BARRACKS *br,int index)
  159. {
  160. int item;
  161.  
  162. DequeNode *removed_node = br->unitdeque[index].tail;
  163. if (is_empty(&br->unitdeque[index])) return;
  164. else {
  165. item = removed_node->type;
  166. if (br->unitdeque[index].tail->llink == NULL) {
  167. br->unitdeque[index].head = NULL;
  168. br->unitdeque[index].tail = NULL;
  169. }
  170. else {
  171. br->unitdeque[index].tail = br->unitdeque[index].tail->llink;
  172. br->unitdeque[index].tail->rlink = NULL;
  173. }
  174. free(removed_node);
  175. printf("대기열에서 %d이(가) 취소되었습니다.", item);
  176.  
  177. }
  178.  
  179.  
  180. }
  181.  
  182. //배럭의 구조체의 모든 대기열의 front의 left타임을 1줄이는 함수
  183. void progress_tick(BARRACKS* barracks)
  184. {
  185.  
  186. for (int i = 0; i < COUNT_BARRACKS; i++) {
  187. if (barracks->unitdeque[i].head != NULL) {
  188. barracks->unitdeque[i].head->lefttime--;
  189.  
  190. }
  191. }
  192. }
  193.  
  194. //대기열의 생산상황 출력
  195. void display(BARRACKS* br)
  196. {
  197. int i;
  198. for (i = 0; i < COUNT_BARRACKS; i++) {
  199. //각 대기열의 진행상황 출력
  200. //예시
  201. //배럭 1: 마린-마린-매딕
  202. if (br->unitdeque[i].head != NULL) {
  203. DequeNode *dq = NULL;
  204. dq = br->unitdeque[i].head;
  205. while (dq->rlink != NULL && dq != NULL) {
  206. printf("배럭 %d : ", i + 1);
  207. unit_display(dq->type);
  208. if (dq->rlink->rlink != NULL)
  209. printf("-");
  210. else break;
  211. }
  212. }
  213. //배럭 2: 파이어뱃-마린
  214. //배럭 3: 매딕-마린
  215. //배럭 4: 고스트-마린
  216. //배럭 5: 마린-매딕
  217.  
  218. }
  219. }
  220.  
  221.  
  222. //
  223. main()
  224. {
  225. int i, select, count;
  226. BARRACKS barracks;
  227. barracks.count = 0;
  228. for (i = 0; i < COUNT_BARRACKS; i++) {
  229. init(&(barracks.unitdeque[i]),&barracks);
  230. }
  231.  
  232. while (TRUE)
  233. {
  234. printf("1. 유닛생산하기\n");
  235. printf("2. 유닛생산취소하기\n");
  236. printf("3. TICK 하나 보내기\n");
  237. printf("원하는 작업을 선택해 주세요:");
  238. scanf_s("%d", &select);
  239. printf("\n\n");
  240.  
  241. switch (select)
  242. {
  243. case 1:
  244. while (TRUE)
  245. {
  246. printf("1. 마린\n");
  247. printf("2. 파이어뱃\n");
  248. printf("3. 고스트\n");
  249. printf("4. 매딕\n");
  250. printf("5. 생산종료\n");
  251. printf("생산할 유닛을 선택해 주세요:");
  252. scanf_s("%d", &select);
  253.  
  254. if (select == 5) {
  255. break;
  256. }
  257. else if (select <= 0 || select > 5) {
  258. printf("잘못선택하셨습니다, 다시선택해 주세요\n");
  259. continue;
  260. }
  261.  
  262. printf("몇기 생산 하시겠습니까?:");
  263. scanf_s("%d", &count);
  264.  
  265. if (barracks.count + count <= 25) {
  266. for (i = 0; i <= count / 5; i++) {
  267. int index = 0;
  268. while (index < count % 5){
  269. add_rear(&barracks, select, index);
  270. index++;
  271. }
  272. //적절한 배럭을 선택하여 count만큼 대기열에 add_rear()을 호출하여 유닛추가(최대한 효율적으로 대기열에 추가해야함)
  273. }
  274. }
  275. else {
  276. printf("대기열이 부족합니다.\n");
  277. }
  278. }
  279. progress_tick(&barracks);
  280. break;
  281. case 2:
  282. printf("생산취소할 유닛의 수:");
  283. scanf_s("%d", &count);
  284. for (i = 0; i < count; i++) {
  285. int index = count;
  286. index %= 5;
  287. delete_rear(&barracks,index);
  288. }
  289. //count만큼 적절하게 배럭의 대기열에서 delete_rear()호출하여 유닛취소 전체 대기열의 유닛수 보다 많은수를
  290. //최소할 경우 전부 취소
  291.  
  292. progress_tick(&barracks);
  293. break;
  294. case 3:
  295. //아무것도 하지 않고 tick만 진행
  296. progress_tick(&barracks);
  297. break;
  298. default:
  299. //잘못선택한 경우 tick이 경과되지 않아야함
  300. printf("잘못선택하셨습니다, 계속하시려면 아무버튼이나 누르십시오...");
  301. break;
  302. }
  303. delete_front(&barracks);
  304.  
  305. //각 대기열의 상황 출력
  306. display(&barracks);
  307.  
  308. _getch();
  309.  
  310. system("cls");
  311. }
  312. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement