俄罗斯方块

一共三个文件

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


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

你可能感兴趣的:(C++,c,C#,J#,qt)