소연의_개발일지
article thumbnail

(3.27) 학습일지

 

 

 

개발 진행 및 완료상황. 무엇을 더 하면 좋을지

사용함수: while, if, scanf, rand 등

 

오늘은 if문과 random함수를 이용한 가위바위보 게임을 만들었다.

쉽다고 생각했는데 이 단순한게임에 엄청난 논리가 있었던 것임

머리가 조금 아프다.

나는 자판기와 비슷하게 while문과 if문, 랜덤함수만 사용해서 만들었다.

 

가위바위보 게임 만들기

 

생각한 로직

노트에 작성한게 너무 지저분해서 컴퓨터로 만들어 봤다.

 

 

로고 출력

가위바위보 아스키 로고입니다

    _______
---'   ____)
      (_____)
      (_____)
      (____)
---.__(___)

    _______
---'   ____)____
          ______)
          _______)
         _______)
---.__________)

    _______
---'   ____)____
          ______)
       __________)
      (____)
---.__(___)
 

아래는 c언어 버전 가위바위보 로고!

printf("    _______\n---'   ____)\n      (_____)\n      (_____)\n      (____)\n---.__(___)\n\n    _______\n---'   ____)____\n          ______)\n          _______)\n         _______)\n---.__________)\n\n    _______\n---'   ____)____\n          ______)\n       __________)\n      (____)\n---.__(___)\n\n")
 

전체 코드

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

int main(void)
{
    srand(time(NULL));
    int computer_choice = rand() % 3 + 1; //컴퓨터 난수 생성 함수  
    int user_choice; //사용자 선택
    char should_continue; // 계속할지 질문
    int cnt_user=0, user_win=0, computer_win=0; //사용자가 게임을 한 횟수, 사용자가 이긴 횟수, 컴퓨터가 이긴 횟수
    // 로고 출력 ↓
    printf("    _______\n---'   ____)\n      (_____)\n      (_____)\n      (____)\n---.__(___)\n\n    _______\n---'   ____)____\n          ______)\n          _______)\n         _______)\n---.__________)\n\n    _______\n---'   ____)____\n          ______)\n       __________)\n      (____)\n---.__(___)\n\n");

    while(should_continue != 'n' && should_continue != 'N') // while문으로 게임 돌리기 n이 아니면 계속 진행. 대소문자 상관없이 쓰기 위해 ||(or)로 구분해줌
    {	
		printf("+======================================+\n"); // 가위바위보 게임 설명
        printf("+컴퓨터와 가위바위보 게임을 시작합니다.+\n");
        printf("+         1.가위 2.바위 3.보           +\n"); // 가위는 1, 바위는 2, 보는 3으로 할당하여 생각한다.
        printf("+======================================+\n");
        printf("당신의 선택은? \n>>"); // 보기 좋게 줄바꿈과 >> 넣어줌
        scanf("%d",&user_choice); // 사용자가 선택한 값을 user_choice로 가져와 준다. 첫번째 scanf함수
        getchar(); // 오류가 나서 개행문자 소비해주려 넣어줌
        printf("----------------(결과)------------------\n");
        
        if(user_choice>3 || user_choice<1) //사용자가 1,2,3 중 하나를 선택하지 않았을 때
        {
            printf("잘못 입력하셨습니다. 1, 2, 3 중 하나를 선택해주세요.\n\n"); //안내 및 다시 시작
            continue;
        }
        else if(user_choice==1 && computer_choice==2 || user_choice==2 && computer_choice==3 || user_choice==3 && computer_choice==1 ) // 컴퓨터가 이겼을 경우의 수 3가지 &&(and)로 묶어줬다.
        {
            printf("당신은 아쉽게도 컴퓨터에게 패배했습니다. \n"); //컴퓨터가 이겼다는 설명 출력
            cnt_user++; // 경기 횟수에 하나씩 추가해 줌
            computer_win++; //컴퓨터 이긴 횟수에 하나씩 추가해 줌
            if(user_choice==1 && computer_choice==3){ // 컴퓨터가 이겼을 경우 1번째 
                printf("당신은 가위를, 컴퓨터는 바위를 냈습니다.\n"); 
            }
            else if(user_choice==2 && computer_choice==1){ // 컴퓨터가 이겼을 경우 2번째 
                printf("당신은 바위를, 컴퓨터는 보를 냈습니다.\n");
            }
            else{ // 컴퓨터가 이겼을 경우 3번째 
                printf("당신은 보를, 컴퓨터는 가위를 냈습니다.\n");
            }
            printf("계속하시겠습니까? (y/n)\n>>"); // 계속했는지 묻기
            scanf("%c", &should_continue); // 사용자가 계속할건지에 대한 답변을 should_continue에 저장. 두번째 scanf함수
        }

        else if(user_choice==2 && computer_choice==1 || user_choice==3 && computer_choice==2 || user_choice==1 && computer_choice==3 ) // 사용자가 이겼을 경우의 수 3가지 &&(and)로 묶어줬다. 
        {
            printf("당신은 컴퓨터를 이겼습니다! \n"); // 사용자가 이겼다는 설명 출력
            cnt_user++; // 경기 횟수에 하나씩 추가해 줌
            user_win++; // 사용자 이긴 횟수에 하나씩 추가해 줌
            if(user_choice==2 && computer_choice==1){ // 사용자가 이겼을 경우 1번째
                printf("당신은 바위를, 컴퓨터는 가위를 냈습니다.\n");
            }
            else if(user_choice==3 && computer_choice==2){ // 사용자가 이겼을 경우 2번째
                printf("당신은 보를, 컴퓨터는 바위를 냈습니다.\n");
            }
            else{ //사용자가 이겼을 경우 3번째
                printf("당신은 가위를, 컴퓨터는 보를 냈습니다.\n");
            }
            printf("\n계속하시겠습니까? (y/n)\n>>"); // 계속할 것인지 묻기
            scanf("%c", &should_continue); // 사용자가 계속할건지에 대한 답변을 should_continue에 저장
        }

        else //if(user_choice=computer_choice) // 사용자의 값과 컴퓨터의 값이 같으면
        {
            printf("비겼습니다.\n"); // 비겼음을 출력
			cnt_user++; // 경기 횟수에 하나를 추가해 줌
			if(user_choice==1 && computer_choice==3){ // 가위일 경우 설명
				printf("당신과 컴퓨터는 가위를 냈습니다.\n");
			}
			else if(user_choice==2 && computer_choice==1){ //바위일 경우 설명
				printf("당신과 컴퓨터는 바위를 냈습니다.\n");
			}
			else{
				printf("당신과 컴퓨터는 보를 냈습니다.\n"); // 보일 경우 설명
			}  	
			printf("계속하시겠습니까? (y/n)\n>>");
            scanf("%c", &should_continue);
        }

        if(should_continue == 'n' || should_continue == 'N') // 사용자가 n을 선택하면 while문에서 빠져나온다.
        {
            break; // break로 빠져나오게 함
        }

        computer_choice = rand() % 3 + 1; // 컴퓨터가 다시 선택하도록 초기화
    }
	printf("+======================================+\n");
    printf("총 %d번의 게임을 했습니다. \n당신은 %d번 이겼습니다. 컴퓨터는 %d번 이겼습니다.\n", cnt_user, user_win, computer_win); //게임횟수, 사용자 이긴 횟수, 컴퓨터 이긴 횟수 출력
    printf("당신의 승률은 %.2lf%% 입니다.\n", (double) user_win / cnt_user * 100); // 승률 출력. 소수점 두번째 숫자까지 나오게 하기 위해서 %2lf를 넣어줌. int -> double로 자료형 바꿔줬다.

    return 0;
}
 

 


 

플레이 해보기

 

 

첫번째로 나오는 화면입니다.

 

 

 

게임 화면입니다.

게임이 종료되면 게임 횟수와, 사용자와 컴퓨터의 이긴 횟수, 승률을 알려줍니다.

 

1,2,3 아닌 수를 입력했을 때

 

 

잘못 입력했다고 알려주기

그리고 다시 실행


업무, 개발 중 발생한 이슈/고민 또는 이를 해결한 내용

1. while 반복 안되는 오류

분명히 저번에 자판기처럼 while문 넣고 돌렸는데 안되는 것이었다. 왜..? 왜.???"

라고 생각하다가 삽질하다 알아냈다. 두가지 이유 때문에 돌아가지 않았던 것

첫번째 -> while조건 초기화해주기. 변수를 0으로 초기화해줘야 한다.

두번째 -> 밑 코드에 컴퓨터가 다시 선택하도록 초기화 하는 부분을 넣어줘야 했던 것이다.

난수개념을 정확히 이해하고 적용해야 하는데 그냥 냅다 위에 #include <stdlib.h>만 쓰면 되는 줄 알았나보다.

==> 초기에 int computer_choice = rand() % 3 + 1; 코드를 사용하여 컴퓨터가 가위바위보 중 하나를 선택하고, 이후에 while문 안에서 다시 computer_choice = rand() % 3 + 1; 코드를 사용하여 컴퓨터가 다시 선택하도록 초기화해준다.

 

2. 컴퓨터가 scanf인식 안함

이건 실수.. &를 넣지 않았다. 꼼꼼하게 확인하는 습관을 기르자.

 

3. 승률 계산 오류

승률은 당연히 %로 나오면 실수형인데 그걸 확인 못했다. double과 float형 추가했다.

 

4. %표시하기

\는 \\처럼 두번 써서 표시하는 것처럼 %도 %%두번 쓰면 한번으로 출력된다고 했다. 구글짱

 

5. 엔터 오류

예쁘게 만들어 보려고 >> 를 scanf함수 뒤에 넣었더니 scanf 함수 이후에 문자열 뒤에 남아있는 개행 문자('\n') 때문에컴퓨터가 자꾸 프로그램을 종료시키는 거다. while문이 제대로 작동되지 않은 이유 두번째였음

진짜 이것때문에 삽질 두번했다.

-> getchar(); 함수를 집어넣어 개행문자를 소비해 줌으로써 해결.

 

 


오늘 새로 배운 내용

 

1. 난수 번호 추가 함수(추가 예정)


참고할 만한 레퍼런스 등

 

https://stackoverflow.com/questions/822323/how-to-generate-a-random-int-in-c/39475626#39475626

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

srand(time(NULL));   // Initialization, should only be called once.
int r = rand();      // Returns a pseudo-random integer between 0 and RAND_MAX.
 

rand()함수는 <stdlib.h>에서 유사한 난수를 반환한다. 반환되는 난수의 범위는 0부터 RAND_MAX까지이다.

srand(unsigned int seed)를 사용하여 시드를 설정할 수 있다.

 

rand()함수와 %연산자를 사용하여 다른 범위를 얻는 것이 일반적인 방법이다.

그러나 균일성이 다소 떨어질 수 있다.

/* 0과 19 사이의 무작위 int */
int r = rand() % 20;
 

 

밑에 답변도 읽어보기

 

+해석

컴퓨터는 보통 '진정한'랜덤 숫자를 반환하는 것이 어렵다. 이는 컴퓨터가 계산하는 난수가 예측 가능할 수 있다는 것을 의미한다. 이 난수가 암호화 키의 기반이 된다면, 키와 그에 따른 보안 메시지가 노출될 수 있다.

암호화로 보호되는 메시지가 안전하게 보호되도록 하기 위해서는, 암호학적으로 안전한 의사 난수 생성기(CSPRNG)가 필요합니다. 이를 사용해서 생성되는 숫자는 제3자가 예측하기 매우 어렵습니다. 이는 이러한 난수로부터 파생된 암호화 키가 굉장히 어려워져, 해당 키로 보호된 메시지가 안전해지기 때문입니다.

https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator

 

오.. 이것까지 내가 알 필요는 없을 것 같다. 하지만 굉장히 흥미롭다.

특이사항(아이디어 메모 등)

출처 입력

c언어에도 분명 파이썬 디렉토리나 리스트 개념이 있을 것 같은데 그 부분을 모르겠다.

아마 곧 배울 것 같긴 한데... 이걸 활용하면 더 쉽게 만들 수 있을 것 같다.

 


회고

출처 입력

c언어에도 <-> 같은 함수가 있었으면 좋겠다. 내가 이기면 쟤는 진거라고~~

코딩도 결국 수학 싸움같다. 나 수학못하는데 큰일남ㅋ

열심히 하자

 


해야 할 것

출처 입력

1. 짧게 함수에 대해 배웠는데 교재에 나와있는 함수 공부하기.

2. 함수 만들어 다시 만들어 보기.

3. 문자 복사하는 strcpy 공부해서 다시 만들어 보기.

4. 코드 줄이는 방법에 대해 고민해 보기.

5. 시간 남으면 하트로 별찍기 만들어보기.

 

 

 

ㅎㅎ 성공했다~~ 근데 하트가 아니라 무슨 여우 머리같다.

이제 진짜 공부해야겠다.

 

 

profile

소연의_개발일지

@ssoyxon

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!