[C++] 연습 문제 - 간단한 가위바위보 게임 만들기
👻 난수 생성 함수 - rand()
컴퓨터와 가위바위보를 하는 게임을 만들어보려면, 우선 난수 생성 함수를 알아야한다. 그래야 비교해서 누가 이기고 졌는지를 알 수 있기 때문이다. rand()
라는 함수를 사용하면 난수를 생성할 수 있다.
// 난수 생성 함수
int value = rand(); // 0 ~ 32767
// 범위 설정 (0 ~ (n-1))
int value2 = rand() % n;
// 범위 설정2 (1 ~ n)
int value3 = (rand() % n) + 1;
수가 어떻게 생성되는 지 출력해보자.
int main()
{
cout << rand() << endl;
cout << rand() << endl;
cout << rand() << endl;
cout << rand() << endl;
cout << rand() << endl;
}
그냥 이렇게만 쓰고 실행시켜보면 프로그램을 백번 재실행 시켜도 항상 동일한 값이 나오게된다.
- 결과
사실상 컴퓨터는 규칙이 없는 랜덤 숫자를 생성해낼 수 없다. 첫 특정값이 정해지면 그 수에 다양한 연산을 하는, 그러한 일련의 과정들을 거쳐서 다음 난수를 생성하는 방식인데 언뜻보면 랜덤한 숫자처럼 보여서 그냥 컴퓨터상의 랜덤이라 생각하면 될 듯하다.
결국 첫 번째 값을 구하는 게 중요한건데 srand()
함수를 통해 시드값을 설정해야한다. 매번 같은 값을 시드값으로 넣을 순 없으니 괄호 안에 현재 시간을 뜻하는 time(0)
을 넣어 매번 다르게 지정해주면 프로그램을 실행할 때마다 각각 다른 시드값으로 난수를 생성할 수 있게 된다.
int main()
{
// 시드 설정
srand(time(0));
cout << rand() << endl;
cout << rand() << endl;
cout << rand() << endl;
cout << rand() << endl;
cout << rand() << endl;
}
이렇게 시드를 설정해주면 매번 다른 값이 나오게 된다.
👻 가위바위보 만들기
유저가 입력하면 컴퓨터와 비교해 승패를 결정해주는 게임을 만들어보기.
(유효한 값이 입력되면 게임은 무한반복되고, 유효하지 않은 값이 입력되면 게임은 종료된다.)
- 내가 푼 코드
#include <iostream>
using namespace std;
int main()
{
while(true)
{
srand(time(0));
// 1 2 3
int comInput = (rand() % 3) + 1;
int userInput;
cout << "가위(1) 바위(2) 보(3) 골라주세요!" << endl;
cout << "> ";
cin >> userInput;
if (userInput > 3)
break;
switch (userInput)
{
case 1:
cout << "가위(유저)";
break;
case 2:
cout << "바위(유저)";
break;
case 3:
cout << "보(유저)";
break;
}
cout << " vs ";
switch (comInput)
{
case 1:
cout << "가위(컴퓨터)";
break;
case 2:
cout << "바위(컴퓨터)";
break;
case 3 :
cout << "보(컴퓨터)";
break;
}
cout << " 결과 : ";
// 1, 2 -> 2 // -1 패
// 1, 3 -> 1 // -2 승
// 2, 1 -> 2 // 1 승
// 2, 3 -> 3 // -1 패
// 3, 1 -> 1 // 2 패
// 3, 2 -> 3 // 1 승
if (userInput == comInput)
{
cout << "무승부입니다!" << endl;
}
else
{
int diff = userInput - comInput;
if (diff == -1 || diff == 2)
cout << "졌습니다!" << endl;
else
cout << "이겼습니다!" << endl;
}
}
}
- 다른 답
int main() { srand(time(0)); const int SCISSORS = 1; const int ROCK = 2; const int PAPER = 3; while (true) { cout << "가위(1) 바위(2) 보(3) 골라주세요!" << endl; cout << "> "; // 컴퓨터 int comInput = (rand() % 3) + 1; // 유저 int userInput; cin >> userInput; if (userInput == SCISSORS) { switch (comInput) { case SCISSORS: cout << "가위(유저) vs 가위(컴퓨터) 결과 : 무승부입니다!" << endl; break; case ROCK: cout << "가위(유저) vs 바위(컴퓨터) 결과 : 졌습니다!" << endl; break; case PAPER: cout << "가위(유저) vs 보(컴퓨터) 결과 : 이겼습니다!" << endl; break; } } else if (userInput == ROCK) { switch (comInput) { case SCISSORS: cout << "바위(유저) vs 가위(컴퓨터) 결과 : 이겼습니다!" << endl; break; case ROCK: cout << "바위(유저) vs 바위(컴퓨터) 결과 : 무승부입니다!" << endl; break; case PAPER: cout << "바위(유저) vs 보(컴퓨터) 결과 : 졌습니다!" << endl; break; } } else if (userInput == PAPER) { switch (comInput) { case SCISSORS: cout << "보(유저) vs 가위(컴퓨터) 결과 : 졌습니다!" << endl; break; case ROCK: cout << "보(유저) vs 바위(컴퓨터) 결과 : 이겼습니다!" << endl; break; case PAPER: cout << "보(유저) vs 보(컴퓨터) 결과 : 무승부입니다!" << endl; break; } } else { // 예외의 값이 나오면 반복문(while(true)) 탈출 break; } } }
뭔가 내 코드가 더 간결해 보이는 것 같기도 하고..🤔?
- 결과
🌱 승률 추가하기
만들어 둔 가위바위보 게임에 현재 승률을 추가해보기 (단, 무승부는 제외)
int main()
{
// 조금만 수정해주기
srand(time(0));
const int SCISSORS = 1;
const int ROCK = 2;
const int PAPER = 3;
int round = 0;
int win = 0;
while(true)
{
// 1 2 3
int comInput = (rand() % 3) + 1;
int userInput;
cout << "Round : " << round << ", win : " << win << endl;
cout << "가위(1) 바위(2) 보(3) 골라주세요!" << endl;
float winrate = 0;
if (round > 0)
winrate = (win / (float)round) * 100;
cout << "> 현재 승률 : " << winrate << "%" << endl;
cout << "> ";
cin >> userInput;
if (userInput > 3)
break;
switch (userInput)
{
case SCISSORS:
cout << "가위(유저)";
break;
case ROCK:
cout << "바위(유저)";
break;
case PAPER:
cout << "보(유저)";
break;
}
cout << " vs ";
switch (comInput)
{
case SCISSORS:
cout << "가위(컴퓨터)";
break;
case ROCK:
cout << "바위(컴퓨터)";
break;
case PAPER:
cout << "보(컴퓨터)";
break;
}
cout << " 결과 : ";
// 1, 2 -> 2 // -1 패
// 1, 3 -> 1 // -2 승
// 2, 1 -> 2 // 1 승
// 2, 3 -> 3 // -1 패
// 3, 1 -> 1 // 2 패
// 3, 2 -> 3 // 1 승
if (userInput == comInput)
{
cout << "무승부입니다!" << endl;
}
else
{
int diff = userInput - comInput;
if (diff == -1 || diff == 2)
cout << "졌습니다!" << endl;
else
{
cout << "이겼습니다!" << endl;
win++;
}
cout << endl;
round++;
}
}
}
정수 / 정수를 하게되면 소수점 아래는 자동으로 날아가기 때문에 주의해야한다. 둘 중 하나를 실수로 변환하여 나누거나 연산 순서를 바꿔서 알맞은 근사값을 구할 수 있다.
- 결과
👻 글을 마치며
이번 시간엔 가위바위보 게임을 간단하게 만들어보았다. 간단한 문제도 많은 생각을 해야 효율적으로 만들 수 있다는 것을 느꼈다. 그래서 어떻게하면 더 짧고 간결하며 효율적으로 만들 수 있을지 고민하느라 시간이 조금 걸렸던 것 같다. 그래도 직접 코드를 짜보니 코드 흐름을 생각하고 보는 능력은 향상된 것 같다. 이제 다른 연습 문제도 열심히 풀면서 문제를 보자마자 머릿속에서 풀릴 수 있도록 더 노력해야겠다.
Leave a comment