C :: 컴퓨터와 가위바위보를 하자. - 코딩편
지난 설계편에 이어서... 우선, 헤더파일을 작성하겠습니다. 헤더파일의 이름은 간단히 play.h 로 합니다.
ComSelect() 함수에서 난수를 이용하기로 설계시 정했기 때문에 stdlib.h 와 time.h 를 포함시켜야 합니다. stdlib.h 에는 rand() 함수와 srand() 함수가 있죠. rand() 함수는 난수를 발생시키고, srand() 함수는 시드값을 줄 수 있습니다. 시드값을 주지 않으면 난수가 항상 같은 값으로 나옵니다. 그리고 시드값은 time.h 에 있는 time(NULL) 함수를 참조합니다.
/***************************************************************
* 프로젝트 이름 : PlayGmae *
* 소스파일 이름 : play.h *
***************************************************************/
#ifndef PLAY_H_INCLUDED
#define PLAY_H_INCLUDED
// 입출력을 위한 헤더파일
#include <stdio.h>
// rand(), srand() 함수를 위한 헤더파일
#include <stdlib.h>
// time(NULL) 함수를 위한 헤더파일
#include <time.h>
int UserSelect(int);
int ComSelect(int);
void Battle(int, int);
#endif // PLAY_H_INCLUDED
그리고 각 함수의 원형을 play.h 안에 선언했죠. 인자로 int 형을 넣어놨는데 이건 사용자나 컴퓨터의 선택값을 받기 위해서입니다.
다음으로, 프로그램의 전체적인 흐름을 통제할 main() 함수를 작성해야겠네요. 당연히 소스파일 이름은 main.c 입니다.
설계에서 이미 다 정해놨기 때문에 그대로 코딩만 하면 됩니다. 설계 내용을 다시 보자면 이렇습니다.
- 안내문 출력.
- 사용자의 선택
- 컴퓨터의 선택 (난수 이용)
- 승부 결정.
- 결과 출력.
여기서 조금 수정을 했습니다. 마지막의 결과 출력을 승부 결정에 포함시켰습니다. 즉, Battle() 함수에 넣었은거죠. 이게 더 깔끔하더라구요. 그리고 선택값에 대한 변수 이름은 사용자는 selectUser, 컴퓨터는 selectCom 으로 했습니다.
/***************************************************************
* 프로젝트 이름 : PlayGmae *
* 프로젝트 목적 : 컴퓨터와 가위바위보를 하자. *
* 소스파일 이름 : main.c *
***************************************************************/
// play.c 와 연결되어 있다.
#include "play.h"
int main()
{
// 사용자의 선택
int selectUser = 0;
// 컴퓨터의 선택
int selectCom = 0;
printf("컴퓨터와 가위바위보를 해보자. \n");
// 사용자가 가위, 바위, 보 중에서 하나를 선택한다.
selectUser = UserSelect(selectUser);
// 컴퓨터가 난수를 이용하여 가위, 바위, 보 중에서 하나를 선택한다.
selectCom = ComSelect(selectCom);
printf("\n");
// 사용자와 컴퓨터의 선택을 비교하여 승부를 결정한다.
Battle(selectUser, selectCom);
return 0;
}
아, 물론 play.h 를 참조하도록 넣어야겠죠?
끝으로, 각 함수를 정의할 play.c 파일을 작성합니다. 먼저 play.h 를 참조하도록 합니다.
/***************************************************************
* 프로젝트 이름 : PlayGmae *
* 소스파일 목적 : 가위바위보 게임을 구현한다. *
* 소스파일 이름 : play.c *
***************************************************************/
// main.c 와 연결되어 있다.
#include "play.h"
그리고 첫 번째 함수, UserSelect() 를 작성합니다. 선택사항에 대한 안내를 하고 선택값을 입력하라고 해야겠죠. 단, 입력받은 값이 잘못된 값일 경우를 예상하여 정해진 값이 아니면 다시 입력하라고 안내해야 합니다. 아니면 프로그램 망칩니다. ㅋ
// 사용자가 가위, 바위, 보 중에서 하나를 선택한다.
int UserSelect(int select)
{
printf("가위(1), 바위(2), 보(3) 중에서 하나 선택해라. >> ");
while(scanf("%d", &select))
{
if((select == 1) || (select == 2) || (select == 3))
{
break;
}
else
{
printf("멍청아, 잘못 입력했잖아. 다시 선택해라. >> ");
}
}
printf("\n넌 %s를 선택했다. \n", (select == 1) ? "가위" : ((select == 2) ? "바위" : "보"));
return select;
}
가위는 1을, 바위는 2를, 보는 3을 입력하라고 안내했습니다. while 문과 if 문을 이용해서 올바른 값을 입력하도록 유도합니다. if 문을 다룰 때는 꼭 else 문을 같이 넣어줘야 합니다. 안 넣어줘도 프로그램 실행에는 문제 없지만 언제 어디서 오류를 일으킬지 모르거든요. 적어도 else 문으로 오류코드가 출력되도록 하면 어디서 오류가 생겼는지 금방 알 수 있습니다.
이제 두 번째 함수, ComSelect() 입니다. 필요한 건 stdlib.h 에 다 정의되어 있기 때문에 라이브러리 함수만 이용하면 특별히 지정해줄 게 없습니다.
// 컴퓨터가 가위, 바위, 보 중에서 하나를 선택한다.
int ComSelect(int select)
{
// time 변수를 이용하여 난수를 생성 후, 3가지 선택사항으로 컴퓨터에게 주어진다.
srand(time(NULL));
select = rand() % 3 + 1;
printf("컴퓨터는 %s를 선택했다. \n", (select == 1) ? "가위" : ((select == 2) ? "바위" : "보"));
return select;
}
난수에 대해 조금 부연설명을 하자면, rand() 함수로 생긴 수많은 경우의 수를 3으로 나눈 나머지 값인 0, 1, 2의 3가지 경우의 수로 분류합니다. 그리고 우리가 원하는 선택값인 1, 2, 3으로 만들기 위해 1을 더하는 거죠.
세 번째 Battle() 함수입니다. 설계에서 어떻게 승부를 결정할 지 못 정했으니 이제 정해야 합니다. 두 함수에서 선택값으로 1, 2, 3을 받도록 되어 있습니다. 이 숫자들을 이용합니다. 여러 방법이 있겠지만, 서로 곱하는 게 가장 깔끔해 보입니다.
// 사용자와 컴퓨터가 선택한 것으로 승부를 결정한다.
void Battle(int user, int com)
{
switch(user * com)
{
// 선택: 가위(1)와 바위(2)
case 2 :
printf("%s가 이겼다. \n", (user > com) ? "너" : "컴퓨터");
break;
// 선택: 가위(1)와 보(3)
case 3 :
printf("%s가 이겼다. \n", (user < com) ? "너" : "컴퓨터");
break;
// 선택: 바위(1)와 보(3)
case 6 :
printf("%s가 이겼다. \n", (user > com) ? "너" : "컴퓨터");
break;
// 선택: 가위(1)와 가위(1), 바위(2)와 바위(2), 보(3)와 보(3)
default :
printf("너와 컴퓨터는 비겼다. \n");
break;
}
}
곱하는 게 아니더라도 XOR 연산을 이용해도 됩니다. XOR 연산을 이용하면 비기는 경우 모두가 0으로 반환되죠.
마지막 함수까지 코딩을 끝마쳤으니 이제 컴파일 해보겠습니다.

큭, 컴퓨터에게 졌네요. 이런이런... 아무튼 간단한 가위바위보 게임을 만들었습니다. 여기에 GUI를 붙이면 더 멋질 것 같은데... GUI는 지금 공부중입니다. 언젠가 한 번 해보죠.
참, 코딩을 할 때 꼭 주석을 붙여주십시오. 간혹 몇몇 프로그램을 참조할 때 주석이 전혀 없어서 해석하기가 무척 난해했습니다. 서로 돕고 도와야죠. 응? 꼭 그런 게 아니더라도 주석을 달아야 나중에 수정을 하더라도 더 쉽게 할 수 있지 않을까요?
관련글
C :: 컴퓨터와 가위바위보를 하자. - 설계편 :: http://hisjournal.net/blog/126
C :: 컴퓨터와 가위바위보를 하자. - 코딩편 :: http://hisjournal.net/blog/127
"#1. 내 머리 속의 노트 / C 언어 마스터 Go! gO!" 분류의 다른 글
| C언어 난관 2 [열혈강의 C p.115] char_add.c (8) | 2010/02/23 |
| C :: typedef으로 함수 포인터를... (2) | 2009/08/25 |
| C :: null 포인터, null 문자, 정수 0에 관한 이야기 (2) | 2009/06/24 |
| C :: srand(time(null)) 과 usleep() 함수 (4) | 2009/04/11 |
| C :: 0xE0 == 224 ? (0) | 2009/03/03 |
| C :: 1byte씩 메모리 읽기 (2) | 2009/02/28 |
| C :: 실수(Float)를 엿보려면 컴퓨터를 속여라. (4) | 2009/02/15 |
| C :: 포인터는 포인터일뿐 이상도 이하도 아닙니다. (2) | 2009/02/13 |
| C :: multiple definition 에러 (0) | 2009/02/01 |
| C :: 컴퓨터와 가위바위보를 하자. - 설계편 (0) | 2009/01/16 |