Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14092
  • 博文数量: 9
  • 博客积分: 50
  • 博客等级: 民兵
  • 技术积分: 42
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-15 18:34
个人简介

简简单单才是美!就像linux 0.11代码那样……

文章存档

2013年(9)

我的朋友

分类: C/C++

2013-05-06 11:04:58

俄罗斯方块游戏代码如下:                                                  运行结果请点击:http://blog.chinaunix.net/uid-28257812-id-3654262.html

#include
#include
#include
#include
#include
#include
#include
#include
#ifndef _BLOCK_H_
#define _BLOCK_H_
#define  p_x 10           //初始化行的位置;
#define  p_y 5            //初始化出口的位置;
#define  X 20                    // 游戏窗口大小尺寸
#define  Y 18
#define  LEVEL_SCORE 500         // 升级需要的分数

jmp_buf env;
static  int x, y;                                      //   当前方块的位置
static  int flag_erase;                                    //   删除标志
static  int num, mode, next_num, next_mode;                //   当前的方块和下一个方块
static  int save_row, save_col, save_x, save_y, save_mode;//   保存坐标, 保存图像
static  int color, save_color, flag_color;        //   保存下一块方块的颜色
static  int matirx[Y][X] = { 0 };                          //   保存方块的模型
static  int level = 1;                                     //   最初的游戏等级水平
static  int score = 0;                       //   最初的游戏分数
/*
struct itimerval {
struct timeval it_interval; // 下一个值
struct timeval it_value;    // 当前的值 
};
struct timeval {
long tv_sec;                // 秒
long tv_usec;               // 微秒 
};
*/
typedef struct itimerval LEVEL;   //itimerval表示数据结构,系统调用time和stime ……用于控制方块下沉的速度
static LEVEL level_00 = { {0,      0}, {0,      0} };   //时间间隔为0
static LEVEL level_01 = { {0, 800000}, {1,      0} };   
static LEVEL level_02 = { {0, 500000}, {0, 500000} };
static LEVEL level_03 = { {0, 400000}, {0, 300000} };
static LEVEL level_04 = { {0, 300000}, {0, 300000} };
static LEVEL level_05 = { {0, 200000}, {0, 300000} };
static LEVEL level_06 = { {0, 150000}, {0, 300000} };
static LEVEL level_07 = { {0, 100000}, {0, 300000} };
static LEVEL level_08 = { {0, 80000 }, {0, 300000} };
static LEVEL level_09 = { {0, 60000 }, {0, 300000} };
//利用三维保存方块和方块的形状
//第一维用于保存方块的形状
//第二维用于保存可变的模式
//第三维用于保存行和出口真实的值
static const int shape[7][4][18] = {    //定义方块形状的结构体,其中7表示七种方块形状、4表示四种变化模式上下左右、18表示行和出口真实的值
                              {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1,     2, 1},   //        
                               {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0,     1, 2},    //   []    []    [][][]     []
                               {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0,     2, 1},    // [][][] [][]    []     [][]
                               {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1,     1, 2}},  //          []                []

                              {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1,     2, 1},   //
                               {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1,     1, 2},  //             []                [][]
                               {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0,     2, 1},   //        []  []      [][][]     []
                               {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1,     1, 2}},   // [][][]  [][]   []           []

                              {{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1,     1, 2},   //
                               {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1,     2, 1},   //          [][]                []
                               {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0,     1, 2},    // []        []    [][][]     []
                               {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1,     2, 1}},  // [][][]   []         []   [][]

                              {{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,     1, 2},   // 
                               {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0,     2, 1},   //    []
                               {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,     1, 2},   //    [][]      [][]
                               {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0,     2, 1}}, //       []   [][]

                              {{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0,     1, 2},   //
                               {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1,     2, 1},   //       []
                               {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0,     1, 2},   //     [][]   [][]
                               {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1,     2, 1}},  //    []        [][]

                              {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1,     2, 2},   //
                               {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1,     2, 2},   //
                               {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1,     2, 2},   //      [][]
                               {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1,     2, 2}},  //     [][]

                              {{0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,     0, 3},   //     []
                               {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,     3, 0},   //      []     [][][][]
                               {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,     0, 3},   //      [] 
                               {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,     3, 0}}   //     []     
                             };
void init_for_globle(void);   //初始化全局函数
void print_start_interface(void);  //打印游戏的开始接口
void print_mode_shape(void);  //打印方块的模式形状
void print_save_matrix(void); //打印保存的矩阵
void change_shape(void);  //改变方块的形状
void move_left(void);   //向左移动
void move_right(void);  //向右移动
void move_down();  //向下移动 
void fall_down();  //下沉
void store_flag_color(void);  //设置游戏标志颜色
void key_control(void);   //设置控制键
void erase_last(void);   //擦除最后一个方块
void destroy_line(void);  //当游戏中方块拼满一行时,销毁这一行
void print_next(void);  //打印下一个方块
void erase_next(void);  //擦除下一个方块
void change_level(void);  //改变游戏水平
void print_score(void);  //打印游戏分数
void print_level(void);  //打印游戏水平
int  judge_by_color(int x, int mode);   //判断方块颜色
void game_over(void);   //游戏结束
#endif

//定义主函数main(int argc, char **argv)
int main (int argc, char **argv)
{
    init_for_globle ();         //初始化全局函数
    print_mode_shape ();        //打印第一个方块 
    print_next ();              //打印下一个方块
    setitimer (ITIMER_REAL, &level_01, NULL);   //初始化游戏水平为1;时间间隔800ms
    signal (SIGALRM, move_down);    //方块下沉取决于时间间隔
    key_control ();             //用方向键控制游戏
    return 0;
}

//初始化全局函数
void init_for_globle(void)
{
    x = X / 2 - 2;        // 第一个方块出现的位置
    flag_erase = 1;         //把擦除标志设置为1
    srand(getpid());    //获取当前进程识别码
    num = rand() % 7;    // 随机出现的第一块方块
    mode = rand() % 4;    // 第一块方块的随机变化模式
    color = rand() % 7 + 41;    // 第一块方块的随机颜色
    next_num = rand() % 7;         //随机出现的下一块方块
    next_mode = rand() % 4;        //下一块方块的随机变化模式
    save_color = rand() % 7 + 41;   //下一块方块的随机颜色
    print_start_interface();    // 打印游戏的开始接口
    print_score();        // 打印游戏初始化的分数为0
    print_level();        // 打印游戏初始化的水平为1
}

//打印开始接口
void print_start_interface(void)
{
    int x, y;
    printf("\33[2J");
    printf("\33[%d;%dH\33[32m分数:\33[0m", p_y + 10, p_x + 25);
    printf("\33[%d;%dH\33[32m等级:\33[0m", p_y + 14, p_x + 25);
    for (x = p_x, y = p_y; x <= 46; x++)
        printf("\33[%d;%dH\33[41m==\33[0m", y, x);
    for (x = p_x, y = p_y + 1; y <= 25; y++)
        printf("\33[%d;%dH\33[41m||\33[0m", y, x);
    for (x = p_x + 22, y = p_y + 1; y <= 25; y++)
        printf("\33[%d;%dH\33[41m||\33[0m", y, x);
    for (x = p_x + 36, y = p_y + 1; y <= 25; y++)
        printf("\33[%d;%dH\33[41m||\33[0m", y, x);
    for (x = p_x + 24, y = p_y + 8; x <= 44; x++)
        printf("\33[%d;%dH\33[41m--\33[0m", y, x);
    for (x = p_x, y = p_y + 21; x <= 46; x++)
        printf("\33[%d;%dH\33[41m==\33[0m", y, x);
    printf("\33[?25l");
    fflush(stdout);
}

//擦除最后一个方块
void erase_last(void)
{
    int j, x1, y1, n;
    x1 = save_x + p_x + 2;
    for (j = 0, n = 0; j < 16; j++) {
        if (j / 4 >= shape[num][save_mode][16] && j % 4 == 0) {
            y1 = save_y + p_y + 1 + n;
            printf("\33[%d;%dH", y1, x1);
            n++;
        }
        if (j / 4 >= shape[num][save_mode][16]&& j % 4 >= shape[num][save_mode][17]) {
            if (shape[num][save_mode][j] == 0) {
                printf("\33[2C");
            }
            if (shape[num][save_mode][j] == 1) {
                printf("  ");
            }
        }
    }
    fflush(stdout);
}

//打印方块的模式形状
void print_mode_shape(void)
{
    int j, x1, y1, n;
    int left_flag = 0;
    if (flag_erase == 0) {
        erase_last();
    }
    x1 = x + p_x + 2;
    for (j = 0, n = 0; j < 16; j++) {
        if (j / 4 >= shape[num][mode][16] && j % 4 == 0) {
            y1 = y + p_y + 1 + n;
            printf("\33[%d;%dH", y1, x1);
            n++;
        }
        if (j / 4 >= shape[num][mode][16]
            && j % 4 >= shape[num][mode][17]) {
            if (shape[num][mode][j] == 0) {
                printf("\33[2C");
            }
            if (shape[num][mode][j] == 1) {
                printf("\33[%dm[]\33[0m", color);
            }
        }
        fflush(stdout);
    }
    printf("\33[0m");
    fflush(stdout);
    save_x = x;
    save_y = y;
    save_mode = mode;
    save_row = 4 - shape[num][mode][16];
    save_col = 4 - shape[num][mode][17];
    flag_erase = 0;
}

//根据标志的颜色来把方块储存到矩阵中去
void store_flag_color(void)
{
    int i, a = 0, b = 0;
    for (i = 0; i < 16; i++) {
        if (i / 4 >= shape[num][mode][16] && i % 4 == 0) {
            a++;
            b = 0;
        }
        if (i / 4 >= shape[num][mode][16]&& i % 4 >= shape[num][mode][17]) {
            if (shape[num][save_mode][i] == 0) {
                b = b + 2;
            }
            if (shape[num][save_mode][i] == 1) {
                matirx[save_y + a - 1][save_x + b] = color;
                b++;
                matirx[save_y + a - 1][save_x + b] = color;
                b++;
            }
        }
    }
}

//打印保存的矩阵
void print_save_matrix(void)
{
    int i, j, n = 0;
    for (i = 0; i < Y; i++) {
        printf("\33[%d;%dH", i + p_y + 1, p_x + 2);
        for (j = 0; j < X; j++) {
            if (matirx[i][j] != 0) {
                n = (n + 1) % 2;
                fprintf(stdout, "\33[%dm", matirx[i][j]);
                (n == 1) ? printf("[") : printf("]");
            }
            if (matirx[i][j] == 0) {
                printf("\33[0m");
                printf(" ");
            }
            fflush(stdout);
        }
    }
}

// 变换方块的形状
void change_shape(void)
{
    int i, n;
    for (i = 0; i < save_row; i++) {
        if (num == 6) {
            n = 4;
        } else {
            n = 0;
        }
        if (((x + n) >= X - save_col * 2 && save_col < save_row) ||
            judge_by_color(x, (mode + 1) % 4) == 1) {
            return;
        }
    }
    mode = (mode + 1) % 4;
    fflush(stdout);
    print_mode_shape();
    fflush(stdout);
}

//向右移动方块
void move_right(void)
{
    int i;
    if (x >= X - save_col * 2 || judge_by_color(x + 2, mode) == 1) {
        return;
    }
    x = x + 2;
    print_mode_shape();
    fflush(stdout);
}

// 向左移动方块
void move_left(void)
{
    int i;
    if (x <= 0 || judge_by_color(x - 2, mode) == 1) {
        return;
    }
    x = x - 2;
    print_mode_shape();
    fflush(stdout);
}

// 向下移动方块
void move_down()
{
    y++;
    if (y >= Y - save_row + 1 || judge_by_color(x, mode) == 1) {
        store_flag_color();
        game_over();
        y = 0;
        save_row = 0;
        save_col = 0;
        x = X / 2 - 2;
        num = next_num;
        mode = next_mode;
        color = save_color;
        next_num = random() % 7;
        next_mode = random() % 4;
        save_color = random() % 7 + 41;
        print_next();
        flag_erase = 1;
        destroy_line();
        fflush(stdout);
        return;
    }
    print_mode_shape();
    fflush(stdout);
}

// 控制方块下沉
void fall_down()
{
    while (1) {
        y++;
        if (y >= Y - save_row + 1 || judge_by_color(x, mode) == 1) {
            store_flag_color();
            game_over();
            y = 0;
            save_row = 0;
            save_col = 0;
            x = X / 2 - 2;
            num = next_num;
            mode = next_mode;
            color = save_color;
            next_num = rand() % 7;
            next_mode = rand() % 4;
            save_color = rand() % 7 + 41;
            print_next();
            flag_erase = 1;
            destroy_line();
            fflush(stdout);
            return;
        }
        print_mode_shape();
        fflush(stdout);
    }
}

//擦除下一个提示的方块
void erase_next(void)
{
    int i, j, n = 0;
    for (i = 0; i < 4; i++) {
        printf("\33[%d;%dH", p_y + 3 + n, p_x + X + 7);
        n++;
        for (j = 0; j < 4; j++) {
            printf("  ");
        }
    }
    printf("\33[30;4H\33[?25l");
    fflush(stdout);
}

//打印下一个提示的方块
void print_next(void)
{
    int j, n = 0;
    erase_next();
    for (j = 0; j < 16; j++) {
        if (j / 4 >= shape[next_num][next_mode][16] && j % 4 == 0) {
            printf("\33[%d;%dH", p_y + 3 + n, p_x + X + 7);
            n++;
        }
        if (j / 4 >= shape[next_num][next_mode][16]&& j % 4 >= shape[next_num][next_mode][17]) {
            if (shape[next_num][next_mode] == 0) {
                printf("\33[2C");
            }
            if (shape[next_num][next_mode][j] == 1) {
                printf("\33[%dm[]\33[0m", save_color);
            }
        }
    }
}

//打印游戏分数信息
void print_score(void)
{
    printf("\33[%d;%dH\33[31m%d\33[0m", p_y + 10, p_x + X + 10, score);
    fprintf(stdout, "\33[%d;0H", p_y + 20 + 2);
}

//打印游戏级别信息
void print_level(void)
{
    printf("\33[%d;%dH\33[31m%d\33[0m", p_y + 14, p_x + X + 10, level);
    fprintf(stdout, "\33[%d;0H", p_y + 20 + 2);
}

//当方块拼满一行或多行时,销毁一行或多行方块    
void destroy_line(void)
{
    int i, j, full;
    int a, b, c;
    for (i = 0; i < Y; i++) {
        full = 1;
        for (j = 0; j < X; j++) {
            if (matirx[i][j] == 0) {
                full = 0;
            }
        }
        if (full == 1) {
            for (a = 0; a < i; a++) {
                for (b = 0; b < X; b++) {
                    matirx[i - a][b] = matirx[i - a - 1][b];
                }
            }
            print_save_matrix();
            score = score + 100;
            if (score % LEVEL_SCORE == 0) {
                level = level + 1;
                if (level >= 9)
                    level = 9;
                change_level();
                print_level();
            }
            print_score();
        }
    }
}

//改变游戏水平 , 改变游戏速度  
void change_level(void)
{
    switch (level) {
    case 1:
        setitimer(ITIMER_REAL, &level_01, NULL);
        break;
    case 2:
        setitimer(ITIMER_REAL, &level_02, NULL);
        break;
    case 3:
        setitimer(ITIMER_REAL, &level_03, NULL);
        break;
    case 4:
        setitimer(ITIMER_REAL, &level_04, NULL);
        break;
    case 5:
        setitimer(ITIMER_REAL, &level_05, NULL);
        break;
    case 6:
        setitimer(ITIMER_REAL, &level_06, NULL);
        break;
    case 7:
        setitimer(ITIMER_REAL, &level_07, NULL);
        break;
    case 8:
        setitimer(ITIMER_REAL, &level_08, NULL);
        break;
    case 9:
        setitimer(ITIMER_REAL, &level_09, NULL);
        break;
    default:
        break;
    }
}

//根据方块颜色来判断方块能否通过
int judge_by_color(int x, int mode)
{
    int i, a = 0, b = 0;
    for (i = 0; i < 16; i++) {
        if (i / 4 >= shape[num][mode][16] && i % 4 == 0) {
            a++;
            b = 0;
        }
        if (i / 4 >= shape[num][mode][16]&& i % 4 >= shape[num][mode][17]) {
            if (shape[num][mode][i] == 0) {
                b = b + 2;
            }
            if (shape[num][mode][i] == 1) {
                if (matirx[a + y - 1][b + x] != 0) {
                    return 1;
                } else
                    b = b + 2;
            }
        }
    }
}

//通过键盘键控制方块的变形模式,方向上键用于调节方块模式,下键用于加速方块下沉,左右键用于调整方块左右移动        
void key_control(void)
{
    int ch, flag = 1;
    struct termios save, raw;
    tcgetattr(0, &save);
    cfmakeraw(&raw);
    tcsetattr(0, 0, &raw);
    if (setjmp(env) == 0) {
        while (flag) {
            ch = getchar();
            if (ch == '\r') {
                fall_down();
            }
            if (ch == '\33') {
                ch = getchar();
                if (ch == '[') {
                    ch = getchar();
                    switch (ch) {
                    case 'A':
                        change_shape();
                        break;
                    case 'B':
                        move_down();
                        break;
                    case 'C':
                        move_right();
                        break;
                    case 'D':
                        move_left();
                        break;
                    }
                }
            }
            if (ch == 'q' || ch == 'Q') {
                flag = 0;
            }
        }
        printf("\33[%d;%dH\33[31m-------------game interrupt exit!-----\33[0m",p_y + Y + 3, p_x);
        printf("\33[%d;0H\33[?25h", p_y + Y + 4);
    }
    tcsetattr(0, 0, &save);
}

//当方块积攒到顶端时,方块若不能被销毁,则游戏结束,失败退出        
void game_over(void)
{
    int i;
    for (i = 0; i < X; i++) {
        if (matirx[1][i] != 0) {
            printf("\33[31m\33[%d;%dH-------------------------game over!-----------------\33[0m",p_y + Y + 3, p_x);
            printf("\33[0m\33[?25h\33[%d;0H", p_y + Y + 4);
            longjmp(env, 2);
        }
    }
}
阅读(1137) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~