Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <conio.h>
- #define TRUE 1
- #define FALSE 0
- #define MAX_UNIT_WAITING 5 //덱 하나당 최대 적재개수
- #define COUNT_BARRACKS 5 //배럭의 수
- //유닛유형
- #define MARINE 1
- #define FIREBAT 2
- #define GHOST 3
- #define MEDIC 4
- typedef struct DequeNode { // 노드의 타입
- int type; //유닛유형
- int lefttime; //남은시간
- struct DequeNode *llink;
- struct DequeNode *rlink;
- } DequeNode;
- typedef struct DequeType { // 덱의 타입
- DequeNode *head;
- DequeNode *tail;
- } DequeType;
- //배럭 구조체
- typedef struct BARRACKS {
- int count; //전체 대기열이 어느만큼 채워져 있는지 알기위한 변수
- DequeType unitdeque[COUNT_BARRACKS];
- } BARRACKS;
- //
- void error(char *message)
- {
- fprintf(stderr, "%s\n", message);
- exit(1);
- }
- //
- void init(DequeType *dq,BARRACKS *br)
- {
- dq->head = dq->tail = NULL;
- br->count = 0;
- }
- DequeType *create_deque() {
- DequeType *dq;
- dq = (DequeType *)malloc(sizeof(DequeType));
- dq->head = NULL;
- dq->tail = NULL;
- return dq;
- }
- //남은시간은 마린, 파이어뱃을 2, 고스트, 메딕을 3으로 계산
- int lefttime_calc(int type) {
- switch (type)
- {
- case MARINE:
- return 2;
- break;
- case FIREBAT:
- return 2;
- break;
- case MEDIC:
- return 3;
- break;
- case GHOST:
- return 3;
- break;
- default:
- break;
- }
- }
- void unit_display(int unit)
- {
- switch (unit)
- {
- case 1:
- printf("마린");
- break;
- case 2:
- printf("파이어뱃");
- break;
- case 3:
- printf("고스트");
- break;
- case 4:
- printf("메딕");
- break;
- default:
- break;
- }
- }
- //
- int is_empty(DequeType *dq)
- {
- if (dq->head == NULL) return TRUE;
- else return FALSE;
- }
- //유닛생산을 완료할 경우 덱의 Front를 제거
- void delete_front(BARRACKS *br)
- {
- int item;
- int i;
- DequeNode *removed_node;
- for (i = 0; i < COUNT_BARRACKS; i++) {
- DequeNode *temp = br->unitdeque[i].head;
- if (temp == NULL)
- break;
- else if (temp->lefttime == 0) {
- removed_node = br->unitdeque[i].head; // 삭제할 노드
- item = removed_node->type; // 데이터 추출
- printf("배럭%d에서 ", i);
- unit_display(item);
- printf("의 생산이 완료됐습니다.");
- br->unitdeque[i].head = br->unitdeque[i].head->rlink; // 헤드 포인터 변경
- free(removed_node); // 메모리 공간 반납
- if (br->unitdeque[i].head == NULL) // 공백상태이면
- br->unitdeque[i].tail = NULL;
- else // 공백상태가 아니면
- {
- br->unitdeque[i].head = br->unitdeque[i].head->rlink;
- br->unitdeque[i].head->llink = NULL;
- }
- }
- else break;
- }
- }
- //완료된 유닛 출력필요(생산된 누적 유닛수는 출력할 필요없음)
- //대기열에 유닛추가, type에 따라 lefttime 지정
- void add_rear(BARRACKS *br,int type,int index)
- {
- DequeNode *new_node = (DequeNode *)malloc(sizeof(DequeNode));
- new_node->type = type;
- new_node->lefttime = lefttime_calc(type);
- if (is_empty(&br->unitdeque[index])) {
- br->unitdeque[index].head = new_node;
- br->unitdeque[index].tail = new_node;
- return;
- }
- else {
- br->unitdeque[index].tail->rlink = new_node;
- new_node->rlink = NULL;
- new_node->llink = br->unitdeque[index].tail;
- br->unitdeque[index].tail = new_node;
- }
- }
- //유닛생산을 취소할 경우 Rear에서 제거
- void delete_rear(BARRACKS *br,int index)
- {
- int item;
- DequeNode *removed_node = br->unitdeque[index].tail;
- if (is_empty(&br->unitdeque[index])) return;
- else {
- item = removed_node->type;
- if (br->unitdeque[index].tail->llink == NULL) {
- br->unitdeque[index].head = NULL;
- br->unitdeque[index].tail = NULL;
- }
- else {
- br->unitdeque[index].tail = br->unitdeque[index].tail->llink;
- br->unitdeque[index].tail->rlink = NULL;
- }
- free(removed_node);
- printf("대기열에서 %d이(가) 취소되었습니다.", item);
- }
- }
- //배럭의 구조체의 모든 대기열의 front의 left타임을 1줄이는 함수
- void progress_tick(BARRACKS* barracks)
- {
- for (int i = 0; i < COUNT_BARRACKS; i++) {
- if (barracks->unitdeque[i].head != NULL) {
- barracks->unitdeque[i].head->lefttime--;
- }
- }
- }
- //대기열의 생산상황 출력
- void display(BARRACKS* br)
- {
- int i;
- for (i = 0; i < COUNT_BARRACKS; i++) {
- //각 대기열의 진행상황 출력
- //예시
- //배럭 1: 마린-마린-매딕
- if (br->unitdeque[i].head != NULL) {
- DequeNode *dq = NULL;
- dq = br->unitdeque[i].head;
- while (dq->rlink != NULL && dq != NULL) {
- printf("배럭 %d : ", i + 1);
- unit_display(dq->type);
- if (dq->rlink->rlink != NULL)
- printf("-");
- else break;
- }
- }
- //배럭 2: 파이어뱃-마린
- //배럭 3: 매딕-마린
- //배럭 4: 고스트-마린
- //배럭 5: 마린-매딕
- }
- }
- //
- main()
- {
- int i, select, count;
- BARRACKS barracks;
- barracks.count = 0;
- for (i = 0; i < COUNT_BARRACKS; i++) {
- init(&(barracks.unitdeque[i]),&barracks);
- }
- while (TRUE)
- {
- printf("1. 유닛생산하기\n");
- printf("2. 유닛생산취소하기\n");
- printf("3. TICK 하나 보내기\n");
- printf("원하는 작업을 선택해 주세요:");
- scanf_s("%d", &select);
- printf("\n\n");
- switch (select)
- {
- case 1:
- while (TRUE)
- {
- printf("1. 마린\n");
- printf("2. 파이어뱃\n");
- printf("3. 고스트\n");
- printf("4. 매딕\n");
- printf("5. 생산종료\n");
- printf("생산할 유닛을 선택해 주세요:");
- scanf_s("%d", &select);
- if (select == 5) {
- break;
- }
- else if (select <= 0 || select > 5) {
- printf("잘못선택하셨습니다, 다시선택해 주세요\n");
- continue;
- }
- printf("몇기 생산 하시겠습니까?:");
- scanf_s("%d", &count);
- if (barracks.count + count <= 25) {
- for (i = 0; i <= count / 5; i++) {
- int index = 0;
- while (index < count % 5){
- add_rear(&barracks, select, index);
- index++;
- }
- //적절한 배럭을 선택하여 count만큼 대기열에 add_rear()을 호출하여 유닛추가(최대한 효율적으로 대기열에 추가해야함)
- }
- }
- else {
- printf("대기열이 부족합니다.\n");
- }
- }
- progress_tick(&barracks);
- break;
- case 2:
- printf("생산취소할 유닛의 수:");
- scanf_s("%d", &count);
- for (i = 0; i < count; i++) {
- int index = count;
- index %= 5;
- delete_rear(&barracks,index);
- }
- //count만큼 적절하게 배럭의 대기열에서 delete_rear()호출하여 유닛취소 전체 대기열의 유닛수 보다 많은수를
- //최소할 경우 전부 취소
- progress_tick(&barracks);
- break;
- case 3:
- //아무것도 하지 않고 tick만 진행
- progress_tick(&barracks);
- break;
- default:
- //잘못선택한 경우 tick이 경과되지 않아야함
- printf("잘못선택하셨습니다, 계속하시려면 아무버튼이나 누르십시오...");
- break;
- }
- delete_front(&barracks);
- //각 대기열의 상황 출력
- display(&barracks);
- _getch();
- system("cls");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement