2023.04.03 학습일지
1. 개발 진행 및 완료상황. 무엇을 더 하면 좋을지
총 3번을 걸쳐서 숫자야구 코드를 수정했다. 분명 가위바위보 게임 하는 것처럼 쉽겠지 했는데
더 어려운 기분~
그래도 코드완성은 했고, 이 방법 말고 다른 분들의 코드를 보면서 다른 방식으로 구현하는걸 배워볼 계획이다.
내 방식보다 훨씬 쉬운 방법이 분명 존재할 것이다!
처음에 그린 순서도
그런데 생각보다 이런 순서도는 허접하다는 것을 깨달았다..
함수를 만들어서 컴퓨터, 사용자의 값을 반환하고 싶은데
return값을 두개 이상 하려면 포인터를 배워야 한다고 한다.(출처 구글)
그래서 포기!
그래도 함수를 포기못해서 이렇게 만들어 봤다.
백, 십, 일의 자리 추출하기 테스트
#include <stdio.h>
int main(void){
int i = 365;
int num1, num2, num3;
num1 = i / 100;
num2 = i / 10 % 10;
num3 = i % 10;
printf("%d %d %d", num1, num2, num3);
}
3 6 5 의 숫자라면 -> 365로 만들어서 -> 비교할때는 다시 3 6 5로 반환하는 방식이다!
이것때문에 시간을 많이 잡아먹었다. 이제 포인터가 배우고 싶어졌다..
출력 결과
3 6 5
잘 출력된다!
이걸 그대로 컴퓨터 난수 숫자와 사용자 숫자에 적용했다.
2. 업무, 개발 중 발생한 이슈/고민 이를 해결한 내용
첫번째 만든 코드
(실패. 감 못 잡는 중)
// 숫자야구 만들기
// 컴퓨터가 임의의 3자리 수를 뽑고 유저가 3자리를 또 뽑음
// 12번 안에 맞추는 게임
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int game_introduce(){ //게임 시작 함수: 게임 규칙 설명
printf("숫자야구 게임에 오신것을 환영합니다!\n");
printf("숫자야구 게임의 규칙에 대해 설명드리겠습니다.\n");
printf("컴퓨터가 랜덤으로 3자리 숫자를 뽑습니다.\n");
printf("사용자는 3가지 숫자를 추측합니다.\n");
printf("자리수와 숫자가 맞으면 '스트라이크', 자리수는 틀리고 숫자는 맞으면 '볼'입니다.\n");
printf("당신에게 주어진 기회는 총 12번 입니다.\n");
}
int user_wants_start(){ //게임 시작 안내
int user_wants_start;
printf("게임을 진행하시겠습니까?\n");
printf("게임 시작: 1, 게임 종료: 2: ");
scanf("%d", &user_wants_start);
if(user_wants_start == 1){
printf("게임을 시작합니다! 당신의 건투를 빕니다!\n");
return 1;
}
else if(user_wants_start == 2){
return 0;
}
else{
printf("1과 2중 하나의 숫자를 입력해 주세요!\n");
}
return 0;
}
int computer_choose_random_number(){ //컴퓨터가 랜덤 숫자를 고름
int com_num_1=0, com_num_2=0, com_num_3=0;
srand(time(NULL));
com_num_1 = rand() % 10 + 1;
com_num_2 = rand() % 10 + 1;
com_num_3 = rand() % 10 + 1;
while(com_num_1 == com_num_2){
com_num_2 = rand() & 10 + 1;
}
while(com_num_1 == com_num_3 || com_num_2 == com_num_3){
com_num_3 = rand() % 10 + 1;
}
}
int user_choose_numbers(){ //사용자가 3개 숫자 고름
int user_num_1, user_num_2, user_num_3;
printf("숫자를 유추하세요!\n");
printf("띄어쓰기로 구분하여 3개의 숫자를 입력해 주세요: \n");
scanf("%d %d %d", &user_num_1, &user_num_2, &user_num_3);
}
int compare_numbers(int com_num_1, int com_num_2, int com_num_3, int user_num_1, int user_num_2, int user_num_3){
int strike=0, ball=0;
if(com_num_1 == user_num_1){
strike ++;
}
if(com_num_2 == user_num_2){
strike ++;
}
if(com_num_3 == user_num_3){
strike ++;
}
if(com_num_1 == user_num_1 && com_num_2 == user_num_2 && com_num_3 == user_num_3){
strike +3;
}
if(com_num_1 == user_num_2 || com_num_1 == user_num_3){
ball ++;
}
if(com_num_2 == user_num_1 || com_num_2 == user_num_3){
ball ++;
}
if(com_num_3 == user_num_1 || com_num_3 == user_num_2){
ball ++;
}
}
int main(){
game_introduce();
user_wants_start();
computer_choose_random_number();
user_choose_numbers();
compare_numbers(com_num_1, com_num_2, com_num_3, user_num_1, user_num_2, user_num_3);
return 0;
}
실패이유
1)
computer_choose_random_number() 함수에서 com_num_1, com_num_2, com_num_3 변수들이 compare_numbers() 함수에서 정의되지 않았기 때문에 오류가 발생했다. --> 스무고개 만든지 몇일이나 지났다고 main()함수에서 따로 변수 가져오는것을 잊었다..
2) compare_numbers() 함수에서 strike와 ball 변수들을 반환하지 않음. --> printf문 추가해서 반환
두번째 만든 코드
(출력은 됨. 그런데 컴퓨터가 생각하는 난수숫자에 0이 포함됨... 예: 403 790 등)
// 숫자야구 만들기
// 컴퓨터가 임의의 3자리 수를 뽑고 유저가 3자리를 또 뽑음
// 12번 안에 맞추는 게임
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int game_introduce(){ //게임 시작 함수: 게임 규칙 설명 함수
printf("|------------------------------------------------|\n");
printf("| |\n");
printf("| 숫자야구 게임에 오신것을 환영합니다! |\n");
printf("| 숫자야구 게임의 규칙에 대해 설명드리겠습니다. |\n");
printf("| 컴퓨터가 랜덤으로 3자리 숫자를 뽑습니다. |\n");
printf("| 사용자는 3가지 숫자를 추측합니다. |\n");
printf("| 자리수와 숫자가 맞으면 '스트라이크(S)', |\n");
printf("| 자리수는 틀리고 숫자는 맞으면 '볼(B)'입니다. |\n");
printf("| 당신에게 주어진 기회는 총 12번 입니다. |\n");
printf("| |\n");
printf("|------------------------------------------------|\n");
}
int computer_choose_random_number(){ //컴퓨터가 랜덤 숫자를 고르는 함수
int com_num_1=0, com_num_2=0, com_num_3=0;
srand(time(NULL));
com_num_1 = rand() % 10 + 1;
com_num_2 = rand() % 10 + 1;
com_num_3 = rand() % 10 + 1;
while(com_num_1 == com_num_2){
com_num_2 = rand() & 10 + 1;
}
while(com_num_1 == com_num_3 || com_num_2 == com_num_3){
com_num_3 = rand() % 10 + 1;
}
return com_num_1 * 100 + com_num_2 * 10 + com_num_3;
}
int user_choose_numbers(){ //사용자가 3개 숫자 고름
int user_num_1, user_num_2, user_num_3;
printf("숫자를 유추하세요!\n");
printf("띄어쓰기로 구분하여 3개의 숫자를 입력해 주세요: ");
scanf("%d %d %d", &user_num_1, &user_num_2, &user_num_3);
return user_num_1 * 100 + user_num_2 * 10 + user_num_3;
}
int compare_numbers(int com_num, int user_num){
int com_num_1 = computer_choose_random_number() % 100; //컴퓨터 첫번째 자리
int com_num_2 = computer_choose_random_number() / 10 % 10; //컴퓨터 두번째 자리
int com_num_3 = computer_choose_random_number() % 10; //컴퓨터 세번째 자리
int user_num_1 = user_num / 100; //유저 첫번재 자리
int user_num_2 = (user_num / 10) % 10; //유저 두번째 자리
int user_num_3 = user_num % 10; //유저 세번째 자리
int strike=0, ball=0;
if(com_num_1 == user_num_1){
strike ++;
}
if(com_num_2 == user_num_2){
strike ++;
}
if(com_num_3 == user_num_3){
strike ++;
}
if(com_num_1 == user_num_1 && com_num_2 == user_num_2 && com_num_3 == user_num_3){
strike +3;
}
if(com_num_1 == user_num_2 || com_num_1 == user_num_3){
ball ++;
}
if(com_num_2 == user_num_1 || com_num_2 == user_num_3){
ball ++;
}
if(com_num_3 == user_num_1 || com_num_3 == user_num_2){
ball ++;
}
if(strike > 0 && ball > 0){
return
printf("스트라이크 %d개, 볼 %d개 입니다.", strike, ball);
}
if(strike > 0 && ball == 0){
printf("스트라이크 %d개 입니다.", strike);
}
if(strike == 0 && ball > 0){
printf("볼 %d개 입니다.", strike);
}
}
int main(){
int strike=0, ball=0; //스트라이크, 볼
int cnt;
int com_num = computer_choose_random_number();
game_introduce(); //게임 규칙 설명
printf("컴퓨터가 숫자 생성중: ");
sleep(1000);
while(cnt<12){
cnt++;
printf("%d번째 시도입니다.\n", cnt);
int user_num = user_choose_numbers();
compare_numbers(com_num, user_num);
if(strike == 3){
printf("승리하셨습니다! 축하합니다.\n");
return 0;
}
}
printf("아쉽게도 실패했습니다...\n");
printf("정답은 %d%d%d이였습니다!\n", com_num/100, com_num/10%10, com_num%10);
return 0;
}
문제점 해결:
1) 컴퓨터가 고르는 숫자 중 0이 출력됨
com_num_1 = rand() % 10 + 1; 은 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 에 1씩 더하는 거니까
1, 2, 3, 4, 5, 6, 7, 8, 9, 10이 된다.
나는 1 ~ 9 까지의 숫자를 원하니까 rand() % 9 + 1;로 바꿔주면 된다.
2) compare_numbers(); 함수에서 ball을 반환해야 하는 자리에 strike가 써져있었음. 다시 ball로 바꿔줌
세번째 만든 코드(성공)
(>>성공<<. 잘 출력됨)
+ 다시 하시겠습니까 질문 추가
+ 화면 지워주는 clear함수 추가
#include <stdio.h>
#include <stdlib.h> //rand함수 위해 넣어줌
#include <time.h> //난수 만들기 위해 넣어줌
#include <unistd.h> //sleep함수 오류 막기 위해 넣어줌
int game_introduce(){ //게임 시작 함수: 게임 규칙 설명 함수
printf("|------------------------------------------------|\n");
printf("| |\n");
printf("| 숫자야구 게임에 오신것을 환영합니다! |\n");
printf("| 숫자야구 게임의 규칙에 대해 설명드리겠습니다. |\n");
printf("| 컴퓨터가 랜덤으로 3자리 숫자를 뽑습니다. |\n");
printf("| 사용자는 3가지 숫자를 추측합니다. |\n");
printf("| 자리수와 숫자가 맞으면 '스트라이크(S)', |\n");
printf("| 자리수는 틀리고 숫자는 맞으면 '볼(B)'입니다. |\n");
printf("| 당신에게 주어진 기회는 총 12번 입니다. |\n");
printf("| |\n");
printf("|------------------------------------------------|\n");
}
int computer_choose_random_number(){ //컴퓨터가 랜덤 숫자를 고르는 함수
int com_num_1, com_num_2, com_num_3; //컴퓨터는 3개의숫자를 고름
srand(time(NULL)); //스래드 시간으로 시드값 설정
com_num_1 = rand() % 9 + 1; //초기 랜덤값 설정
com_num_2 = rand() % 9 + 1;
com_num_3 = rand() % 9 + 1;
while(com_num_1 == com_num_2){ // 1과 2가 다른 수가 나올 때까지 계속함
com_num_2 = rand() & 9 + 1;
}
while(com_num_1 == com_num_3 || com_num_2 == com_num_3){ //1, 3과 2, 3이 다른 수가 나올 때까지 계속함
com_num_3 = rand() % 9 + 1;
}
return com_num_1 * 100 + com_num_2 * 10 + com_num_3; //하나의 숫자로 만들어서 반환해줌. 예)3, 6, 5 -> 365
}
int user_choose_numbers(){ //사용자가 3개 숫자 고름
int user_num_1, user_num_2, user_num_3;
printf("숫자를 유추하세요!\n");
printf("띄어쓰기로 구분하여 3개의 숫자를 입력해 주세요: ");
scanf("%d %d %d", &user_num_1, &user_num_2, &user_num_3); //사용자가 유추한 숫자는 user_num_1, 2, 3에 저장됨
return user_num_1 * 100 + user_num_2 * 10 + user_num_3; //하나의 숫자로 만들어서 반환해줌. 예)3, 6, 5 -> 365
}
int compare_numbers(int com_num, int user_num){
int com_num_1 = com_num / 100; //컴퓨터 첫번째 자리
int com_num_2 = com_num / 10 % 10; //컴퓨터 두번째 자리
int com_num_3 = com_num % 10; //컴퓨터 세번째 자리
//--------------------------------------------------
int user_num_1 = user_num / 100; //유저 첫번재 자리
int user_num_2 = (user_num / 10) % 10; //유저 두번째 자리
int user_num_3 = user_num % 10; //유저 세번째 자리
int strike=0, ball=0; //스트라이크 볼 초기값 0으로 설정
if(com_num_1 == user_num_1){ //컴퓨터 1번값 == 사용자 1번값 => 스트라이크
strike ++;
}
if(com_num_2 == user_num_2){ //컴퓨터 2번값 == 사용자 2번값 => 스트라이크
strike ++;
}
if(com_num_3 == user_num_3){ //컴퓨터 3번값 == 사용자 3번값 => 스트라이크
strike ++;
}
if(com_num_1 == user_num_1 && com_num_2 == user_num_2 && com_num_3 == user_num_3){ //컴퓨터와 사용자의 값이 모두 같으면 사용자 win
strike +3; //스트라이크에 3더해줌
}
if(com_num_1 == user_num_2 || com_num_1 == user_num_3){ //컴퓨터와 사용자의 자리값이 다르게 맞는다면 ball에 1 더해줌
ball ++;
}
if(com_num_2 == user_num_1 || com_num_2 == user_num_3){
ball ++;
}
if(com_num_3 == user_num_1 || com_num_3 == user_num_2){
ball ++;
}
if(strike > 0 && ball > 0){ //두개 다 0초과이면 둘 다 출력
printf(">> 스트라이크 %d개, 볼 %d개 입니다.\n", strike, ball);
}
if(strike > 0 && ball == 0){ //스트라이크만 0초과이면 스트라이크만 출력
printf(">> 스트라이크 %d개 입니다.\n", strike);
if(strike == 3){ //스트라이크가 3이면 2반환
return 2;
}
}
if(strike == 0 && ball > 0){ //볼만 0 초과이면 볼만 출력
printf(">> 볼 %d개 입니다.\n", ball);
}
if(strike == 0 && ball == 0){ //둘다 0이면 아웃이라고 알림
printf(">> 아웃입니다! 다시 생각하세요!\n");
}
printf("==================================================\n"); //깔끔을 위한 선
}
int main(){
int strike=0, ball=0; //스트라이크, 볼
int cnt=0; //횟수는 0으로 설정
int com_num = computer_choose_random_number(); //컴퓨터가 랜덤으로 숫자를 생각함 -> com_num으로 받아옴
printf("사실 정답은: %d\n", com_num); //게임 제작자를 위한 야매승리
while(1)
{
game_introduce(); //게임 규칙 설명
for(int i=3;i>0;i--) //컴퓨터 숫자 생성~
{
printf("컴퓨터가 숫자 생성중 ... %d초\n", i); //컴퓨터가 고민합니다 숫자를~
sleep(1);
}
while(1){
cnt++; //횟수에 하나씩 추가됨. 12번 되면 종료
printf("%d번째 시도입니다. ", cnt); //사용자에게 몇 번 도전하는지 알려줌
int user_num = user_choose_numbers(); //사용자가 선택한 숫자를 받아와서
if(compare_numbers(com_num, user_num) == 2) //사용자가 이겼을 때 위에서 2받아옴. 승리 출력
{
printf("==================================================\n");
printf("승리하셨습니다! 축하합니다.\n");
cnt = 0; //승리하면 횟수는 0으로 초기화
break;
}
if(cnt == 12) //횟수가 12일 경우 게임은 종료됨
{
printf("아쉽게도 실패했습니다...\n");
printf("정답은 %d%d%d이였습니다!\n", com_num/100, com_num/10%10, com_num%10); //정답출력 후 break;로 while문 빠져나옴
break;
}
}
printf("다시 게임하시겠습니까?\n");
printf("1: 계속할래요, 2:그만할래요\n>>"); //다시 할 지 물어봄
int replay;
scanf("%d", &replay); //다시할지 물어보는 함수 replay에 받음
if(replay == 1 )
{
system("clear"); //계속하길 원하면 화면을 지워주고 계속함
continue;
}
else if(replay == 2) //아니면 break로 멈춰줌
{
break;}
else
{
printf("1과 2중 하나의 숫자를 입력해주세요!"); //1과 2의 숫자를 입력하지 않으면 출력
}
printf("==================================================\n");
}
return 0;
}
추가 부분:
1) 컴퓨터가 숫자를 고민합니다 .... 부분 추가: for문과 sleep함수를 구글링 + 저번 카페 글 보고 참고하여 만들었다.
2) system("clear")함수 추가: 게임을 계속하길 원하면 화면을 지우고 다시 게임 설명을 해준다.
문제점 해결:
1) 게임이 시작될 때 cnt부분이 초기화되지 않는 문제점이 생겼다. 그래서 cnt를 게임을 다시 시작하기 원하면 cnt = 0으로 초기화함으로 해결
2) 유저 선택값을 100단위로 합쳤다가 나눠주는 부분에서 부호를 제대로 안 써줘서 오류가 생겼다. 다시 확인하고 해결
3) 게임 재시작 할 때 화면이 계속 뜨는 문제가 있어서 게임 설명 부분 함수를 while문 안에 넣어 마치 계속 존재하는 것처럼 해줬다. 사실 그 이후로도 코드 뒷부분 다시 헤맸지만 해결해서 기분 좋음~~
그리고 리눅스 환경이라 cls 대신 clear써줘야 하는것도 기억!!하자
코드 구현 사진
3 2 1하고 시작
게임 플레이 화면
다시플레이 눌렀을 때 초기화 되는 모습!!
3. 새로 배운 내용 / 4.참고할 만한 레퍼런스
스무고개에서 3 2 1을 천천히 나오도록 사용한
이시연님의 for문 + sleep 코드를 그대로 차용하여 사용해봤다.(미리 감사합니다)
그런데 노란색 선 오류가 떠서 구글링 해 봄
https://stackoverflow.com/questions/39156743/sleep-warning-implicit-declaration-of-function-sleep
번역) sleep 함수는 C 프로그래밍 언어의 일부가 아닙니다. 그래서 C 컴파일러는 이 함수의 원형을 프로토타입으로 필요로 하며, 이를 통해 함수의 인수의 수와 데이터 유형 및 반환 데이터 유형을 알 수 있습니다. 이를 찾지 못하면 함수의 암시적 선언을 생성합니다.
Linux에서는 sleep 함수에 대한 원형이 <unistd.h>에 있으며,
Windows에서는 <windows.h> 또는 <synchapi.h>에 있는 다른 함수인 Sleep에 대한 원형이 있습니다.
필요한 경우 함수의 원형을 명시적으로 제공하여 헤더를 포함하지 않고도 사용할 수 있습니다. 이는 헤더 파일에서 몇 가지 함수만 필요한 경우 유용합니다.
6. 회고
오늘 내 코드는 도합 4명이 만들었다고 할 수 있다(...)
마치 골 하나를 넣기 위해 서브를 3번이나 받았다고 할 수 있고...
그래도 결국 구현은 했으니 된거 아닐까 하는 마음을 먹기로 했다.
그래도 김밥천국을 만들 때보다 함수를 사용하니 나름 깔끔해진 느낌이다.
더 연습해야 할 것 같다. 특히 순서도와 코드 제작 사이에 의사코드를 자세하게 적는 과정을 거쳐야겠다.
그리고 오늘 usb랑 동글이랑 qcy블투이어폰이 생겼다. 감사합니다 잘 쓰겠습니다~~~
오늘 감사할 일이 참 많이 생긴다.,.
7. 해야할것
- 다른 사람들의 코드 보고 배우기
- 들여쓰기 잘해보자
- 작성한 코드 복습하기. 내가 만든 코드도 하루 지나면 내가 만들었다고? 싶음. 복습하자.
'개발공부 > C언어' 카테고리의 다른 글
C언어_제어문과 반복문을 활용해 턴제 게임 만들기 (0) | 2023.04.06 |
---|---|
C언어_게임만들기 순서도(1차) (0) | 2023.04.04 |
C언어_김밥천국 포스기 만들기 (0) | 2023.04.03 |
C언어_윤년 계산기 만들기 (0) | 2023.03.30 |
C언어_붕어빵 심리테스트 만들기 (0) | 2023.03.30 |