오늘은 좀 빠르게 빠르게 진행해보자.
이번 기회에 반복문에 대해 공부해보자.
for문은 저번 시간에 설명했으니 패스하고 while과 do while문을 공부해보자
while(조건문)
{
반복문;
}
while문은 보통 위의 형식을 가지며
조건문이 참일 경우 반복 문을 반복하게 되는 특징이 있다.
따라서 while문 내부에 탈출을 위한 구문을 추가하지 않으면 무한 루프가 되는 경우가 상당히 많고
for문 처럼 사용하고 싶다면 조건문에 i < 100 반복문의 끝에 i ++을 붙이면
매 루프마다 i에 1씩 더해지게 되고 100이 되는 순간 조건을 불만족하기 때문에 반복문에서 탈출하게 된다.
do
{
반복문
}
while (조건문);
do - while 문의 경우는 위의 형식을 가지며
최초의 1회 반복문은 무조건 실행되는 특징을 가지고 있다.
while 문과 마찬가지로 조건문을 만족하는 동안 반복 실행되며 while 뒤에 반복문이 붙는게 아니라
do 뒤에 중괄호 안에 반복문을 넣고 그 반복문이 실행되는 원리이다.
자 이제 for, while, do-while을 사용해 작성해보자.
using System;
int j = 0;
int k = 0;
for(int i = 0; i <=100; i++)
{
if (i % 2 == 1) Console.WriteLine(i);
}
while (j < 100)
{
if (j % 2 == 1) Console.WriteLine(j);
j++;
}
do
{
if (k % 2 == 1) Console.WriteLine(k);
k++;
}
while (k < 100);
솔직히 문제는 별로 어렵지 않다.
저번에 짝수를 구해봤듯이 홀수는 2로 나누었을 때 나머지가 1이 남기 때문
배열과 반복문을 배웠으니 빠르게 작성해보자.
숫자를 일일이 넣어주기 귀찮으니 랜덤 함수와 직접 함수를 만들어서 실행해보자.
using System;
Random random = new Random();
string input = Console.ReadLine();
int sum = 0;
int average = 0;
sum = Plus(RandomGen(Convert.ToInt32(input))); //받아온 글자를 정수형으로 변환 후 함수 실행
average = sum / Convert.ToInt32(input);
Console.WriteLine("총 합계는 "+sum+"이며, \r\n평균은 "+average+ " 입니다." );
int[] RandomGen(int n) //n의 길이를 가진 배열생성 (랜덤한 내부 값)
{
int[] numbers = new int[n]; //new를 통한 배열선언
for (int i = 0; i < n; i++)
{
numbers[i] = random.Next(1, 11); //1에서 10 사이의 랜덤 값 집어넣기
Console.WriteLine(n + "개 중 " + (i + 1) + "번째에 " + numbers[i] + " 값이 삽입되었습니다.");
}
return numbers; //배열 반환
}
int Plus(int[] n) //배열을 받아서 배열의 길이만큼 반복하여 더해주기
{
int sum = 0;
for (int i = 0; i < n.Length; i++)
{
sum += n[i];
}
return sum;
}
쉬운 코드 어렵게 만들기 장인
new를 통해 배열을 생성하면 길이를 지정해주지 않아도 유동적으로 그 길이를 지정해 줄 수 있게된다.
이를 응용해 처음에 숫자를 받아오면 그 숫자의 길이만큼 배열을 만들어주고
그 안에 랜덤한 1 ~ 10의 값을 넣어준 다음 몇 번째에 어떤 숫자가 들어갔는지 표시하고
그에 대한 총 합과 평균을 구해주는 코드를 작성했다.
실행해보면?
문자가 삽입되는 경우도 있겠지만 이번엔 고려하지 않고 만들었다.
숫자를 입력받으면 그에 대한 팩토리얼 값을 출력해보자.
이번엔 진짜 쉽게 함수고 뭐고 다 버리고 반복문만 이용해서 만들어보자
팩토리얼의 가장 중요한 점은 i를 0으로 시작하면 뭐든 0을 곱하면 0이 되니까
시작은 int i = 1로 설정해두는게 중요하다. 또는 i가 0일때 실행되지 않게 하면 된다.
using System;
Console.WriteLine("숫자를 입력해주세요.");
int n = Convert.ToInt32(Console.ReadLine());
int factorial = 1;
for(int i = 0; i <= n; i++) //n까지 곱해야하기 때문에 작거나 같을 때로 설정
{
if (i == 0) continue; //i가 0이라면 아래 구문을 실행하지 않음
factorial *= i;
}
Console.WriteLine(factorial);
실행해보면?
1 * 2 * 3 * 4 * 5니까 20 * 6 = 120 잘 나오는 것 같다.
컴퓨터가 랜덤한 숫자를 생성하게 하고 그 숫자를 맞춰보자.
위에서 사용했던 랜덤 함수를 통해 랜덤한 숫자를 만들게 하고 입력을 통해 그 숫자를 맞춰보자
우선 컴퓨터는 1에서 100사이의 난수를 생성하게 하고
우리가 입력한 값보다 높은지 적은지 힌트를 주게 만들어보자.
using System;
Random random = new Random();
int goal = random.Next(1, 101);
bool isCorrect = false;
while(isCorrect == false)
{
Console.WriteLine("예상 값을 입력해주세요 (1-100)");
int a = Convert.ToInt32(Console.ReadLine());
if (a == goal)
{
Console.WriteLine("정답입니다.");
isCorrect = !isCorrect;
}
else
{
if (a > goal)
Console.WriteLine("조금 더 아래로!\r\n");
else Console.WriteLine("조금 더 위로!\r\n");
}
}
부울 변수를 통해 조건을 만족하면 부울 변수값을 뒤집고 게임을 끝내게 만들자
이중 조건문을 사용했는데 아래 조건문을 보면 엥 숫자 맞춰도 조금 더 위로! 나오는거 아닌가요?
하지만 위에서 이미 조건문을 통해 else인 경우에만 아래로 빠져나가게 했기 때문에
숫자를 맞추면 아래에 있는 구문을 참조하지 않는다.
실행해보면?
이번에는 이중 반복문을 사용해서 구구단을 출력해보자.
구구단은 1~9 * 1~9이다.
즉 반복문을 두 개를 중첩해서 9번씩 실행되게 만들면 81번 실행되는데
이걸로 구구단을 구현해보자.
진짜 세상 간단하고 짧게 만들어볼 수 있다.
가로 세로를 바꾸고 싶다면? i와 j의 배치만 바꾸어주면 된다.
이 경우에는 Console.Write()와 Console.WriteLine()의 차이가 보이는데
Console.WriteLine()의 경우 한 줄을 출력하면 자동으로 줄 바뀜이 되는 반면
Console.Write()는 따로 줄 바꿈을 넣어줘야 작동한다.
다음
위에서 만들었던 랜덤 배열 만들기 함수를 가져와서 작성해보자.
여태까지 배열과 반복문을 같이 사용하는 방법은 정말 여러번 사용했었다.
마찬가지로 최대숫자 변수와 최소숫자 변수를 넣고 모든 배열을 for 문을 통해 단순비교하여 크면 최대숫자 작으면 최소숫자에 넣어주자.
using System;
Random random = new Random();
string input = Console.ReadLine();
int[] arr = RandomGen(Convert.ToInt32(input));
int maxNum = 0;
int minNum = 100;
for (int i = 0; i < Convert.ToInt32(input) ; i++)
{
if (maxNum < arr[i]) maxNum = arr[i];
if (minNum > arr[i]) minNum = arr[i];
}
Console.WriteLine("최대값은 " + maxNum + " 이며 최솟값은 " + minNum + " 입니다.");
int[] RandomGen(int n) //n의 길이를 가진 배열생성 (랜덤한 내부 값)
{
int[] numbers = new int[n]; //new를 통한 배열선언
for (int i = 0; i < n; i++)
{
numbers[i] = random.Next(1, 101); //1에서 100 사이의 랜덤 값 집어넣기
Console.WriteLine(n + "개 중 " + (i + 1) + "번째에 " + numbers[i] + " 값이 삽입되었습니다.");
}
return numbers; //배열 반환
}
실행해보면?
잘 실행되는 걸 볼 수 있다.
근데 사실 Convert.ToInt32(input)보다
애초에 input 변수를 정수형으로 한 후 받아오는 값을 컨버트 해주는게 더 작성하기 쉬운거 아니냐고 묻는다면
그 말이 맞습니다.
string input = Console.ReadLine(); //이거 보단
int input = Convert.ToInt32(Console.ReadLine()); //이게 짧고 좋잖아요
근데 그냥 위에 쓴거 복사 붙여넣기 하다보니까 깜빡하고 있었네요
그리고 이제와서 쓰는거긴 한데 입력을 받으면 숫자인지 문자인지 구별해주는 재귀함수를 만들고
숫자면 반환시켜주는 함수를 만들어서 작성하는게 더 나았을 것 같기도....
이제라도 바꿔봅시다.
using System;
Random random = new Random();
int input = ReturnInt(Console.ReadLine());
int[] arr = RandomGen(input);
int maxNum = 0;
int minNum = 100;
for (int i = 0; i < input ; i++)
{
if (maxNum < arr[i]) maxNum = arr[i];
if (minNum > arr[i]) minNum = arr[i];
}
Console.WriteLine("최대값은 " + maxNum + " 이며 최솟값은 " + minNum + " 입니다.");
int[] RandomGen(int n) //n의 길이를 가진 배열생성 (랜덤한 내부 값)
{
int[] numbers = new int[n]; //new를 통한 배열선언
for (int i = 0; i < n; i++)
{
numbers[i] = random.Next(1, 101); //1에서 100 사이의 랜덤 값 집어넣기
Console.WriteLine(n + "개 중 " + (i + 1) + "번째에 " + numbers[i] + " 값이 삽입되었습니다.");
}
return numbers; //배열 반환
}
int ReturnInt(string a) //입력된 문자열이 숫자라면 반환, 아니라면 재입력
{
int b;
bool isSuccess = int.TryParse(a, out b);
if (isSuccess) return b;
else
{
Console.WriteLine("숫자가 아닙니다.");
return ReturnInt(Console.ReadLine());
}
}
실행해보면?
잘 실행되는걸 확인 할 수 있다.
이렇게 쓰다가 코드 보다가 고민하면
아 좀 더 잘 쓸 수 있을 것 같은데 하는 부분이 보인다.
저~번 시간에 문자열은 문자의 배열이라고 했던 거 기억이 나는가?
이를 통해 간단한 행맨 게임을 만들어보자
함수를 통해 문자를 입력받으면 문자열과 비교하고 맞는 부분에 글자를 보이게 구현해보자.
그 외에도 미리 단어를 입력해두고 그 중에서 랜덤하게 문제를 내는 부분도 같이 구현해보자.
우선 행맨 게임이란 목표로 하는 한 단어를 보이지 않게 설정하고 알파벳을 하나하나 던지면서
해당 단어를 맞춰나가는 게임이다.
우선 입력받은 글자가 한 글자의 문자인지 확인해보자.
char IsChar(string a)
{
char x;
bool isSuccess = char.TryParse(a, out x);
if (isSuccess) return x;
else
{
Console.WriteLine("알파벳 한 글자만 입력해주세요.");
IsChar(Console.ReadLine());
}
}
그 다음 입력받은 글자를 정답과 비교하는 함수를 만들어주고
char[] IsCorrect(char[] a, char[] b, char c)
{
bool correct = false;
for(int i = 0;i < a.Length;i ++)
{
if (a[i] == c)
{
b[i] = c;
correct = true;
}
}
if (correct == false) chance--;
return b;
}
이렇게 보니 헷갈리니까 전문을 살펴보자
using System;
Random random = new Random();
char[] secretWord = RandomWord(); //정답은 랜덤단어
char[] hidden = new char[secretWord.Length]; //정답을 같은 길이로 숨겨줌
int chance = 6;
for(int i = 0; i < hidden.Length; i++) //숨겨진 단어를 _로 표시함
{
hidden[i] = '_';
}
while(chance >= 0) //찬스가 남아있다면 지속
{
bool win = true;
for (int i = 0; i < hidden.Length; i++)
{
Console.Write(hidden[i]); //반복 시 마다 맞춰야 할 글자를 재표시
}
if (chance == 0)
{
Console.WriteLine("\r\n모든 기회를 소진하였습니다. 게임을 종료합니다.");
break; //찬스가 없다면 게임종료
}
else
{
Console.Write("\r\n남은 기회는 " + chance + "회 입니다.\r\n");
}
hidden = IsCorrect(secretWord, hidden, IsChar(Console.ReadLine()));
for(int i = 0;i < hidden.Length; i++)
{
if (hidden[i] != secretWord[i])
{
win = false;
}
}
if (win)
{
Console.WriteLine("\r\n당신이 승리했습니다! 게임을 종료합니다.");
break;
}
}
char[] IsCorrect(char[] a, char[] b, char c)
{
bool correct = false;
for(int i = 0;i < a.Length;i ++)
{
if (a[i] == c)
{
b[i] = c;
correct = true;
}
}
if (correct == false) chance--;
return b;
}
char[] RandomWord() //문제로 출제될 랜덤 단어들의 모임
{
string[] strings = { "honet", "hangman", "electric", "desk", "monitor" };
return strings[random.Next(strings.Length)].ToCharArray();
}
char IsChar(string a) //문자인지 확인해주는 함수
{
char x;
bool isSuccess = char.TryParse(a, out x);
if (isSuccess) return x;
else
{
Console.WriteLine("알파벳 한 글자만 입력해주세요.");
return IsChar(Console.ReadLine());
}
}
시작과 동시에 랜덤 단어를 정답으로 불러온 후
같은 길이의 숨겨진 단어를 만들어 언더바로 도배해준다.
찬스가 하나라도 남았다면 반복하게 반복문을 설정해주고
매 반복 시작시 마다 승리 조건을 True로 해주고
글자가 하나라도 틀렸다면 False로 바꾸어 게임을 지속되게 만들어주었다.
입력한 글자가 정답과 일치한다면 해당 부분을 입력한 알파벳으로 바꿔주고
모든 글자가 정답과 일치한다면 승리 조건을 true로 유지시켜 게임을 종료되게 만들었다.
실행해보자.
이번엔 일부러 틀려보자
보면 실행시마다 랜덤한 단어가 정답이 되며 글자 수에 맞춰 언더바를 생성하고
정답이라면 해당 부분을 치환하는 것을 볼 수 있다.
오늘 TIL THE END
0909 TIL - 깃 허브와 프로젝트 (1) | 2024.09.09 |
---|---|
0906 TIL - C# 기초 문법 5 (2) | 2024.09.06 |
0904 TIL - C# 기초문법 3 (0) | 2024.09.04 |
0903 TIL - C# 기초 문법 2 (0) | 2024.09.04 |
0902 TIL - C# 문법 기초 1 (0) | 2024.09.02 |