-
15주 차 수업 중 과제C/수업 2024. 6. 10. 16:07














구조체를 사용하는 가장 큰 장점
구조체를 사용하면 멤버들을 다 복사해버림

배열은 너무 복잡함 #define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고를 무시하기 위한 매크로 정의
#include <stdio.h> // 표준 입출력 함수 사용을 위한 헤더 파일 포함
// Grade 구조체 정의: 학생의 학번(num), 국어 점수(kor), 영어 점수(eng), 수학 점수(mat), 총점(total), 평균(avg)을 저장
struct Grade {
int num, kor, eng, mat, total;
double avg;
};
int main(void) {
int i; // 반복문 제어 변수
struct Grade man[5]; // 5명의 학생 정보를 저장할 구조체 배열 선언
double avgkor = 0.0, avgeng = 0.0, avgmat = 0.0; // 국어, 영어, 수학 점수의 총합을 저장할 변수 초기화
// 5명의 학생 정보를 입력받기 위한 반복문
for (i = 0; i < 5; i++) {
printf("%d번째 학생의 학번=", i + 1); // 사용자에게 학번 입력을 요청
scanf("%d", &man[i].num); // 학번 입력받기
printf("국어 점수="); scanf("%d", &man[i].kor); // 국어 점수 입력받기
printf("영어 점수="); scanf("%d", &man[i].eng); // 영어 점수 입력받기
printf("수학 점수="); scanf("%d", &man[i].mat); // 수학 점수 입력받기
// 각 학생의 총점을 계산
man[i].total = man[i].kor + man[i].eng + man[i].mat;
// 각 학생의 평균을 계산
man[i].avg = man[i].total / 3.0;
// 과목별 점수를 누적하기
avgkor += man[i].kor;
avgeng += man[i].eng;
avgmat += man[i].mat;
}
// 입력받은 학생들의 정보를 출력
printf(" 학번 국어 영어 수학 총점 평균\n");
for (i = 0; i < 5; i++) {
printf("%8d %6d %6d %6d %6d %7.2f\n",
man[i].num, man[i].kor, man[i].eng, man[i].mat, man[i].total, man[i].avg);
}
// 과목별 평균 점수를 계산하여 출력
printf(" 국어 평균: %7.2f\n 영어 평균: %7.2f\n 수학 평균: %7.2f\n",
avgkor / 5.0, avgeng / 5.0, avgmat / 5.0);
return 0; // 프로그램 종료
}

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
// 난이도 설정에 따른 최대 시도 횟수
int getMaxAttempts(int difficulty) {
switch (difficulty) {
case 1: return 15; // 쉬움
case 2: return 10; // 보통
case 3: return 5; // 어려움
default: return 10;
}
}
int main() {
int guess, random, count, max_attempts, difficulty, score, high_score = 0;
char play_again;
srand((unsigned int)time(NULL));
do {
printf("난이도를 선택하세요 (1: 쉬움, 2: 보통, 3: 어려움): ");
scanf("%d", &difficulty);
max_attempts = getMaxAttempts(difficulty);
random = rand() % 100 + 1;
count = 1;
score = 0;
printf("숫자 맞추기 게임에 오신 것을 환영합니다! 최대 %d번 시도할 수 있습니다.\n", max_attempts);
while (count <= max_attempts) {
printf("[ %02d회 ] 1~100까지 숫자 하나를 입력하세요: ", count);
scanf("%d", &guess);
if (guess == random) {
score = 100 - (count - 1) * (100 / max_attempts);
printf(" => 빙고! %d번 만에 맞췄습니다! 점수: %d\n", count, score);
if (score > high_score) {
high_score = score;
printf("축하합니다! 최고 점수를 갱신했습니다: %d\n", high_score);
}
break;
} else if (guess > random) {
printf(" => 더 작은 수를 입력하세요.\n");
} else {
printf(" => 더 큰 수를 입력하세요.\n");
}
// 힌트 제공 (중간 범위 힌트)
if (count % 3 == 0 && count < max_attempts) {
int hint_range = 5 + difficulty * 5;
int lower_bound = random - hint_range < 1 ? 1 : random - hint_range;
int upper_bound = random + hint_range > 100 ? 100 : random + hint_range;
printf("힌트: 숫자는 %d와 %d 사이에 있습니다.\n", lower_bound, upper_bound);
}
count++;
}
if (count > max_attempts) {
printf("아쉽습니다. %d번의 시도 안에 맞추지 못했습니다. 정답은 %d였습니다.\n", max_attempts, random);
}
// 게임 재시작 여부 묻기
printf("게임을 다시 하시겠습니까? (y/n): ");
scanf(" %c", &play_again); // 공백을 넣어 이전 입력의 개행 문자를 무시
} while (play_again == 'y' || play_again == 'Y');
printf("게임을 종료합니다. 최고 점수: %d. 감사합니다!\n", high_score);
return 0;
}게임적인 요소 추가 챗지피티
위 코드에는 다음과 같은 추가 요소가 포함되어 있습니다:
- 난이도 선택 (쉬움, 보통, 어려움)과 이에 따른 최대 시도 횟수 설정.
- 점수 시스템 (시도 횟수에 따라 점수 계산).
- 최고 점수 기록 및 갱신 시 알림.
- 중간 범위 힌트 제공 (현재 난이도에 따라 범위 조정).
이러한 요소들은 게임을 더욱 흥미롭게 만들어줍니다.
야구게임
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> //printf(), scanf()
#include <stdlib.h> //rand()
#include <time.h> //time()
#include <conio.h> //getch()
#include <ctype.h> //toupper()
void intro(); //함수 선언
void final(int count); //함수 선언
int main(void)
{
int i, j, Com[3], User[3];
int strike, ball, count = 1;
char key;
srand((unsigned int)time(NULL));
do {
count = 1;
intro(); //함수호출
do {
for (i = 0; i < 3; i++) Com[i] = rand() % 9 + 1;
} while (Com[0] == Com[1] || Com[0] == Com[2] || Com[1] == Com[2]);
for (i = 0; i < 3; i++) printf("%d ", Com[i]); printf("\n");
do {
printf("[%2d번째] 숫자 3개를 입력:", count);
scanf("%d%d%d", &User[0], &User[1], &User[2]);
fflush(stdin); //버퍼를 비운다.
strike = 0; ball = 0;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if (Com[i] == User[j]) {
if (i == j) strike++;
else ball++;
}
}
}
printf("[ %d Strike %d Ball ]\n", strike, ball);
count++;
} while (strike < 3);
final(count); //함수 호출
printf("게임을 다시 하겠습니까(Y/N): ");
key = _getch();
} while (key == 'y' || key == 'Y');
return 0;
} //main()끝
void intro() //함수 정의
{
puts("\n");
puts("-------------------------------");
puts(" 숫자야구게임 ");
puts("-------------------------------");
}
void final(int count) //함수 정의
{
if (count <= 5)puts("축하합니다.당신은 천재군요!");
else if (count <= 10) puts("당신의 집중력은 보통입니다.");
else if (count <= 15) puts("심하다~~~~");
else puts("삶이 그대를 속일지라고 슬퍼하거나 노하지 말라!");
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <ctype.h>
void intro(); // 함수 선언
void final(int count); // 함수 선언
void generateUniqueNumbers(int arr[], int size); // 유니크한 숫자 생성 함수
void getUserInput(int arr[], int size); // 사용자 입력 함수
void calculateStrikeBall(int com[], int user[], int size, int* strike, int* ball); // 스트라이크와 볼 계산 함수
int main(void) {
int com[3], user[3];
int strike, ball, count;
char key;
srand((unsigned int)time(NULL));
do {
count = 1;
intro(); // 함수 호출
generateUniqueNumbers(com, 3);
// 디버깅용으로 컴퓨터 숫자를 출력
for (int i = 0; i < 3; i++) printf("%d ", com[i]);
printf("\n");
do {
printf("[%2d번째] 숫자 3개를 입력: ", count);
getUserInput(user, 3);
calculateStrikeBall(com, user, 3, &strike, &ball);
printf("[ %d Strike %d Ball ]\n", strike, ball);
count++;
} while (strike < 3);
final(count); // 함수 호출
printf("게임을 다시 하겠습니까(Y/N): ");
key = _getch();
} while (toupper(key) == 'Y');
return 0;
}
void intro() {
puts("\n-------------------------------");
puts(" 숫자야구게임 ");
puts("-------------------------------");
}
void final(int count) {
if (count <= 5)
puts("축하합니다. 당신은 천재군요!");
else if (count <= 10)
puts("당신의 집중력은 보통입니다.");
else if (count <= 15)
puts("심하다~~~~");
else
puts("삶이 그대를 속일지라도 슬퍼하거나 노하지 말라!");
}
void generateUniqueNumbers(int arr[], int size) {
int i, j;
do {
for (i = 0; i < size; i++) arr[i] = rand() % 9 + 1;
} while (arr[0] == arr[1] || arr[0] == arr[2] || arr[1] == arr[2]);
}
void getUserInput(int arr[], int size) {
for (int i = 0; i < size; i++) {
scanf("%d", &arr[i]);
}
fflush(stdin); // 버퍼를 비운다
}
void calculateStrikeBall(int com[], int user[], int size, int* strike, int* ball) {
*strike = 0;
*ball = 0;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (com[i] == user[j]) {
if (i == j)
(*strike)++;
else
(*ball)++;
}
}
}
}리팩토링된 코드에서 개선된 사항은 다음과 같습니다:
- 중복된 숫자 생성을 방지하는 generateUniqueNumbers 함수 추가.
- 사용자 입력을 받는 getUserInput 함수 추가.
- 스트라이크와 볼을 계산하는 calculateStrikeBall 함수 추가.
- 함수 선언과 정의를 명확히 하여 코드의 가독성과 재사용성을 높임.
- 불필요한 주석 제거 및 필요한 경우 코드 자체가 설명이 되도록 개선.
이러한 개선으로 코드의 가독성이 향상되고, 유지보수와 확장이 용이해집니다.
C언어로 100줄 내외의 숫자 맞추기 게임을 만들거야. 최대한 많은 단계를 통해서 최종 완성 소스가 만들어지는 과정을 보여줘. 각 단계별로 주석과 설명도 작성해주고
1단계: 기본 구조 만들기
먼저, 프로그램의 기본 구조를 잡아보겠습니다.
c
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int target, guess; // 랜덤 숫자를 생성하기 위해 시드 설정 srand((unsigned int)time(NULL)); // 1부터 100 사이의 랜덤 숫자 생성 target = rand() % 100 + 1; printf("숫자 맞추기 게임에 오신 것을 환영합니다!\n"); // 사용자가 맞출 때까지 반복 do { printf("숫자를 입력하세요 (1-100): "); scanf("%d", &guess); if (guess > target) { printf("너무 높습니다. 다시 시도하세요.\n"); } else if (guess < target) { printf("너무 낮습니다. 다시 시도하세요.\n"); } else { printf("축하합니다! 숫자를 맞추셨습니다.\n"); } } while (guess != target); return 0; }이 단계에서는 숫자를 맞추는 기본 구조를 만들었습니다. 사용자가 숫자를 맞출 때까지 반복하고, 입력한 숫자가 목표 숫자보다 높은지 낮은지를 알려줍니다.
2단계: 게임을 다시 시작할 수 있도록 수정
게임이 끝난 후 다시 시작할 수 있도록 기능을 추가해보겠습니다.
c
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <ctype.h> int main(void) { int target, guess; char playAgain; do { // 랜덤 숫자를 생성하기 위해 시드 설정 srand((unsigned int)time(NULL)); // 1부터 100 사이의 랜덤 숫자 생성 target = rand() % 100 + 1; printf("숫자 맞추기 게임에 오신 것을 환영합니다!\n"); // 사용자가 맞출 때까지 반복 do { printf("숫자를 입력하세요 (1-100): "); scanf("%d", &guess); if (guess > target) { printf("너무 높습니다. 다시 시도하세요.\n"); } else if (guess < target) { printf("너무 낮습니다. 다시 시도하세요.\n"); } else { printf("축하합니다! 숫자를 맞추셨습니다.\n"); } } while (guess != target); // 게임을 다시 할지 묻기 printf("게임을 다시 하시겠습니까? (Y/N): "); scanf(" %c", &playAgain); } while (toupper(playAgain) == 'Y'); return 0; }이 단계에서는 사용자가 게임을 다시 시작할 수 있도록 묻는 기능을 추가했습니다. toupper 함수를 사용하여 'Y' 또는 'y' 입력에 대해 동일하게 처리했습니다.
3단계: 시도 횟수를 세고 결과에 표시
사용자가 몇 번 만에 숫자를 맞췄는지 표시하도록 수정해보겠습니다.
c
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <ctype.h> int main(void) { int target, guess, attempts; char playAgain; do { // 랜덤 숫자를 생성하기 위해 시드 설정 srand((unsigned int)time(NULL)); // 1부터 100 사이의 랜덤 숫자 생성 target = rand() % 100 + 1; attempts = 0; // 시도 횟수 초기화 printf("숫자 맞추기 게임에 오신 것을 환영합니다!\n"); // 사용자가 맞출 때까지 반복 do { printf("숫자를 입력하세요 (1-100): "); scanf("%d", &guess); attempts++; // 시도 횟수 증가 if (guess > target) { printf("너무 높습니다. 다시 시도하세요.\n"); } else if (guess < target) { printf("너무 낮습니다. 다시 시도하세요.\n"); } else { printf("축하합니다! %d번 만에 숫자를 맞추셨습니다.\n", attempts); } } while (guess != target); // 게임을 다시 할지 묻기 printf("게임을 다시 하시겠습니까? (Y/N): "); scanf(" %c", &playAgain); } while (toupper(playAgain) == 'Y'); return 0; }이 단계에서는 시도 횟수를 세어 사용자가 숫자를 맞췄을 때 몇 번 만에 맞췄는지 출력하도록 수정했습니다.
4단계: 입력 유효성 검사 추가
사용자가 1-100 범위 밖의 숫자를 입력했을 때 경고 메시지를 표시하도록 수정해보겠습니다.
c
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <ctype.h> int main(void) { int target, guess, attempts; char playAgain; do { // 랜덤 숫자를 생성하기 위해 시드 설정 srand((unsigned int)time(NULL)); // 1부터 100 사이의 랜덤 숫자 생성 target = rand() % 100 + 1; attempts = 0; // 시도 횟수 초기화 printf("숫자 맞추기 게임에 오신 것을 환영합니다!\n"); // 사용자가 맞출 때까지 반복 do { printf("숫자를 입력하세요 (1-100): "); scanf("%d", &guess); if (guess < 1 || guess > 100) { printf("잘못된 입력입니다. 1에서 100 사이의 숫자를 입력하세요.\n"); continue; // 잘못된 입력 시도는 시도 횟수에 포함하지 않음 } attempts++; // 유효한 입력일 때만 시도 횟수 증가 if (guess > target) { printf("너무 높습니다. 다시 시도하세요.\n"); } else if (guess < target) { printf("너무 낮습니다. 다시 시도하세요.\n"); } else { printf("축하합니다! %d번 만에 숫자를 맞추셨습니다.\n", attempts); } } while (guess != target); // 게임을 다시 할지 묻기 printf("게임을 다시 하시겠습니까? (Y/N): "); scanf(" %c", &playAgain); } while (toupper(playAgain) == 'Y'); return 0; }5단계: 입력 버퍼 정리 및 최종 완성
입력 시 버퍼에 남아 있는 문자를 정리하고, 코드의 가독성을 높이기 위해 일부 정리를 하겠습니다.
c
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <ctype.h> // 입력 버퍼를 비우는 함수 void clearInputBuffer(void) { while (getchar() != '\n'); } int main(void) { int target, guess, attempts; char playAgain; do { // 랜덤 숫자를 생성하기 위해 시드 설정 srand((unsigned int)time(NULL)); // 1부터 100 사이의 랜덤 숫자 생성 target = rand() % 100 + 1; attempts = 0; // 시도 횟수 초기화 printf("숫자 맞추기 게임에 오신 것을 환영합니다!\n"); // 사용자가 맞출 때까지 반복 do { printf("숫자를 입력하세요 (1-100): "); if (scanf("%d", &guess) != 1) { printf("잘못된 입력입니다. 숫자를 입력하세요.\n"); clearInputBuffer(); // 잘못된 입력 시 버퍼 비우기 continue; } if (guess < 1 || guess > 100) { printf("잘못된 입력입니다. 1에서 100 사이의 숫자를 입력하세요.\n"); continue; // 잘못된 입력 시도는 시도 횟수에 포함하지 않음 } attempts++; // 유효한 입력일 때만 시도 횟수 증가 if (guess > target) { printf("너무 높습니다. 다시 시도하세요.\n"); } else if (guess < target) { printf("너무 낮습니다. 다시 시도하세요.\n"); } else { printf("축하합니다! %d번 만에 숫자를 맞추셨습니다.\n", attempts); } } while (guess != target); // 게임을 다시 할지 묻기 printf("게임을 다시 하시겠습니까? (Y/N): "); clearInputBuffer(); // 이전 입력의 남은 버퍼 비우기 scanf(" %c", &playAgain); } while (toupper(playAgain) == 'Y'); return 0; }이 단계에서는 다음과 같은 기능을 추가하고 개선했습니다:
- 사용자가 숫자가 아닌 값을 입력했을 때 처리하기 위해 입력 유효성 검사를 추가했습니다.
- clearInputBuffer 함수를 사용하여 잘못된 입력이 있을 때 입력 버퍼를 비우도록 했습니다.
- 게임을 다시 시작할지 묻는 부분에서 입력 버퍼를 비우도록 했습니다.
이제 완성된 숫자 맞추기 게임의 전체 소스 코드를 다시 한 번 확인해보겠습니다:
c
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <ctype.h> // 입력 버퍼를 비우는 함수 void clearInputBuffer(void) { while (getchar() != '\n'); } int main(void) { int target, guess, attempts; char playAgain; do { // 랜덤 숫자를 생성하기 위해 시드 설정 srand((unsigned int)time(NULL)); // 1부터 100 사이의 랜덤 숫자 생성 target = rand() % 100 + 1; attempts = 0; // 시도 횟수 초기화 printf("숫자 맞추기 게임에 오신 것을 환영합니다!\n"); // 사용자가 맞출 때까지 반복 do { printf("숫자를 입력하세요 (1-100): "); if (scanf("%d", &guess) != 1) { printf("잘못된 입력입니다. 숫자를 입력하세요.\n"); clearInputBuffer(); // 잘못된 입력 시 버퍼 비우기 continue; } if (guess < 1 || guess > 100) { printf("잘못된 입력입니다. 1에서 100 사이의 숫자를 입력하세요.\n"); continue; // 잘못된 입력 시도는 시도 횟수에 포함하지 않음 } attempts++; // 유효한 입력일 때만 시도 횟수 증가 if (guess > target) { printf("너무 높습니다. 다시 시도하세요.\n"); } else if (guess < target) { printf("너무 낮습니다. 다시 시도하세요.\n"); } else { printf("축하합니다! %d번 만에 숫자를 맞추셨습니다.\n", attempts); } } while (guess != target); // 게임을 다시 할지 묻기 printf("게임을 다시 하시겠습니까? (Y/N): "); clearInputBuffer(); // 이전 입력의 남은 버퍼 비우기 scanf(" %c", &playAgain); } while (toupper(playAgain) == 'Y'); return 0; }이제 이 코드는 숫자 맞추기 게임을 완성된 형태로 제공합니다. 사용자는 게임을 끝낸 후 다시 시작할 수 있으며, 잘못된 입력에 대한 처리도 포함되어 있습니다.
출처: Smile Han의 C언어 프로그래밍
'C > 수업' 카테고리의 다른 글
14주 차 수업 중 과제 (1) 2024.06.03 13주 차 수업 중 과제 (0) 2024.05.27 12주 차 수업 중 과제 (0) 2024.05.20 11주 차 수업 과제 (0) 2024.05.13 9주 차 수업 중 과제 (0) 2024.04.29