1. 간단한 가위바위보 게임 만들기

마지막 수정일: 2022-06-06

입문강좌를 시작하며

안녕하세요. 앞으로 입문강좌를 쓰게 될 Denoil 입니다. :) 제가 초보때 겪었던 어려움을 기초로 여러분에게 약간이나마 도움이 되고자 이렇게 입문강좌를 쓰게 되었습니다.

말 그대로 입문강좌입니다. 3D 입문도 아닙니다. 게임개발 처음 접하시는 분들을 위한 글들이지요. 처음에는 쉬운것부터 시작해서 점점 난이도를 높여 갈 생각입니다. 그러다보면 여러분들의 실력도 그만큼 많이 향상되어 간단한 게임정도는 혼자서 뚝딱! 뽑아낼수 있는 실력이 될 수 있을것이라 생각합니다. :)

꾸준히 올려야 하는데 앞으로 해야할 일이 많아서 어떻게 될지는 잘 모르겠군요. :) 최대한 노력해서 올려보도록 하겠습니다. ^^

가위바위보 게임

처음에 뭐부터 시작할까 고민고민하다가 C를 이용한 가위바위보 게임을 선정하게 되었습니다. 제가 처음 C를 공부할때 처음으로 만들어본 간단한 미니게임이지요^^; 사용자가 가위, 바위, 보 중에 하나를 입력하면 컴퓨터 역시 가위, 바위, 보 중에서 하나를 임의로 선택! 승패를 알려주는 게임입니다.

전체 소스코드

일단 먼저 풀소스부터 보여 드리도록 하겠습니다.

#include    <stdio.h>
#include    <conio.h>
#include    <stdlib.h>
#include    <time.h>

char*    g_FingerMotion[3]  =    {    "가위", "바위", "보"        };
char*    g_Result[3][3]     =    {    "비겼다", "졌다", "이겼다",
                                      "이겼다", "비겼다", "졌다",
                                      "졌다", "이겼다", "비겼다"
                                 };

void    main()
{
   int    User        =    0;
   int    Computer    =    0;

   srand( time( NULL ) );
   
   while( 1 )
   {
       system( "cls" );

       printf("가위[0], 바위[1], 보[2], 종료[3]\n" );
       printf("입력: " );
       scanf( "%d", &User );

       if( User == 3 )    break;
       if( User < 0 || User > 3 )
       {
           printf( "잘못 입력하셨습니다. 다시입력해주세요.\n" );
           printf( "Press any key" );
           getch();
           continue;
       }

       Computer    =    rand() % 3;

       printf("컴퓨터 : %s\n", g_FingerMotion[ Computer ] );
       printf("유저 : %s\n", g_FingerMotion[ User ] );
       printf("결과 : %s\n", g_Result[ User ][ Computer ] );
       printf( "Press any key" );

       getch();
   }
}

소스 분석

소스는 매우 간단하게 되어 있습니다. 변수명은 그낭 맘대로 짓겠습니다. -_-)a 워래 코드짜는 스타일은 엿장수 마음 아니겠습니까 ^^( 농담입니다 :) )

일단

#include    <stdio.h>
#include    <conio.h>
#include    <stdlib.h>
#include    <time.h>

누구나 다 알고 있겠죠?

  • stdio -> standard Input Ouput (표준 입력/출력)
  • conio -> Consol Input Output (콘솔 입력/출력)
  • stdlib-> standard Library (표준 라이브러리)
  • time -> Time -_-)a
  • stdio - printf, scanf 함수
  • conio - getch 함수 사용
  • stdlib - rand, system, srand 함수 사용
  • time - time 함수사용

저런 이유에서 저렇게 많은 파일을 포함했습니다. 자 다음

char*    g_FingerMotion[3]  =    {    "가위", "바위", "보"        }    ;
char*    g_Result[3][3]     =    {    "비겼다", "졌다", "이겼다",
                                      "이겼다", "비겼다", "졌다",
                                      "졌다", "이겼다", "비겼다"
                                 }    ;
  • g_FingerMotion - 변수명이 참 이상하죠? ^^; 이 변수는 가위, 바위, 보를 출력해 주기 위해 만든 포인터 배열입니다.
char* g_FingerMotion = "가위" ;

이렇게하면 g_FingerMotion은 "가위"라는 단어의 포인터를 가지고 있겠죠? 3개의 단어를 가지게 하려고 g_FingerMotion[3] 이라는 배열로 선언하였습니다. g_Result는 2차원 배열입니다. 여기가 이 프로그램의 '''키포인트!''' 결과를 Table로 만든 것입니다.

가위, 바위, 보 만을 이용해서 둘이서 싸울 때 나오는 경우의 수는 9개지요?

사용자 컴퓨터 결과
가위    
가위 비김  
가위 바위
가위 이김
     
바위 가위 이김
바위 바위 비김
바위
     
가위
비김
비김

위의 결과를 g_Result라는 변수를 2차원 배열로 선언하여 테이블에 넣어놓은것입니다. 그렇게 하면 더욱 쉬워지겠죠? ^^ 저렇게 안하면 if문의 압박이 심할 것입니다.

if( "가위" == "가위" )
{
  비겼따 ;
}
else if( "가위" == "바위" )
{
   졌다 ;
}
     .
     .
     .
     .

요런식으로 9가지의 if문을 다 써줘야 하겠죠. 겁네 깁니다. 짜증나죠-_-)a 이걸 Table화시키면 단 한 줄이면 끝납니다. ( 밑에서 설명 )

※main함수는 누구나 아는것이니 생략

int    User        =    0;
int    Computer    =    0;
User      - User입력을 받을 변수
Computer  - 임의의 수를 저장할 변수

User는 입력을 받고 Computer는 임의로 저장하고 있다가 User와 Computer와 비교해야 하기에 변수 2개가 필요하겠죠? ^^

while( 1 )
{
  ...코드생략 ;
}

자, 게임에서 제일 중요한 부분. 무한 루프 입니다.

게임한판만하고 끝낼것은 아니지 않습니까? 그렇기 때문에 게임 돌아가는 코드를 while문으로 감싸는 것 입니다. 그러면 한판끝나면 다시하고 한판 끝나고 다시하고 그렇게 할수 잇겠죠?

system( "cls" );

system - 이 함수는 콘솔 커맨드 입력창 ( 윈도우시작버튼 -> 실행 -> cmd ) 에서 사용할수 있는 명령어들을 수행하는함수 입니다. 우리가 지금 하는것은 콘솔 어플리케이션이기 때문에 저것이 사용가능합니다. cls 이외에도, dir, md.. 등등 ( 생각이 안나요-_-)a ) 을 사용할수 있습니다. 화면에는 그대로 표현되구요.

보통 게임에서는 한번 루프를 돌면 화면을 Clear 한후 다시 렌더링하고 그렇게 합니다. 여기서는 그런 게임구조를 모방한것이지요.

printf("가위[0], 바위[1], 보[2], 종료[3]\n" );
printf("입력: " );
scanf( "%d", &User );

윗부분은 생략합니다.

if( User == 3 )    break;
if( User < 0 || User > 3 )
{
   printf( "잘못 입력하셨습니다. 다시입력해주세요.\n" );
   printf( "Press any key" );
   getch();
   continue;
}

입력부분에서 3을 누르면 종료를 이르켜야 하게 되있기때문에 만약 입력받은 값이 3이라면 while문을 빠져나가게 break 를 거는 것입니다. 그러면 자동으로 프로그램은 종료가 되겠죠.

그 밑에는 키를 잘못 입력했을 시에 대한 예외 처리입니다. 입력하는것은 0~3까지 뿐이니 그 이외의 입력은 무시하고 다시 처음부터 시작하게 하는것입니다. getch는 키보드 입력 한 개를 받을때까지 Blocking(멈춰 있는 것)되어 있다가 키보드 입력이 들어오면 그 아스키코드를 리턴하면서 함수를 빠져나오게 됩니다.

continue라는 것은 더 이상 진행하지 않고 반복문의 처음으로 가는 것이지요.

Computer    =    rand() % 3;

컴퓨터에게서 가위,바위,보 중 하나를 뽑아오게 하는 루틴입니다. 0은 가위, 1은 바위, 2는 보죠?

rand라는 함수가 임의의 숫자를 리턴하게됩니다.

리턴형이 int 이니깐 -32768 ~ 32767 까지 나오게 되겠죠. 그러나 rand가 음수는 리턴하지 않습니다.

테스트 결과 rand의 범위는 0~32767 의 숫자가 나오게 됩니다. :)

임의의 숫자가 튀어나오면 나머지연산자 ( % ) 를 이용해서 0~2까지 뽑습니다.

9999를 3으로 나누면 나머지는 0 10000을 3으로 나누면 나머지는 1 10001을 3으로 나누면 나머지는 2 10002를 3으로 나누면 나머지는 0 10003을 3으로 나누면 나머지는 1 10004를 3으로 나누면 나머지는 2 . . .

이런식으로 계속 반복하게되겠죠. 산수를 조금 하셨다면 이정도는 이해하시리라 믿습니다. :) 이걸 응용해서 rand() % 100 을하면 0~99 까지 나오겠죠. 그냥 간단하게 0~ n-1 까지나온다고 생각하시면 됩니다.

printf("컴퓨터 : %s\n", g_FingerMotion[ Computer ] );
printf("유저 : %s\n", g_FingerMotion[ User ] );
printf("결과 : %s\n", g_Result[ User ][ Computer ] );
printf( "Press any key" );

첫번째 printf 컴퓨터가 낸 것이 무엇인지 보여준다.

두번째 printf 유저가 낸 것이 무엇인지 보여준다.

세번째는 결과값을 보여주는 것입니다.

아까 Table 작성한것있죠. 그것을 일렬로 정렬시켜보면 "비겼다", "졌다", "이겼다","이겼다", "비겼다", "졌다", "졌다", "이겼다", "비겼다" 메모리구조에서는 이런식으로 들어가 있겠죠?

자! 배열에서는 맨 오른쪽부터 우선순위를 가지니깐 앞쪽에 User를 넣고 뒷쪽에 Computer를 넣으면

*g_Result[0][0] == 비겼다    ( 가위 - 가위 )
*g_Result[0][1] == 졌다     ( 가위 - 바위 )
*g_Result[0][2] == 이겼다    ( 가위 - 보 )

이렇게 되겠죠. 그래서 g_Result[ User ][ Computer ] 이런순서로 User와 Computer 변수를 넣어주었던것입니다. 바뀌면 안됩니다. :)

마치며

자 이로서.. Denoil 군의 첫 강좌를 마쳤습니다. 근데 소스를 다 설명하다보니 생각보다 너무 길어졌네요. 다음부턴 액기스만 뽑아서 하는 습관을 들이도록 노력하겠습니다. :) 전체 소스를 보면 그다지 어렵지 않습니다.

그럼 허접한 강좌 봐주셔서 감사하구요. 다음에 뵈요 ^^;;;

참고

( ※ 저런식으로 테이블을 이용해서 가위바위보 짜는것은 박세환님께 배운것 입니다. 저시절에는 저렇게 짤 생각을 못했기때문에..-_-)a 쿨럭;; )

저술정보

  • 저자: Denoil
  • 저술일: 2005년 7월 10일
img

프로그래밍 실력 Level-Up! | 사장님께 인정받는 개발자 되기 | 프로그래밍계의 소림사

네카라쿠배 개발자도 강추하는 프로그래머 Level-Up 강의! POCU 아카데미가 올해 연봉협상을 책임지겠습니다!