리메이크 중/C,C++ 실습 중심

C(&C++) 실습 9. 매트릭스 시분할 예제

라이피 (Lypi) 2023. 1. 11. 19:03
반응형


예제 출처

SoEn (soen.kr)


 

#include <Turboc.h>

#define MAX		1024
// 신호 최대 갯수 정의
#define LEFT		75
#define RIGHT		77
#define UP		72
#define DOWN		80
#define ESC		27 
// 특수 키 정의

struct Signal 
{
	bool		exist;		//신호 존재 유무
	char		ch;		//신호의 문자
	int		x, y;		//신호의 위치
	int		distance;	//신호가 한번에 이동할 거리
	int		nFrame;		//이동할 타이밍 (속도)
	int		nStay;		//속도에 대한 카운터
};
//신호 구조체

Signal S[MAX];
//신호 구조체 배열 선언


int main()
{
	int freq = 15;
	int frame = 200;
	//신호 빈도와 속도 기본값

	clrscr();
	gotoxy(0, 23);
	printf("매 트 릭 스  흉 내 내 기. 상하: 속도 증감, 좌우: 빈도 증감, ESC: 종료");
	randomize();

	while (true) {
		gotoxy(60, 23);
		printf("속도:%d, 빈도:%d    ", frame, freq);

		//키 입력 처리
		if (_kbhit()) {
			int ch = _getch();
			if (ch == 0xE0) {
				ch = _getch();
				switch (ch) {
				case UP:
					frame = min(frame + 10, 1000);
					break;
				case DOWN:
					frame = max(frame - 10, 10);
					break;
				case RIGHT:
					freq = max(freq - 1, 1);
					break;
				case LEFT:
					freq = min(freq + 1, 30);
					break;
				}
			}
			else {
				if (ch == ESC) {
					return 0;
				}
			}
		}


		//새로운 신호 생성
		if (random(freq) == 0) {
			for (int i = 0; i < MAX; i++) {
				if (S[i].exist == false) {
					S[i].exist = true;
					S[i].ch = random('Z' - 'A' + 1) + 'A';
					S[i].x = random(80);
					S[i].y = 0;
					S[i].distance = random(14) + 9;
					S[i].nFrame = S[i].nStay = random(15) + 5;
					break;
				}
			}
		}

		//주기가 다 된 신호 이동 및 제거 처리
		for (int i = 0; i < MAX; i++) {
			if (S[i].exist == false) {
				continue;
			}
			if (--S[i].nStay == 0) {
				S[i].nStay = S[i].nFrame;
				gotoxy(S[i].x, S[i].y); _putch(' ');
				if (++S[i].y < S[i].distance) {
					gotoxy(S[i].x, S[i].y); _putch(S[i].ch);
				}
				else {
					S[i].exist = FALSE;
				}
			}
		}
		delay(1000 / frame);

	}
}

■ define문 : 뒤의 코드를 앞의 단어로 단순 치환하는 문법. 

■ 전처리문이므로 코드 앞쪽에서 #으로 시작한다. 

■ #define A B 라고 쓰면 B 부분의 코드를 A라는 단어로 치환한다.

■ ex ) #define A (i+i)*j

■ A라는 단어를 쓰면 그 곳에 (i+i)*j라는 코드가 대신 삽입된다. 

■ 여기서는 신호 개수의 최대치와 키입력에 사용되는 특수키 숫자값을 치환했다.

 

■ 구조체 : 타입이 다른 변수들을 하나로 묶어서 처리하는 문법

■ C++에서는 클래스의 기본이 되며 함수도 넣을 수 있다.

■ 신호 구조체를 배열로 선언할 예정이므로 구조체의 이름을 먼저 정해주었다.

■ 구조체 변수가 하나만 필요하다면 이름을 생략하고 마지막에 변수명을 적으면 된다. 

 

■ 첫번째가 구조체 변수가 하나만 필요할 때, 두번째가 여러개를 사용할 때의 예이다.

■ 구조체를 정의해두고 필요할 때 마다 쓸 수 있으므로 주로 두번째 방법을 사용한다.

 

■ _kbhit() : 키보드가 눌렸는지 확인하는 함수.

■ 어떤 키가 눌렸는지는 _getch() 함수로 한번 더 확인해야한다.

■ 0xE0 : 눌린키가 방향키 같은 특수키인지 확인하는 값.

 

■ 시분할 : 시간을 나눠서 필요로 하는 대상에게 나눠주는 방식. 

■ 예를 들어 신호 1은 3초에 한번씩 이동하고, 신호 2는 1초에 한번씩 이동한다면 신호2가 훨씬 빠르게 보일 것이다.

■ 예제 속 무한 루프 마지막에 delay() 함수가 시간을 나누는 역할을 한다.

■ delay() 함수는 인자로 밀리초 단위를 사용하므로 1000을 넣어주면 1초가 된다.

■ 이를 원하는 프레임 예를 들어 n으로 나눠주면 n fps(frame per second)가 된다.

 

■ 90번째 줄에서 nStay가 0이랑 같은지 확인하기 전에 nStay값을 1씩 줄이고 있다.

■ 이 값이 0이 되면 nStay값을 nFrame값으로 초기화하고 움직임을 처리한다.

반응형