직접 만든 문제입니다. 이 중에 두 문제를 선택했는데 심지어 더 쉽게 수정까지 했는데 빠꾸먹었다고... ...전달받아서 원본을 공개합니다.
답안도 같이 나와있으니 문서를 읽을 시 주의바랍니다.
컴퓨터공학과 1학년을 대상으로 한 문제입니다.
범위는
- 리눅스에서 gcc 사용, C언어 (C99를 가르치기엔 복잡해지니 ANSI C 기준)
- 함수의 정의 및 사용
- 파일을 여러개로 분리하여 컴파일
정도입니다.
CC-BY-SA, by sftblw
스토리 게임을 만드려고 한다. 문장을 출력한 뒤, 문장 끝 부분에 연필이 굴러가는 것 같은 애니메이션을 넣으면 좋을 것 같다.
\b
와 usleep(int)
을 사용하여 회전하는 기호 (\, |, /, - 를 순서대로 출력) 가 지정한 횟수만큼 반복하여 출력되는 함수 marked_sleep(int repeat_count)
를 작성하고 출력하는 데 사용하라. usleep(int)
으로 각각의 기호를 출력할 때마다 0.25 초씩 대기하라.
\b
기호를 사용하면 한 글자 앞으로 커서를 옮길 수 있다. 실제로 지워지지는 않지만, 지운다고 생각하면 편하다.\b
기호를 출력한 뒤에 화면에 결과가 나오지 않는다면printf("\b")
를 호출한 후fflush(stdio)
를 호출하라.usleep(int)
은unistd.h
헤더에 있으며, 마이크로초를 입력으로 받아 대기하므로, 실제 호출할 때는 초단위로 대기하려면 1000 * 1000 을 곱해야 한다.
#include <stdio.h>
#include <unistd.h>
void marked_sleep(int repeat_count);
int main() {
// 예제 입력
printf("It is a good day to die... ");
marked_sleep(3);
printf("\n");
printf("and do a barrel roll... ");
marked_sleep(4);
printf("\n");
printf("and HEROES OF THE STORM! ");
marked_sleep(5);
printf("\n");
}
#include <stdio.h>
#include <unistd.h>
void marked_sleep(int repeat_count);
int main() {
// 예제 입력
printf("It is a good day to die... ");
marked_sleep(3);
printf("\n");
printf("and do a barrel roll... ");
marked_sleep(4);
printf("\n");
printf("and HEROES OF THE STORM! ");
marked_sleep(5);
printf("\n");
}
void marked_sleep(int repeat_count) {
int delay = 1000 * 1000 / 4;
int i = 0;
printf(" ");
for (i = 0; i < repeat_count; i++) {
printf("\b\\");
fflush(stdout);
usleep(delay);
printf("\b|");
fflush(stdout);
usleep(delay);
printf("\b/");
fflush(stdout);
usleep(delay);
printf("\b-");
fflush(stdout);
usleep(delay);
}
printf("\b ");
fflush(stdout);
}
그림을 그리는 함수를 만들어놓고 나중에 쓰려고 한다.
속이 빈 사각형을 출력하는 함수 draw_rect(int width, int height)
와 속이 찬 사각형을 출력하는 함수 fill_rect(int width, int height)
를 별도의 파일 paint_rect.c
와 paint_rect.h
에 작성하여 컴파일하고 메인 함수에서 출력하는 프로그램을 작성하라.
- 속이 빈 사각형을 출력할 때, 가로폭 1, 세로폭 1인 경우에도 정상적으로 출력할 수 있어야 한다.
- 힌트:
*
는 출력할 수 있는 조건에만 출력하고, 그 외에는 모두 공백을 출력하면 됨
- 힌트:
#ifndef
등을 사용하여 헤더paint_rect.h
가 여러 번 include 되어도 동작할 수 있게 작성하고 이를 보여라.- 참고: 그리는 함수에서 사용하는
for
문은i, j
같은 변수명보다x, y
같은 변수명을 사용하는 게 덜 헷갈린다.
draw rect: 5 3
*****
* *
*****
fill rect: 5 3
*****
*****
*****
main.c
#include <stdio.h>
#include "paint_rect.h"
#include "paint_rect.h"
int main() {
int width, height;
printf("draw rect: ");
scanf(" %d %d", &width, &height);
draw_rect(width, height);
}
paint_rect.h
#ifndef __DRAW_RECT_H__
#define __DRAW_RECT_H__
void draw_rect(int width, int height);
void fill_rect(int width, int height);
#endif
paint_rect.c
#include "paint_rect.h"
void draw_rect(int width, int height) {
int y, x;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
if (x == 0
|| x == width - 1
|| y == 0
|| y == height - 1
) {
printf("*");
}
else printf(" ");
}
printf("\n");
}
}
void fill_rect(int width, int height) {
int y, x;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
printf("*");
}
printf("\n");
}
}
모바일 게임 <신데렐라 대전쟁> 에는 스태미너라는 자원이 있다. "스태미너"를 사용해야 게임을 플레이할 수 있고, "스태미너"가 5분마다 1씩 자동으로 충전된다.
- 현재 스태미너와 최대 스태미너를 입력받아 스태미너가 완전히 충전되려면 몇 분 걸리는지 반환하는 함수
stamina_calculate(int current_stamina, int max_stamina)
를 별도의 파일stamina.h
와stamina.c
에 작성하라. - 분을 입력받아 "7hour 2min", "3day 4hour 6min"과 같은 형태로 출력하는 함수
print_duration(int minute)
를 위에서 만든 파일에 작성하라. 출력 형식은 일, 시, 분 외에는 고려하지 않는다. - 위 두 함수를 사용하여, 현재 스태미너와 최대 스태미너를 입력받으면
stamina_calculate_print(int current_stamina, int max_stamina)
몇 시간 걸리는지 출력하는 함수를 위에서 만든 파일에 작성하고 main 함수에서 테스트하라. #ifndef
등을 사용하여 헤더paint_rect.h
가 여러 번 include 되어도 동작할 수 있게 작성하고 이를 보여라.
current stamina: 346
max stamina: 765
charge duration: 1day 10hour 55min
main.c
#include <stdio.h>
#include "stamina.h"
int main() {
int current_stamina, max_stamina;
printf("current stamina: ");
scanf(" %d", ¤t_stamina);
printf("max stamina: ");
scanf(" %d", &max_stamina);
printf("charge duration: ");
stamina_calculate_print(current_stamina, max_stamina);
}
stamina.h
#ifndef __STAMINA_H__
#define __STAMINA_H__
int stamina_calculate(int current_stamina, int max_stamina);
void print_duration(int minute);
void stamina_calculate_print(int current_stamina, int max_stamina);
#endif
stamina.c
#include "stamina.h"
int stamina_calculate(int current_stamina, int max_stamina) {
return (max_stamina - current_stamina) * 5;
}
void print_duration(int minute) {
int day, hour;
if (minute > 60 * 60) {
day = minute / (60 * 60);
minute %= (60 * 60);
printf("%dday ", day);
}
if (hour > 60) {
hour = minute / (60);
minute %= (60);
printf("%dhour ", hour);
}
printf("%dmin\n", minute);
}
void stamina_calculate_print(int current_stamina, int max_stamina) {
print_duration(stamina_calculate(current_stamina, max_stamina));
}
- 1번
- 3번
- 346
- 765
- 7h 2min
- 모티프는 @sftblw_bot 에 구현되어 있는 데레스테 스태미너 계산 명령어입니다.
- 2번 문제는 1학기때 조교로 들어갔다 낸 문제인데, x나 y중 하나가 1이거나 2인 경우에 대해 못 하는 경우가 많았습니다.
- 3번 문제도 마찬가지로 1학기때 조교로 들어갔다 냈던 것을 약화한 문제입니다. 좀 더 복잡하게 만드려면, 실제로 언제 다 충전되는지 계산하라고 하면 더 어렵게 만들 수 있습
- 1번은 재밌으라고 낸 건데 실습용으로는 적절치 않다는 지적이 많이 들어왔습니다.