[사전캠프 10일차] 행맨-2
1. 오늘 학습 키워드
어제 만들다 실패한 행맨을... 다시. 만들어볼 것이다. 처음부터 코드를 뜯어고치는 한이 있더라도 완성은 해보도록 하자.
2. 오늘 학습 한 내용을 나만의 언어로 정리하기
지난 코드
//비밀문자 지정
char[] secretword = "hangman".ToCharArray();
//hangman 이라는 단어를 h/a/n/g/m/a/n 으로 쪼갬
char[] guessWord = new char[secretword.Length];
//guessWord라는 이름의 hangman의 문자와 같은 수의 방을 가진 배열 생성
bool guess=false; //불리언 생성. 왜 false인가?>정답을 다 맞추면 true가 될것
int x = 6; //6회의 횟수제한
//guesWord의 배열에 전부 _를 채워넣는 작업
for (int i=0; i<guessWord.Length; i++)
{
guessWord[i]= '_';
}
Console.WriteLine("알파벳을 입력해주세요.");
Console.WriteLine($"정답 현황: {new string(guessWord)}");
Console.WriteLine("정답이 아닌 알파벳을 넣으면 정답기회가 차감됩니다.");
do
{
Console.WriteLine($"정답 기회가 {x}회 남았습니다.");
char input;
bool OK; //입력한 데이터가 char값인지 확인
OK = char.TryParse(Console.ReadLine(), out input);//입력값을 input에 char 값으로 변경
bool Correct = false; //정답여부 체크용 >>bool guess와 중첩된 역할이 아닌지 확인
if (OK)
{
//입력한 알파벳이 secretWord와 같으면 OK, 다르면 기회 차감
for(int i = 0; i < secretword.Length; i++) //여기랑
{
if (secretword[i] == input) //조건을 Array Exists로 변경
//이것의 위치를 바꿔볼 예정이다 >for이 계속 반복되어 x가 급격하게 차감되는 걸 막음
{
guessWord[i] = input; //맞춘 알파벳은 공개시킴
secretword[i] = '0'; //알파벳이 아닌 숫자 0으로 바꾸어 중복정답 방지>>삭제하고 Array.Exists 사용
Console.WriteLine($"정답 현황: {new string(guessWord)}");
}
else
{
x--;
Console.WriteLine("틀렸습니다.\n"); //한 번에 확인 하도록 수정 필요
}
}
}
else //입력 값이 알파벳 문자 하나가 아님
{
Console.WriteLine("알파벳을 하나만 입력해주세요");
}
} while (x > 0 && !guess);
답변을 입력까지는 가능했다. x가 0이 되면 게임이 종료되기도 했다!
현재 생성되지 않은 것
1. 게임 완료 조건
2. 한 단어의 확인에 기회 6번이 다 날아가버리는 상태
수정하고 싶은 것
1. 현재는 기존 배열인 hangman을 맞는 것을 0으로 변경하면서 중복 오류를 막고있다.
>>가능한 데이터를 변경하지 않고 실행시키고 싶다 (Array.Exists 라는 걸 알아왔다)
Step 1. Array.Exists?
Array.Exists 함수는 무엇인가? 여지껏 한 번도 알아본 적 없는 걸 들고왔으니 간단히 알아보고 갈 생각이다.
Array는 배열( [ ] )을 의미한다. Exists는 존재한다는 뜻의 영어이다.
둘이 합해지면? 배열에 존재한다.는 뜻이 된다. 즉, 해당 함수는 내가 원하는 글자가 해당 배열 속에 들어있는지 확인하는 함수인 것이다.
사용법은 다음과 같다
Array.Exists(secretword, answer => answer == input)
(비교배열, 매개변수=>매개변수 ==비교대상)
즉 비교배열A 안에 비교대상a가 있는지, 확인하는 것이다.
Q: 그럼 매개변수의 역할은 뭔가요?
A: 솔직하게, 잘 모르겠습니다. (aka. 코딩시작 10일차..)
하지만 둘 다 같은 이름인 걸 보면 비교배열에 있는 각각의 요소들을 answer(원하는 이름으로 작성)라는 이름으로 바꾸어서 비교대상과 같은지 확인하는 것 같습니다.
코드 1
do
{
Console.WriteLine($"정답 기회가 {x}회 남았습니다.");
char input;
bool OK; //입력한 데이터가 char값인지 확인
OK = char.TryParse(Console.ReadLine(), out input);//입력값을 input에 char 값으로 변경
// bool Correct = false;는 필요없어진 불리언이므로 제거
if(Array.Exists(guessWord, element => element == input)) //입력값이 이미 입력한 적 있는지 확인, 중복방지
{
Console.WriteLine("이미 입력된 문자입니다. 다른 문자를 입력해주세요.");
}
else if (Array.Exists(secretword, answer => answer == input)) //입력값이 정답에 해당하고, 입력된 적이 없을 때
{
for(int i=0; i<secretword.Length; i++)
{
if (secretword[i] == input)
//secretword와 정확히 i가 동일할 때 input값이 들어가도록(없으면 모든 칸에 같은 단어가 들어간다)
{
guessWord[i] = input; // '_'를 정답 알파벳으로 변경
}
}
Console.WriteLine($"정답 현황: {new string(guessWord)}");
}
else if(!OK) //입력값이 문자가 아닐 경우
{
Console.WriteLine("알파벳 하나만 입력해주세요.");
}
else
{
x--; //오답이므로 횟수 차감
Console.WriteLine($"{input}은 해당되지 않습니다.");
}
if (guessWord == secretword) //secretword와 guessWord가 동일하게 되면 끊기
{
Console.WriteLine($"축하합니다! 정답을 맞췄습니다. 정답: { new string(guessWord) }");
break;
}
} while (x > 0 && !guess);
Console.WriteLine($"기회를 모두 사용하셨습니다. 정답: { new string(guessWord) }"); //횟수 전부 소모시.

지난 코드에서 해결되지 않은 것들을 신경쓰면서 새로 코드를 짰다.
그 결과,
현재 생성되지 않은 것
1. 게임 완료 조건
2. 한 단어의 확인에 기회 6번이 다 날아가버리는 상태(해결)
수정하고 싶은 것
1. 현재는 기존 배열인 hangman을 맞는 것을 0으로 변경하면서 중복 오류를 막고있다.(해결)
수정이 필요했던 3개중 2개는 해결이 되었다.
문제는 제일 중요한 게임 종료가 되지 않는다! 정확히는, 기회를 전부 소모할 경우에는 정상적으로 종료되지만, 정답을 모두 맞췄을 때는 '종료'되지 않는 현상이다.
심지어 불리언인 guess는 제대로 쓰지도 못했다...
원하는 것은 guess가 guessWord와 secretword와 같아지면 데이터값이 변하여 게임 종료, 끝! 을 선언하는 것이다.
그러려면 do-while문 안에 guess값을 지정해줘야 하는데, 탈출이 쉽지 않다..
guess = guessWord==secretword 로 했는데도 먹히지 않았고, 위처럼 if문으로 맞춰봤는데도 같은 배열이라고 인식하지 못하는 모양이다.
그렇게 팀원들에게 물어본 결과, 한 가지를 알게되었다.
배열은... ==로 동일하다는 걸 판정할 수 없다.
하지만 string 이라면 ==로 확인할 수 있다.
...char []를 string으로 형변환만 하면 되는 일이었다.
그렇게 해서 만들어진 최종코드는 아래에 있다. (정상적으로 동작한다. 그 어떤 문제도 없다!)
최종 코드
//비밀문자 지정
using Systehttp://m.IO.Pipes;
char[] secretword = "hangman".ToCharArray();
//hangman 이라는 단어를 h/a/n/g/m/a/n 으로 쪼갬
char[] guessWord = new char[secretword.Length];
//guessWord라는 이름의 hangman의 문자와 같은 수의 방을 가진 배열 생성
//guesWord의 배열에 전부 _를 채워넣는 작업
for (int i = 0; i < guessWord.Length; i++)
{
guessWord[i] = '_';
}
bool guess =false; //불리언 생성, 정답 판독용
int x = 6; //6회의 횟수제한
//초기 출력 텍스트
Console.WriteLine("행맨게임을 시작합니다!");
Console.WriteLine("정답이 아닌 알파벳을 넣으면 정답기회가 차감됩니다.");
Console.WriteLine("알파벳을 입력해주세요.");
Console.WriteLine($"정답 현황: {new string(guessWord)}");
do
{
//매 입력 시 정답기회가 얼마나 남았는지 확인
Console.WriteLine($"정답 기회가 {x}회 남았습니다.");
char input;
bool OK; //입력한 데이터가 char값인지 확인
OK = char.TryParse(Console.ReadLine(), out input); //입력값을 input에 char 값으로 변경
if(Array.Exists(guessWord, element => element == input)) //입력값이 이미 입력한 적 있는지 확인, 중복방지
{
Console.WriteLine("이미 입력된 문자입니다. 다른 문자를 입력해주세요.");
}
else if (Array.Exists(secretword, answer => answer == input)) //입력값이 정답에 해당하고, 입력된 적이 없을 때
{
for(int i=0; i<secretword.Length; i++)
{
if (secretword[i] == input) //secretword와 정확히 i가 동일할 때 input값이 들어가도록
{
guessWord[i] = input;
}
}
Console.WriteLine($"정답 현황: {new string(guessWord)}");
}
else if(!OK) //입력값이 문자가 아닐 경우
{
Console.WriteLine("알파벳 하나만 입력해주세요.");
}
else
{
x--; //오답이므로 횟수 차감
Console.WriteLine($"{input}은 해당되지 않습니다.");
}
//두 배열의 비교를 위해 new string()을 이용하여 string 값으로 변환
string secretW = new string(secretword);
string guessW = new string(guessWord);
if (guessW == secretW) //두 배열이 같을 경우(=정답) 동작
{
guess= true;
}
} while (x > 0 && !guess);
if (guess) //guess = true 가 되어 나왔을 경우
{
Console.WriteLine($"정답입니다! 정답: {new string (secretword)}");
}
else //x=0이 되어 나왔을 경우.
{
Console.WriteLine($"기회를 모두 사용하셨습니다. 정답: {new string(secretword)}");
}

3. 학습하며 겪었던 문제점 & 에러
- 문제&에러에 대한 정의
1. x값이 반복 확인에 한 번에 날아가버리는 상황(반복문 안에 들어있어서 반복 처리 된 것)
2. 게임이 완료되었음에도 종료가 안되던 문제(조건을 지정하지 못하니 guess =true 변환이 안됨)
3. 문제에서 단어를 변경하기 위해 secretword의 데이터를 변경시켜야 했음(극 초기. 어제까지의 문제)
- 내가 한 시도
1. x-- 의 위치를 내부 반복문에서 빼냈다. (지독한 실수였다.) 또한, 전반적으로 함수의 구성을 뒤바꾸었다.
2. 머리를 싸매다가 해결이 되지않아 팀원들의 지성을 빌렸다. (감사합니다)
3. Array.Exists 를 이용했다.
- 해결 방법/새롭게 알게 된 점
2>>char [ ] 은 ==로 동일한지 비교가 안된다.
string은 ==로 비교가 된다.
그렇기 때문에 char [] 배열을 string으로 형변환 하여 동일한지 확인하면 된다.
그럼 두 string값이 같을 때, guess=true;로 변환시켜 반복문을 탈출할 수 있다.
4. 내일 학습 할 것은 무엇인지
우선 숫자야구를 만들어 볼 것이다. (하루만에 끝낼 수 있으면 좋겠다...)
다음주 월요일: 아무 게임이나 하나를 집어서, 게임 속 상호작용을 분석해볼 예정이다.