俄罗斯方块

一共三个文件

实现得很恶心,很多代码没效率


SCR.c


#include "SCR.h"

typedef enum mode_t {
CHARACTER = 3,
BACKGROUND = 4
} mode_t;

static struct termios orig;
static unsigned int term_init = 0;

void clear(void)
{
fprintf(stderr, "\033[2J");
}

int start_iaction(int sec, int usec, void (*action)(int))
{
struct itimerval itimer;
struct sigaction sa;
int ret;

sa.sa_handler = action;
sigemptyset(&(sa.sa_mask));
sa.sa_flags = 0;
ret = sigaction(SIGALRM, &sa, NULL);
if (ret != 0) {
perror("sigaction");
return -1;
}

itimer.it_value.tv_sec = sec;
itimer.it_value.tv_usec = usec;
itimer.it_interval.tv_sec = sec;
itimer.it_interval.tv_usec = usec;
ret = setitimer(ITIMER_REAL, &itimer, NULL);
if (ret != 0) {
perror("setitimer");
sa.sa_handler = SIG_DFL;
sigemptyset(&(sa.sa_mask));
sa.sa_flags = 0;
sigaction(SIGALRM, &sa, NULL);
return -1;
}

return 0;
}

int stop_iaction(void)
{
struct itimerval itimer;
struct sigaction sa;
int ret;

memset(&itimer, '\0', sizeof(struct itimerval));
ret = setitimer(ITIMER_REAL, &itimer, NULL);
if (ret != 0) {
perror("setitimer");
return -1;
}
sa.sa_handler = SIG_DFL;
sigemptyset(&(sa.sa_mask));
sa.sa_flags = 0;
ret = sigaction(SIGALRM, &sa, NULL);
if (ret != 0) {
perror("sigaction");
}

return ret;
}

int get_winsz(int *row, int *col)
{
struct winsize win;
int ret;

ret = ioctl(STDOUT_FILENO, TIOCGWINSZ, &win);
if (ret != 0) {
perror("ioctl");
return -1;
}
*row = win.ws_row;
*col = win.ws_col;

return 0;
}

int stty(void)
{
struct termios ttystat;
int ret;

ret = tcgetattr(STDIN_FILENO, &ttystat);
if (ret != 0) {
perror("tcgetattr");
return -1;
}
if (term_init == 0) {
memcpy(&orig, &ttystat, sizeof(struct termios));
term_init = 1;
}
ttystat.c_lflag &= ~(ECHO | ICANON);
ttystat.c_cc[VMIN] = 1;
ret = tcsetattr(STDIN_FILENO, TCSANOW, &ttystat);
if (ret != 0) {
perror("tcsetattr");
return -1;
}
printf("\033[?25l\033[?1c");

return 0;
}

int rtty(void)
{
int ret;

if (term_init == 0) {
return 0;
}
ret = tcsetattr(STDIN_FILENO, TCSANOW, &orig);
if (ret != 0) {
perror("tcsetattr");
return -1;
}
printf("\033[?25h\033[?0c");

return 0;
}

int get_input(int expected)
{
char seq[8] = {0};
int ret;

while (1) {
ret = read(STDIN_FILENO, seq, 8);
if (ret < 0 && errno != EINTR) {
perror("read");
return -1;
}
if ((expected & UP) && ret == 3 &&
seq[0] == '\033' && seq[1] == '[' && seq[2] == 'A') {
return UP;
}
if ((expected & DOWN) && ret == 3 &&
seq[0] == '\033' && seq[1] == '[' && seq[2] == 'B') {
return DOWN;
}
if ((expected & RIGHT) && ret == 3 &&
seq[0] == '\033' && seq[1] == '[' && seq[2] == 'C') {
return RIGHT;
}
if ((expected & LEFT) && ret == 3 &&
seq[0] == '\033' && seq[1] == '[' && seq[2] == 'D') {
return LEFT;
}
if ((expected & ESC) && ret == 1 && seq[0] == '\033') {
return ESC;
}
if ((expected & ENTER) && ret == 1 && seq[0] == '\n') {
return ENTER;
}
if ((expected & KEY_Q) && ret == 1 &&
(seq[0] == 'q' || seq[0] == 'Q')) {
return KEY_Q;
}
if ((expected & KEY_S) && ret == 1 &&
(seq[0] == 's' || seq[0] == 'S')) {
return KEY_S;
}
if ((expected & KEY_H) && ret == 1 &&
(seq[0] == 'h' || seq[0] == 'H')) {
return KEY_H;
}
if ((expected & KEY_J) && ret == 1 &&
(seq[0] == 'j' || seq[0] == 'J')) {
return KEY_J;
}
if ((expected & KEY_K) && ret == 1 &&
(seq[0] == 'k' || seq[0] == 'K')) {
return KEY_K;
}
if ((expected & KEY_L) && ret == 1 &&
(seq[0] == 'l' || seq[0] == 'L')) {
return KEY_L;
}
}

return 0;
}

void move_curs(int x, int y)
{
printf("\033[%d;%dH", y, x);
}

void draw_rec(rec_t *rec)
{
int i, j;

printf("\033[%d%d;%d%dm",
BACKGROUND, rec->background, CHARACTER, rec->foreground);
for (i = 0; i < rec->h; ++i) {
printf("\033[%d;%dH", rec->y + i, rec->x);
for (j = 0; j < rec->w; ++j) {
printf("%c", rec->ch);
}
}
printf("\033[0m");
fflush(NULL);
return;
}


SCR.h


#ifndef _SCR_H_
#define _SCR_H_


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <errno.h>
#include <math.h>


typedef enum ch_t {
UP = 0x00000001,
DOWN = 0x00000002,
RIGHT = 0x00000004,
LEFT = 0x00000008,
ESC = 0x00000010,
ENTER = 0x00000020,
KEY_Q = 0x00000040,
KEY_S = 0x00000080,
KEY_H = 0x00000100,
KEY_J = 0x00000200,
KEY_K = 0x00000400,
KEY_L = 0x00000800
} ch_t;

typedef enum color_t {
COLOR_MIN = 0,
BLACK = 0,
RED,
GREEN,
YELLOW,
BLUE,
MAGENTA,
CYAN,
WHITE,
COLOR_MAX = WHITE
} color_t;


typedef struct rec_t {
int x;
int y;
int w;
int h;
char ch;
color_t background;
color_t foreground;
} rec_t;

void clear(void);

int stty(void);

int rtty(void);

int start_iaction(int sec, int usec, void (*)(int));

int stop_iaction(void);

int get_winsz(int *row, int *col);

int get_input(int expected);

void move_curs(int x, int y);

void draw_rec(rec_t *);

#endif


TETRIS.c

#include "SCR.h"

enum {
SEC = 0,
USEC = 500000
};

int A[4][4]={{0,0,0,0},
{0,1,1,0},
{0,1,1,0},
{0,0,0,0}};

int B[4][4]={{0,0,1,0},
{0,0,1,0},
{0,0,1,0},
{0,0,1,0}};

int C[4][4]={{0,1,0,0},
{0,1,1,0},
{0,1,0,0},
{0,0,0,0}};

int D[4][4]={{0,0,0,0},
{0,1,1,0},
{0,0,1,1},
{0,0,0,0}};

int E[4][4]={{0,0,0,0},
{0,0,1,1},
{0,1,1,0},
{0,0,0,0}};

int F[4][4]={{0,0,0,0},
{0,1,1,0},
{0,0,1,0},
{0,0,1,0}};

int G[4][4]={{0,0,0,0},
{0,1,1,0},
{0,1,0,0},
{0,1,0,0}};


int w_col;
int w_row;

#define up 2
#define down 23
#define right 22
#define left 4


int N,top=0;
int tmp_k;
int x,y;
int matrix[10][20];
int __rec_tmp[4][4];
int color[10][20];

rec_t bg;
rec_t __rec[4];


void ___draw_frame(int x,int y){

rec_t __frame;

__frame.x=x;
__frame.y=y+1;
__frame.w = 2;
__frame.h = 20;
__frame.ch = ' ';
__frame.background = RED;
__frame.foreground = RED;
draw_rec(&__frame);

__frame.x=x;
__frame.y=y;
__frame.w = 24;
__frame.h = 1;
__frame.ch = ' ';
__frame.background = RED;
__frame.foreground = RED;
draw_rec(&__frame);

__frame.x=x+22;
__frame.y=y+1;
__frame.w = 2;
__frame.h = 20;
__frame.ch = ' ';
__frame.background = RED;
__frame.foreground = RED;
draw_rec(&__frame);

__frame.x=x;
__frame.y=y+21;
__frame.w = 24;
__frame.h = 1;
__frame.ch = ' ';
__frame.background = RED;
__frame.foreground = RED;
draw_rec(&__frame);


}

void ___draw_bg(){


int i=0;
int j=0;
rec_t tmp;

for(i=0;i<20;i++){
for(j=0;j<10;j++){
tmp.x=(j+2)*2;
tmp.y=i+3;
tmp.w = 2;
tmp.h = 1;
tmp.ch = ' ';
tmp.background = color[j][i];
tmp.foreground = color[j][i];
draw_rec(&tmp);
}
}
___draw_frame(2,2);

}

void ___draw_square(int square[4][4]){

int i,j,k=0;

tmp_k=4;

k=0;

for(i=0;i<4;i++){
for(j=0;j<4;j++){
if(square[i][j]==1){
__rec[k].x=(i+4)*2;
__rec[k].y=(j+2)*1;
__rec[k].w = 2;
__rec[k].h = 1;
__rec[k].ch = ' ';
__rec[k].background = N;
__rec[k].foreground = N;
k++;
}
}
}
x=4;
y=2;

for(i=0;i<4;i++)
for(j=0;j<4;j++)
__rec_tmp[i][j]=square[i][j];


for(i=0;i<4;i++){
if(matrix[(__rec[i].x-4)/2][__rec[i].y-3]==1){
top=1;
}
}
}

int MAX_Y(rec_t __rec[],int count){

int max=0,i;
for(i=0;i<count;i++){
if(__rec[i].y >= max)
max=__rec[i].y;
}
return max;
}

int MAX_X(rec_t __rec[],int count){

int max=0,i;
for(i=0;i<count;i++){
if(__rec[i].x >= max)
max=__rec[i].x;
}
return max;
}

int MIN_X(rec_t __rec[],int count){

int min=__rec[0].x;
int i;
for(i=0;i<count;i++){
if(__rec[i].x <= min)
min=__rec[i].x;
}
return min;
}

int MIN_Y(rec_t __rec[],int count){

int min=__rec[0].y;
int i;
for(i=0;i<count;i++){
if(__rec[i].y <= min)
min=__rec[i].y;
}
return min;
}

int GameOver(){

int i,j,tmp1=0,tmp2=0;

for(i=0;i<20;i++){
for(j=0;j<10;j++){
tmp1 += matrix[j][i];
}
if(tmp1>0){
tmp2++;
}
if(tmp2==20 || top==1){
fprintf(stderr,"\n\tGame Over\n");
stop_iaction();
rtty();
exit(1);
}
tmp1=0;
}

return 0;
}

void Delete(){

int i,j,m,n,tmp;

for(i=0;i<20;i++){
for(j=0;j<10;j++){
tmp += matrix[j][i];
}
if(tmp==10){
for(n=i;n>0;n--){
for(m=0;m<10;m++){
matrix[m][n]=matrix[m][n-1];
color[m][n]=color[m][n-1];
}
}
}
tmp=0;
}

}

void Change(int arr[][4]){

int i=4,j=4;
int acc[4][4];

for(i=0;i<4;i++)
for(j=0;j<4;j++)
acc[i][j]=arr[i][j];

for(i=0;i<4;i++)
for(j=0;j<4;j++)
arr[i][j]=acc[j][3-i];
}

int Limit_D(rec_t __rec[],int tmp_k){

int i,j,status=0;
int max;
int flag=0;

for(i=0;i<tmp_k;i++){
flag=0;

for(j=0;j<tmp_k;j++){
if(__rec[i].x==__rec[j].x){
max=(__rec[i].y >= __rec[j].y ? __rec[i].y : __rec[j].y);
flag=1;
}
}

if(flag==1){
if(matrix[(__rec[i].x-4)/2][max-2]==1)
status=1;
}

if(flag==0){
if(matrix[(__rec[i].x-4)/2][__rec[i].y-2]==1)
status=1;
}

}

return status;
}

int Limit_R(rec_t __rec[],int tmp_k){

int i,j,status=0;
int max=0;
int flag=0;


for(i=0;i<tmp_k;i++){

flag=0;
max=0;

for(j=0;j<tmp_k;j++){
if(__rec[i].y==__rec[j].y){
max=(__rec[i].x > __rec[j].x ? __rec[i].x : __rec[j].x);
flag=1;
}
}
if(flag==1){
if(matrix[(max-4)/2+1][__rec[i].y-3]==1)
status=1;
}

if(flag==0){
if(matrix[(__rec[i].x-4)/2+1][__rec[i].y-3]==1)
status=1;
}

}

return status;
}

int Limit_L(rec_t __rec[],int tmp_k){

int i,j,status=0;
int min;
int flag=0;

for(i=0;i<tmp_k;i++){

min=MAX_X(__rec,tmp_k);
flag=0;

for(j=0;j<tmp_k;j++){
if(__rec[i].y==__rec[j].y && min >= __rec[j].x){
min=__rec[j].x;
flag=1;
}
}

if(flag==1){
if(matrix[(min-4)/2-1][__rec[i].y-3]==1)
return 1;
}

if(flag==0){
if(matrix[(__rec[i].x-4)/2-1][__rec[i].y-3]==1)
return 1;
}

}

return status;
}

void Transform(){

int i,j,k;
rec_t tmp[4];
int tmp_m[4][4];

for(i=0;i<4;i++)
for(j=0;j<4;j++)
tmp_m[i][j]=__rec_tmp[i][j];

for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=0;

for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=WHITE;

Change(tmp_m);

k=0;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
if(tmp_m[i][j]==1){
tmp[k].x=(i+x)*2;
tmp[k].y=(j+y)*1;
tmp[k].w = 2;
tmp[k].h = 1;
tmp[k].ch = ' ';
tmp[k].background = N;
tmp[k].foreground = N;
k++;
}
}
}

if(Limit_D(tmp,4)==0 && Limit_R(tmp,4)==0 && \
Limit_L(tmp,4)==0 && MIN_X(tmp,4)>left && \
MAX_X(tmp,4)<right && MAX_Y(tmp,4)<down && \
MIN_Y(tmp,4)>up){

for(i=0;i<4;i++)
__rec[i]=tmp[i];

for(i=0;i<4;i++)
for(j=0;j<4;j++)
__rec_tmp[i][j]=tmp_m[i][j];
}

for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=1;

for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=N;

}

void CALL_GATE(int sig){

int i=0;

if((Limit_D(__rec,4)==0)&&(MAX_Y(__rec,tmp_k)<22)){
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=0;
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=WHITE;
for(i=0;i<tmp_k;i++)
__rec[i].y++;
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=1;
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=N;
y++;
___draw_bg();

}else if(GameOver()==0){

Delete();
N=random()%7;

switch(N){
case 0:
___draw_square(A);
break;
case 1:
___draw_square(B);
break;
case 2:
___draw_square(C);
break;
case 3:
___draw_square(D);
break;
case 4:
___draw_square(E);
break;
case 5:
___draw_square(F);
break;
case 6:
___draw_square(G);
break;
default:
break;
}
if(GameOver()==0&&top==0){
___draw_bg();
}
}
}

void Init(void){

int i=0;
int j=0;
int ret;

for(i=0;i<10;i++)
for(j=0;j<20;j++)
matrix[i][j]=0;
for(i=0;i<10;i++)
for(j=0;j<20;j++)
color[i][j]=WHITE;

ret = get_winsz(&w_row, &w_col);
if(ret!=0){

fprintf(stderr,"ERROR\n");
exit(1);
}

clear();
bg.x = 1;
bg.y = 1;
bg.w = w_col;
bg.h = w_row;
bg.ch = ' ';
bg.background = WHITE;
bg.foreground = WHITE;
draw_rec(&bg);

N=4;
___draw_square(E);
___draw_frame(2,2);

for(i=0;i<tmp_k;i++)
draw_rec(&__rec[i]);

return;
}

void Response(void){

int out=0;
int ret=0;

int i=0;

while (out != 1) {
ret = get_input(UP | DOWN | LEFT | RIGHT | ESC);
if (ret == -1) {
printf("get input error!\n");
break;
}

switch (ret) {
case LEFT:
if (MIN_X(__rec,tmp_k) > left && Limit_L(__rec,4)==0) {
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=WHITE;
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=0;
for(i=0;i<tmp_k;i++)
__rec[i].x -= 2;
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=N;
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=1;
x--;
}
break;
case DOWN:
if (MAX_Y(__rec,tmp_k) + __rec[0].h < down && Limit_D(__rec,4)==0){
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=WHITE;
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=0;
for(i=0;i<tmp_k;i++)
__rec[i].y += 1;
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=N;
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=1;
y++;
}
break;
case UP:
Transform();
break;
case RIGHT:
if (MAX_X(__rec,tmp_k) + __rec[0].w <= right && Limit_R(__rec,4)==0){
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=WHITE;
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=0;
for(i=0;i<tmp_k;i++)
__rec[i].x += 2;
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=N;
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=1;
x++;
}
break;
case ESC:
out = 1;
break;
default:
break;
}
___draw_bg();
}

return;
}

int main(void){


Init();

stty();
start_iaction(SEC, USEC, CALL_GATE);

Response();

stop_iaction();
rtty();
move_curs(1, 1);
clear();

return 0;
}



编译输入 gcc TETRIS.c SCR.c -o TETRIS

这程序是终端下运行的 写这程序时 还不会QT
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值