안녕하세요 저는 C++을 공부하고있는 대학생입니다.
제가 리눅스를 이용해서 테트리스를 만들었느데, 기본적으로 라즈베리파이3를 사용하였으며, GPIO 컨트롤을 이용하여 화면을 제어 할 수 있는 테트리스를 만들었습니다.
우선. 화면의 좌표를 잡기 위해 간단히 숙지 해 두어야 할 것이 있습니다.
화면에서 가로가 X축, 세로가 Y축입니다. 다만 우리가 기존에 알고있는 좌표계에서의 X축의 양의방향 과 음의방향은 같지만, Y축은 반대로, 컴퓨터상에서 양의방향은 아래쪽방향 이며 음의방향은 위쪽 방향 입니다.
그리고 간단하게 제가 이 테트리스를 만들기 전, 아이디어를 말씀드리자면 배열을 이용해서 하였습니다. 테트리스 배열판을 가로 세로축으로 크기를 정한다음, 2차원배열을 이용해서 오리지널 맵 과 카피 맵 두가지 맵에 대한 배열을 만들어서 표현하였습니다. 소스코드는 아래와 같습니다.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define MAIN_X 10
#define MAIN_Y 20
int map[MAIN_X][MAIN_Y] = {0, };
int mapcpy[MAIN_X][MAIN_Y] = {0, };
void gotoxy(int x,int y) {
printf("\033[%d;%df",y,x);
fflush(stdout);
}
int maps(int n)
{
for(int i =0; i<MAIN_X; i++)
{
for(int j =0; j<MAIN_Y; j++)
{
if(i==MAIN_X-1||j==0||j==MAIN_Y-1)
{
map[i][j]=1;
mapcpy[i][j] = 1;
}
else
{
map[i][j] =0;
mapcpy[i][j]=0;
}
}
}
if(n == 1)
{
for(int i =0; i<MAIN_X; i++)
{
for(int j =0; j<MAIN_Y; j++)
{
if(map[i][j]==1)
{
printf("%c[43m",27);
printf("■");
printf("%c[49m",27);
}
else printf(" ");
}
printf("\n");
}
}
else
{
for(int i =0; i<MAIN_X; i++)
{
for(int j =0; j<MAIN_Y; j++)
{
if(mapcpy[i][j]==1)
{
printf("%c[43m",27);
printf("■");
printf("%c[49m",27);
}
else printf(" ");
}
printf("\n");
}
}
}
리눅스에는 기본적으로 gotoxy 함수가 없습니다. gotoxy 함수는 컴퓨터 좌표계를 이동시켜주는 역할을 합니다. 윈도우 헤더 안에 함수가 있지만, 저는 사용자 정의함수를 이용하여 새로 구현하였습니다.
이 소스코드는 map.h 라는 이름을 가지고있습니다.
아까 말씀드린 것 처럼, 사각형 문자를 이용해서 벽을 표현하였고, 그 벽이있는 부분을 0으로 모두 초기화 된 배열에서 1로 값을 치환하였습니다. 그 이유는, 충돌처리를 하기 위함입니다.
다음으로는 테트리스 블록에 관한 소스코드를 보여드리겠습니다.
#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdlib.h>
int block[7][4][4][4]={
{
{
1,1,0,0,
1,1,0,0,
0,0,0,0,
0,0,0,0
},
{
1,1,0,0,
1,1,0,0,
0,0,0,0,
0,0,0,0
},
{
1,1,0,0,
1,1,0,0,
0,0,0,0,
0,0,0,0
},
{
1,1,0,0,
1,1,0,0,
0,0,0,0,
0,0,0,0
}
},
{
{
1,1,1,1,
0,0,0,0,
0,0,0,0,
0,0,0,0
},
{
1,0,0,0,
1,0,0,0,
1,0,0,0,
1,0,0,0
},
{
1,1,1,1,
0,0,0,0,
0,0,0,0,
0,0,0,0
},
{
1,0,0,0,
1,0,0,0,
1,0,0,0,
1,0,0,0
}
},
{
{
1,1,0,0,
0,1,1,0,
0,0,0,0,
0,0,0,0
},
{
0,1,0,0,
1,1,0,0,
1,0,0,0,
0,0,0,0
},
{
1,1,0,0,
0,1,1,0,
0,0,0,0,
0,0,0,0
},
{
0,1,0,0,
1,1,0,0,
1,0,0,0,
0,0,0,0
}
},
{
{
0,1,1,0,
1,1,0,0,
0,0,0,0,
0,0,0,0
},
{
1,0,0,0,
1,1,0,0,
0,1,0,0,
0,0,0,0
},
{
0,0,0,0,
0,1,1,0,
1,1,0,0,
0,0,0,0
},
{
1,0,0,0,
1,1,0,0,
0,1,0,0,
0,0,0,0
}
},
{
{
1,1,1,0,
1,0,0,0,
0,0,0,0,
0,0,0,0
},
{
1,1,0,0,
0,1,0,0,
0,1,0,0,
0,0,0,0
},
{
0,0,1,0,
1,1,1,0,
0,0,0,0,
0,0,0,0
},
{
1,0,0,0,
1,0,0,0,
1,1,0,0,
0,0,0,0
}
},
{
{
1,0,0,0,
1,1,1,0,
0,0,0,0,
0,0,0,0
},
{
0,1,0,0,
0,1,0,0,
1,1,0,0,
0,0,0,0
},
{
1,1,1,0,
0,0,1,0,
0,0,0,0,
0,0,0,0
},
{
1,1,0,0,
1,0,0,0,
1,0,0,0,
0,0,0,0
}
},
{
{
0,1,0,0,
1,1,1,0,
0,0,0,0,
0,0,0,0
},
{
1,0,0,0,
1,1,0,0,
1,0,0,0,
0,0,0,0
},
{
1,1,1,0,
0,1,0,0,
0,0,0,0,
0,0,0,0
},
{
0,1,0,0,
1,1,0,0,
0,1,0,0,
0,0,0,0
}
}
};
4차원배열로 표현하였습니다. 각각, 모양(shape) ,회전(rotation) , 블록 모양(2차원 배열) 로 표현하였습니다.
sensor.h라는 이름으로 만들어 주었습니다.
다음은 센서 제어를 이용한 소스코드를 보여드리겠습니다.
#include <iostream>
#include <stdio.h>
#include <wiringPi.h>
#define up 29
#define upL 23
#define right 28
#define rightL 22
#define down 27
#define downL 1
#define left 21
#define leftL 0
void sensor()
{
wiringPiSetup();
pinMode(up,INPUT);
pinMode(upL,OUTPUT);
pinMode(left,INPUT);
pinMode(leftL,OUTPUT);
pinMode(down,INPUT);
pinMode(downL,OUTPUT);
pinMode(right,INPUT);
pinMode(rightL,OUTPUT);
int curnumU =0;
int curnumD =0;
int curnumL =0;
int curnumR =0;
//void up{
if(digitalRead(up)==0)
{
digitalWrite(upL,1);
curnumU = 5;
}
else
{
digitalWrite(upL,0);
curnumU = 0;
}
//void left{
if(digitalRead(left)==0)
{
digitalWrite(leftL,1);
curnumL = 3;
}
else
{
digitalWrite(leftL,0);
curnumL = 0;
}
//void right{
if(digitalRead(right)==0)
{
digitalWrite(rightL,1);
curnumR = 1;
}
else
{
digitalWrite(rightL,0);
curnumR = 0;
}
//void down{
if(digitalRead(down)==0)
{
digitalWrite(downL,1);
curnumD = 2;
else
{
digitalWrite(downL,0);
curnumD = 0;
}
}
스위치랑 LED를 이용해서 제어 한 소스코드입니다. wiringPi 핀 번호를 이용해서 GPIO를 다루었습니다.
curnumD 숫자의 5 1 2 3 의미는, 키보드 패드 오른쪽 숫자패드에,
동서남북 방향의 키보드를 이용해서 컨트롤 하기 위함입니다. (혹시 키보드로 컨트롤 해야 할 경우를 대비해서 만들어 두었습니다.)
이렇게 부족한 실력이지만, 테트리스를 만들어보았는데요. 무엇보다도 혼자 만들었다는것에 보람을 느꼈고, 쭉 해보면서 저 스스로 부족한 부분을 많이 찾아보기도 하였고, 개인적으로 아쉬웠던 점을 보면서 조금 더 보완하고 돌아보았던 계기가 되었던 것 같습니다.
main 파일은 코드 길이가 900줄정도 되어서, 따로 올리기엔 힘들 것 같습니다. 그래서 핵심이 되는 헤더파일을 간단하게 정리함으로써 간단하게 올려보았습니다.
처음으로 1200줄정도 되는 코드를 작성해보아서 제가 가진 실력이 어느정도인지 알 수 있었고, 좋은 경험이 되었던 것 같습니다. 기존보다 더 열심히 해야 할 것 같습니다.