숫자야구란?
-
사용되는 숫자는 0에서 9까지 서로 다른 숫자이다. 경우에 따라 0은 사용하지 않기도 한다.
-
숫자는 맞지만 위치가 틀렸을 때는 볼.
-
숫자와 위치가 전부 맞으면 스트라이크.
-
숫자와 위치가 전부 틀리면 아웃. "틀렸다"는 게 중요하다. 의외로 아웃이 제일 좋은 수인데, 틀린 숫자만 제끼고 남은 숫자끼리 조합하면 되므로 경우의 수가 팍팍 줄어들기 때문. 볼, 스트라이크는 숫자는 맞는 게 있으나 무슨 숫자가 맞았는지를 알 수가 없어 경우의 수를 더 생각해봐야 하지만 아웃은 틀린 숫자만 제거한 나머지만 생각해보면 어렵지 않기 때문. 2아웃이 나오면 더욱 좋다. 작정하고 숫자 예측을 이상하게 하지 않는 이상 3아웃 이상은 절대로 나오지 않는다.
-
물론 무엇이 볼이고 스트라이크인지는 알려주지 않는다.
-
두 숫자가 중복되면 경우의 수가 많아져서 그런지 중복 숫자는 잘 사용하지 않는다.
수정
1. 숫자는 1 ~ 9 까지 중복되지 않는 랜덤한 숫자를 사용한다.
2. 입력이 모두 틀리면 "안타!" 를 출력한다.
3. 하나라도 볼, 스트라이크에 해당되면 볼 : x 개 스트라이크 : x 개 로 갯수를 알려준다.
4. 총 입력기회는 10회이다.
5. 10번안에 맞추지 못하면 컴퓨터의 승리로 종료된다.
구현 코드
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
internal class Class
{
static void Main()
{
const char space = ' '; // 공백
int strike = 0; // 스트라이크 카운트
int ball = 0; // 볼 카운트
int count = 10; // 입력 기회
int[] number = new int[3]; // 적의 번호
int[] player = new int[3]; // 플레이어의 번호
bool isGaming = true; // 게임 중 여부
string str; // 문자열을 입력받고
string[] strarr; // 공백을 제거한 문자열을 저장
//=======중복 없는 난수 생성=====================================================================//
Random rand = new Random(); // 랜덤을 생성하기 위함.
for (int i = 0; i < 3; i++) // 일단 랜덤 숫자 생성
{
number[i] = rand.Next(1, 10);
}
// 중복 제거
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++) // 서로 비교하면서
{
if (i != j && number[i] == number[j]) // 자기 자신과는 비교 안함
{
number[j] = rand.Next(1, 10); // 중복이면 새 수 입력
j = 0; // 다시 재검사를 하기 위해 0으로 돌아감
}
}
}
//=======플레이어에게 숫자를 입력받기==================================================================//
while (isGaming)
{
Console.Write("숫자 3개를 입력하세요 : ");
str = Console.ReadLine();
if (!string.IsNullOrEmpty(str))
{
strarr = str.Split(space, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < 3; i++) // 플레이어 입력
{
player[i] = int.Parse(strarr[i]);
}
}
//=======입력받은 숫자 판정하기 ==================================================================//
for (int i = 0; i < 3; i++) // 공 체크
{
if (player[i] == number[i]) // 스트라이크 체크
{
strike++;
}
}
// 볼 체크
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
if(i != j && player[i] == number[j])
{
ball++;
}
}
}
//=======판정한 결과에 따른 결과를 출력==================================================================//
count--; // 기회 차감
if (strike == 0 && ball == 0) // 다 못 맞추면
{
Console.WriteLine("안타! | 남은 기회 : {0}\n", count);
}
else Console.WriteLine("스트라이크 : {0}, 볼 : {1} 남은기회 : {2}\n", strike, ball, count); // 뭐라도 있으면
//=======게임 종료=======================================================================================//
if (strike == 3 && count >= 1)
{
isGaming = false;
Console.WriteLine("플레이어 승리!");
return;
}
else if(count <= 0)
{
isGaming = false;
Console.WriteLine("컴퓨터 승리!");
return;
}
}
}
}
}
코드 상세 설명
선언부
char space = ' '; // 공백
int strike = 0; // 스트라이크 카운트
int ball = 0; // 볼 카운트
int count = 10; // 입력 기회
int[] number = new int[3]; // 적의 번호
int[] player = new int[3]; // 플레이어의 번호
bool isGaming = true; // 게임 중 여부
string str; // 문자열을 입력받고
string[] strarr; // 공백을 제거한 문자열을 저장
Console.ReadLine() 은 입력을 문자열의 형태로 받는다.
따라서 숫자 3개를 입력받기 위해 변환이 필요하고, 그 과정에서 필요한 변수 (space, str, strarr) 를 선언한다.
이외에 strike, ball 의 갯수를 저장할 변수, 전체 게임 기회를 저장할 count, 플레이어의 입력 player[] 와
컴퓨터의 숫자 number[] 를 선언한다.
중복 없는 난수 생성
//=======중복 없는 난수 생성=====================================================================//
Random rand = new Random(); // 랜덤을 생성하기 위함.
for (int i = 0; i < 3; i++) // 일단 랜덤 숫자 생성
{
number[i] = rand.Next(1, 10);
}
// 중복 제거
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++) // 서로 비교하면서
{
if (i != j && number[i] == number[j]) // 자기 자신과는 비교 안함
{
number[j] = rand.Next(1, 10); // 중복이면 새 수 입력
j = 0; // 다시 재검사를 하기 위해 0으로 돌아감
}
}
}
Random 클래스를 활용하여 난수를 생성할 수 있다.
우선, 배열의 3 원소를 모두 난수를 생성하여 준다.
그 후, 이중 반복문을 돌며, 나를 제외한 다른 숫자들과 비교하면서
만약에 같은 숫자라면 새로운 난수를 대입하여 준다.
다시 중복이 발생하지 않았는지 처음으로 돌아가 체크하기 위해 j = 0을 대입해 처음부터 체크한다.
숫자 입력 받기
Console.Write("숫자 3개를 입력하세요 : ");
str = Console.ReadLine();
if (!string.IsNullOrEmpty(str))
{
strarr = str.Split(space, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < 3; i++) // 플레이어 입력
{
player[i] = int.Parse(strarr[i]);
}
}
str 에 ReadLine() 을 활용하여 문자열을 입력받는다.
strarr 에는 Split 함수를 사용하여 공백을 제거한 문자열을 다시 대입한다.
이 때, 처음에 미리 선언했던 char space = ' '; 를 활용한다.
공백을 제거하기 위해
string[] str = Console.ReadLine().Split(' ');
더 짧게는 이 방법도 활용할 수 있다.
숫자 판정 하기
//=======입력받은 숫자 판정하기 ==================================================================//
for (int i = 0; i < 3; i++) // 공 체크
{
if (player[i] == number[i]) // 스트라이크 체크
{
strike++;
}
}
// 볼 체크
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
if(i != j && player[i] == number[j])
{
ball++;
}
}
}
먼저 스트라이크 여부를 체크한다. 스트라이크는 각 자리와 각 자리에 해당하는 숫자가 같으면 스트라이크 이므로,
조건에 맞게 작성한다.
두 번째로 볼체크를 한다. 볼은 자리는 다르지만 특정 값이 다른 자리에 존재하면 볼이다.
이중 반복문을 돌면서 나를 제외한 자리와 값을 비교하여 볼에 해당되면 ball 을 1씩 증가 시켜준다.
결과 출력하기
//=======판정한 결과에 따른 결과를 출력==================================================================//
count--; // 기회 차감
if (strike == 0 && ball == 0) // 다 못 맞추면
{
Console.WriteLine("안타! | 남은 기회 : {0}\n", count);
}
else Console.WriteLine("스트라이크 : {0}, 볼 : {1} 남은기회 : {2}\n", strike, ball, count); // 뭐라도 있으면
//=======게임 종료=======================================================================================//
if (strike == 3 && count >= 1)
{
isGaming = false;
Console.WriteLine("플레이어 승리!");
return;
}
else if(count <= 0)
{
isGaming = false;
Console.WriteLine("컴퓨터 승리!");
return;
}
판정 이후, strike 와 ball 이 모두 0 이라면 아무것도 맞추지 못한 것이므로,
"안타!" 를 출력하고 남은 기회(count) 를 알려준다.
둘 중 하나라도 1 이상이면 해당하는 스트라이크, 볼의 갯수를 출력한다.
루프를 돌다가, count 가 남아있는 상태에서 3 strike가 나올 경우,
플레이어의 승리로 판단하여 "플레이어 승리!" 를 출력한다.
count가 모두 소진될 경우 플레이어의 패배로 처리되며 "컴퓨터 승리!" 를 출력한다.
'C# 콘솔 & 윈도우폼' 카테고리의 다른 글
[C#] 콘솔창으로 만드는 텍스트RPG (0) | 2022.07.14 |
---|---|
[C# Window Form] 윈도우 폼으로 슈팅게임 구현하기 4 : 갤러그 (2) | 2022.07.02 |
[C#] 콘솔로 슈팅게임 구현하기 3 : 갤러그 (0) | 2022.07.02 |
[C#] 콘솔로 슈팅게임 구현하기 2 : 갤러그 (0) | 2022.07.01 |
[C#] 콘솔 창으로 슈팅게임 구현하기 1 : 갤러그 (2) | 2022.06.30 |