- 과제 내용 이해 어려워 일반적인 규칙의 야구 게임을 기준으로 작성했습니다.
- 숫자 야구 게임을 작성하세요. 컴퓨터가 3자리의 숫자를 선택하면 사용자가 그 숫자를 맞추는 게임을 구현하세요. 각 자리의 숫자를 비교하여 스트라이크와 볼의 개수를 출력합니다.
- 숫자 야구 게임 설명
- 숫자 야구 게임은 3자리의 숫자를 맞추는 게임입니다. 컴퓨터가 고른 3자리 숫자는 모두 다른 숫자로 이루어져 있습니다. 사용자는 3자리 숫자를 입력하고, 컴퓨터는 입력한 숫자와 자리수를 비교하여 스트라이크와 볼의 개수를 알려줍니다.
- 스트라이크: 숫자와 자리수가 모두 맞는 경우
- 볼: 숫자는 맞지만 자리수가 다른 경우
예상 출력)
Enter your guess (3 digits): 123 0 Strike(s), 0 Ball(s)
Enter your guess (3 digits): 456 0 Strike(s), 0 Ball(s)
Enter your guess (3 digits): 789 1 Strike(s), 2 Ball(s)
Enter your guess (3 digits): 987 3 Strike(s), 0 Ball(s)
Congratulations! You've guessed the number in 4 attempts.
고민했던 부분
- 4자리 숫자 게임도 있으므로 확장성을 고려하여 정답 숫자 배열 길이를 변수로 생성
- 중복 숫자 방지를 위해 0~9숫자를 문자열로 만들어 하나씩 선택하도록 로직 구성
- 문자열 쉽게 비교하기 위해 만들어진 정답 숫자 배열을 문자열로 변환
- 사용자 입력 받는 부분 길어져서 함수로 분리
- 사용자 입력은 유효한 입력을 받을 때까지 반복
- 볼과 스트라이크 변수는 매반복에서 0으로 초기화
- 입력 문자열과 정답 문자열 비교 가독성 위해 함수로 분리
- 스트라이크와 볼 변수를 참조로 넘기기
- 결과 출력 후 스트라이크와 정답문자열 길이 같으면 프로그램 종료(정답 맞췄는지 확인하는 변수 생략)
놓쳐서 고생한 부분...
- 난수 생성 로직에서 자꾸 이상한 값이 들어가서 디버깅해보니 숫자의 아스키코드 값을 받아오고 있었다!
int num = random.Next(0, digits.Length);
targetNumber[i] = digits[num];
/*********** 야구 게임 ***********/
/* 게임 초기 설정 */
// 컴퓨터가 랜덤한 3자리 숫자 정함
int length = 3;
Random random = new Random();
int[] targetNumber = new int[length]; // 랜덤한 숫자 배열
string digits = "0123456789"; // 중복 방지용 배열
// 중복 없이 숫자 입력 받기
for (int i = 0; i < length; i++)
{
int num = random.Next(0, digits.Length); // 0 ~ 선택숫자배열 사이의 난수 생성
targetNumber[i] = digits[num] - '0'; // 난수를 인덱스로 i번째 자리에 저장
digits = digits.Remove(num, 1); // 중복 방지하여 사용한 숫자 제거
}
// 정해진 랜덤한 숫자 배열을 문자열로 전환
string targetNum = string.Concat(targetNumber);
int attempts = 0; // 시도 횟수
/* 게임 실행부 */
while (true)
{
// 사용자 입력 받기
string input = InputNum();
if (input == null)
{
Console.WriteLine("Input Error...");
return;
}
// 매 반복시 초기화
int ball = 0;
int strike = 0;
// 사용자 입력 숫자와 정답 숫자 비교
CompareNum(input, ref strike, ref ball);
attempts++;
// 결과 출력
Console.WriteLine($"{strike} Strike(s), {ball} Ball(s)");
if (strike == length)
{
Console.WriteLine($"Congratulations! You've guessed the number in {attempts} attempts.");
return;
}
}
/* 함수부 */
// 사용자가 입력한 숫자 유효성 체크하고 문자열로 반환하는 함수
string InputNum()
{
while (true)
{
Console.Write($"Enter your guess ({length} digits): ");
string input = Console.ReadLine();
if (input.Length != length) // 3자리 아니면 개행 후 반복
{
Console.WriteLine();
continue;
}
// 문자열이 정수인지 확인
int temp;
bool isNum = int.TryParse(input, out temp);
if (isNum)
return input;
}
// 예상치 못한 에러 발생하는 경우 null 반환
return null;
}
// 입력된 숫자와 정답 숫자 비교하여 스트라이크와 볼 계산
void CompareNum(string num, ref int strike, ref int ball)
{
for (int i = 0; i < length; i++)
{
// 추측한 숫자와 정답 숫자의 값과 자리가 같으면
if (num[i] == targetNum[i])
{
strike++; // 스트라이크 증가
}
// 추측한 숫자와 정답 숫자 같은 같으나 자리가 다르면
// (이전 조건은 만족하지 않지만 숫자가 정답 숫자열에 포함됨)
else if (targetNum.Contains(num[i]))
{
ball++; // 볼 증가
}
}
}'내일배움캠프 > 달리기반' 카테고리의 다른 글
| [내배캠][Unity_6기][과제] 7. 행맨 게임 (0) | 2024.09.01 |
|---|---|
| [내배캠][Unity_6기][과제] 6. 배열의 최대, 최소 찾기 (0) | 2024.09.01 |
| [내배캠][Unity_6기][과제] 5. 구구단 출력 (0) | 2024.09.01 |
| [내배캠][Unity_6기][과제] 4. 숫자 맞추기 게임 (0) | 2024.09.01 |
| [내배캠][Unity_6기][과제] 3. 팩토리얼 계산 (0) | 2024.09.01 |