- 참치군
- ?
- stalk.io
- :: 2013년, 스리는 여섯살
- 웹 강좌
- 점프 투 파이썬
- 요니나의 대학생 재테크
- This is CS50
- 애자일 이야기
- isao의 IT,게임번역소
- 소프트웨어 이야기
- Color Scripter
- 어디를 가든지 마음을 다해 가라
- VisuAlgo
- 서울대 평생교육원
- 몽환
- RegExr: Learn, Build, & Test R…
- Hello, Stranger :D
- I Like Exploit
- Z3alous Security Story
- Project Euler
- Blog
- pieces of code
- window 쪼물딱 거리기
- IT - Informatics Alphabet
- rop
- 국제 정보교육센터 I2sec 대구 1기
- This is the moment. :)
- blackmoon
- z3alous는 세상에 소리 z3alous~
- Acord
- FORENSIC-PROOF
- 어셈블리
- Outsider's Dev Story
- Open Tutorials
- 코드라이언
- 컴퓨터 그래픽스와 3D 프린팅
- HACKABILITY
- Lee, Jae-Hong
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 버퍼오버플로우
- 컴파일러
- C언어
- Debug
- 시간복잡도
- 레지스터
- 창의공학설계
- 염색
- 펌
- 블루블랙
- 베이스
- 동대구
- Wireshark
- 소켓
- ubuntu
- BOF
- 오지총
- Calling Convention
- Hello World
- Packet
- 탈색
- 파이썬
- 공간복잡도
- 알고리즘
- 추상데이터타입
- 디버깅
- 호출규약
- 피보나치
- 발표
- Visual Studio
- Today
- Total
c0smicb0y
시스템 프로그래밍 팀프로젝트 4 본문
이제 여러가지 기술이 들어간 산성비 게임에 대해 설명하겠다.
한컴타자연습을 해보았다면 다들 해봤을법한 게임이다.
구현은 일단 입력칸이 있고, HP가 있고, 위에서부터 랜덤한 위치에 단어가 나오면서 밑으로 떨어진다.
맞는 단어를 입력하면 그 단어가 사라지고, 결국 못맞추고 단어가 제일 아래까지 내려오면 HP가 감소하게 만들었다.
일단 화면상에 표시되는 단어들이 어디에 저장되어 있어야 할것이다. 단어가 화면에 나타나고 먼저 나타난 단어가 먼저 맨 밑까지 가서 사라지기 때문에 선입선출이 일어날 수 있는 큐를 써야할 것이다. 하지만 큐를 쓰는 부분에서 간단히 정적 배열을 통한 큐를 쓴다면 언젠가 큐의 끝부분이 나와서 더 이상 데이터를 집어넣을수 없으므로 데이터를 큐의 앞쪽으로 이동시켜야하는데 이 부분에서 성능 상의 문제가 생길 수 있다. 그래서 이럴 필요가 없는 링크드리스트를 통하여 큐를 구현하였다.
저장할 방법을 정했으니 이제 화면에 표시하는 부분에서 문제가 있었다. 커서는 하나인데 화면에 글자를 출력하면서 입력창에 입력을 하는것은 불가능하기 때문이다. 그래서 화면을 표시하는 쓰레드를 분리해서 표시하였다.
그리고 큐를 링크드리스트로 구현하면서 동적할당을 사용하여 인터럽트를 발생시켜서 프로그램이 강제로 종료되는 경우에 메모리 할당해제가 안되고, 변경했던 터미널 설정이 원래대로 돌아가지 않는 문제가 발생하였다. 그래서 signal을 통제하는 함수를 써서 인터럽트로 인해 강제종료 될 경우에 메모리 할당을 해제하고, 커서표시를 비활성화 했었는데 이걸 다시 활성화 시키고, 콘솔 윈도우창을 닫고, 프로그램을 종료하게 handling해주었다.
1 2 3 4 5 6 7 | void function(int signum) { reset(); // 메모리 할당 해제 curs_set(1); // 커서 표시 활성화 endwin(); // 콘솔 윈도우창 닫기 exit(1); // 프로그램 종료 } | cs |
다음은 이렇게해서 만든 프로그램의 코드이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <curses.h> #include <string.h> #include <signal.h> #include <pthread.h> #include <time.h> int hp = 100; // 체력 int a = 0; // 문자열 위치 int i = 0; // for문용 int length = 0; char hpText[3] = { 0 }; node *ptr = 0; char enterText[20] = { 0 }; int enterHere = 0; int sleep_time = 1; void function(int signum) { reset(); // 메모리 할당 해제 curs_set(1); // 커서 표시 활성화 endwin(); // 콘솔 윈도우창 닫기 exit(1); // 프로그램 종료 } // 큐를 비워주고 메모리 할당을 해제해주는 함수 void reset() { node *temp = NULL; node *temp2 = NULL; temp = ptr; if (temp != NULL) { while (length > 0) { temp = ptr; while (temp->link) { temp2 = temp; temp = temp->link; } free(temp); if (temp2 != NULL) temp2->link = NULL; length--; temp2 = NULL; } ptr = NULL; } } // 화면에 글자를 보이게만 하는 함수 void thread_1(void *none) { int t = sleep_time; while (hp > 0) { //alarm(2); node *temp = 0; addQueue(returnWord(), (rand() % 40) + 8); temp = ptr; while (temp) { draw(temp->row, temp->col, temp->str); temp = temp->link; } move(17, 12); sleep(t); } } // 자연수를 문자열로 int itoa(int n, char *str) { int temp; if (n <= 0) { strcpy(str, "0"); return 0; } temp = itoa(n / 10, str); *(str + temp) = 48 + (n % 10); return temp + 1; } // 입력한 문자열을 큐에서 찾아서 없애주는 함수 void findWord(char *str) { node *temp = 0; temp = ptr; while (temp) { if (!strcmp(temp->str, str)) { strcpy(temp->str, ""); return; } else temp = temp->link; } } // 노드 생성 node *makeNode() { node *temp = 0; temp = (node *)malloc(sizeof(*temp)); temp->link = 0; } // 한 줄씩 밑으로 내려오게 해 주는 코드 void makePlusOne() { node *temp = ptr->link; while (temp) { temp->row += 1; temp = temp->link; } } // 큐에 하나씩 넣는 함수 void addQueue(char *str, int col) { node *temp = 0; node *temp2 = 0; if (ptr == 0) { ptr = makeNode(); strcpy(ptr->str, str); ptr->row = 1; ptr->col = col; } else { temp = makeNode(); strcpy(temp->str, str); temp->row = 1; temp->col = col; temp->link = ptr; ptr = temp; makePlusOne(); } length++; if (length > 15) { while (temp->link) { temp2 = temp; temp = temp->link; } hp -= strlen(temp->str); hpText[2] = '\0'; itoa(hp, hpText); move(17, 55); addstr(" "); move(17, 55); addstr(hpText); free(temp); temp2->link = 0; length--; } } // 단어 데이터베이스에서 글자를 골라서 리턴해주는 부분 char *returnWord() { char *database[] = { "Apple", "Jung", "Cocaine", "Hello", "Elite", "Fail", "Game", "Halo", "Icon", "Jail", "Knight", "Lake", "Monkey", "Nope" }; if (a == 13) a = 0; else a++; return database[a]; } // row행 col열에 문자열 str을 출력해주는 부분 void draw(int row, int col, char *str) { move(row, 0); addstr(" "); move(row, col); addstr(str); refresh(); } void startGame() { pthread_t t1; clear(); draw(16, 0, " -------------------------------------------------------- "); draw(17, 0, " | Enter : | HP : |"); draw(18, 0, " -------------------------------------------------------- "); itoa(hp, hpText); move(17, 55); addstr(" "); move(17, 55); addstr(hpText); pthread_create(&t1, NULL, thread_1, NULL); while (hp > 0) { for (enterHere = 0; enterHere < 20;) { int c = getch(); if (c == '\n') { enterText[enterHere] = '\0'; findWord(enterText); for (i = 0; i < 20; i++) { enterText[i] = '\0'; } draw(17, 0, " | Enter : | HP : "); move(17, 12); break; } else if (c == 127) { if (enterHere > 0) { enterText[--enterHere] = '\0'; move(17, 12); addstr(" "); move(17, 12); addstr(enterText); } else { move(17, 12); addstr(" "); } } else { enterText[enterHere++] = c; move(17, 12); addstr(enterText); } refresh(); } } pthread_join(&t1, NULL); reset(); clear(); } | cs |
그래서 만들어진 최종 프로그램의 시연 동영상이다.
출력되는 단어를 파일입출력을 통해 표시하게 했으면 더 좋았을건데 시간이 없어서 그러진 못했다. 다른 팀들은 대부분 소켓통신을 통한 프로그램을 만들었던데 소켓통신이 약간 어려워서 그런지 기본구현에도 다들 애를 먹었는지 대부분 그냥 소켓통신이 되는 프로그램이라는 느낌밖에 주지못했다. 우리팀도 소켓통신을 넣을려고 했는데 아무리 생각해봐도 만들려고 하는 것에 필요없는 기능같아서 과감히 뺀 덕분에 독창적으로 이것저것 구현할 수 있었다. 그리고 팀프로젝트를 할 때마다 느끼는 점인데 개인프로젝트보다 다섯배정도 어려운것 같다. 단순히 다른팀원의 코드를 알아보는게 힘들어서가 아니라 다른팀원을 관리하는게 더 어려워서 그렇다. 결국 사람 문제인것 같다. 소프트웨어 설계 시간에도 사람을 다루는 기술로 몇시간정도 수업을 했었다. 공돌이한테는 커뮤니케이션은 참 어렵다. 그것도 개인주의 성향이 강한 컴공에서는 말이다. 그래도 파탄나지 않고 순조롭게 진행되어서 다행이다.
'진행한 프로젝트 > 시스템 프로그래밍' 카테고리의 다른 글
시스템 프로그래밍 팀프로젝트 3 (0) | 2015.01.08 |
---|---|
시스템 프로그래밍 팀프로젝트 2 (0) | 2015.01.07 |
시스템 프로그래밍 팀프로젝트 1 (0) | 2014.11.25 |