俄罗斯方块
头文件
#define FRAME_WIDTH 80 //游戏框架宽度
#define FRAME_HEIGHT 25 //游戏框架高度
#define FRAME_STARTPOS_X 20 //起始位置X坐标
#define FRAME_STARTPOS_Y 2 //起始位置Y坐标#define ELS_WIDTH 8 //俄罗斯方块宽度
#define ELS_HEIGHT 4 //俄罗斯方块高度
#define ELS_START_POS_X (((FRAME_WIDTH/3*2))/2-(ELS_WIDTH/2))
#define ELS_START_POS_Y (1)
#define NEXT_BOX_POS_X (((FRAME_WIDTH/3*2)+(FRAME_WIDTH/3/2))-(ELS_WIDTH/2)+1)
#define NEXT_BOX_POS_Y ((FRAME_HEIGHT/4)-(ELS_HEIGHT/2)+1)#define GAME_STAT_RUNNING 1
#define GAME_STAT_PAUSE 2/* 俄罗斯方块类型 */
struct els {int no; //编号int nextno; //变形后的编号unsigned char els[ELS_HEIGHT][ELS_WIDTH]; //俄罗斯方块数组
};extern int curx; //当前俄罗斯方块的横坐标
extern int cury; //当前俄罗斯方块的纵坐标
extern struct els curbox; //当前俄罗斯方块
extern struct els nextbox; //当前俄罗斯方块
extern unsigned char frame[FRAME_HEIGHT][FRAME_WIDTH]; //游戏框架数组extern int score;extern void init_frame(void);
extern void test_printf(void);
extern void show_frame(void);
extern void create_box(struct els* pels, int no);
extern void movebox(struct els* pels, int y, int x);
extern int can_movebox(struct els* pels, int y, int x);
extern void clear_movebox(struct els* pels, int y, int x);
extern void check_line(void);
extern void clear_line(int n);
定义函数
#include <stdio.h>
#include <string.h>
#include "els.h"unsigned char frame[FRAME_HEIGHT][FRAME_WIDTH];
struct els nextbox;
struct els curbox;
void create_box(struct els* pels, int no)
{int i = 0;int j = 0;if (0 == no){pels->no = 0;pels->nextno = 1;for (i = 0; i < ELS_WIDTH; i++){pels->els[0][i] = '#';}}else if (1 == no){pels->no = 1;pels->nextno = 0;for (j = 0; j < ELS_HEIGHT; j++){pels->els[j][0] = '#';pels->els[j][1] = '#';}}else if (no >= 2 && no <= 5) {pels->no = no;pels->nextno = (no == 5) ? 2 : no + 1;if (no == 2){pels->els[0][0] = '#';pels->els[0][1] = '#';pels->els[1][0] = '#';pels->els[1][1] = '#';pels->els[2][0] = '#';pels->els[2][1] = '#';pels->els[2][2] = '#';pels->els[2][3] = '#';}else if (no == 3){pels->els[0][4] = '#';pels->els[0][5] = '#';pels->els[1][0] = '#';pels->els[1][1] = '#';pels->els[1][2] = '#';pels->els[1][3] = '#';pels->els[1][4] = '#';pels->els[1][5] = '#';}else if (no == 4){pels->els[0][0] = '#';pels->els[0][1] = '#';pels->els[0][2] = '#';pels->els[0][3] = '#';pels->els[1][2] = '#';pels->els[1][3] = '#';pels->els[2][2] = '#';pels->els[2][3] = '#';}else {pels->els[0][0] = '#';pels->els[0][1] = '#';pels->els[0][2] = '#';pels->els[0][3] = '#';pels->els[0][4] = '#';pels->els[0][5] = '#';pels->els[1][0] = '#';pels->els[1][1] = '#';}}else if (no >= 6 && no <= 9) {pels->no = no;pels->nextno = (no == 9) ? 6 : no + 1;if (no == 6){pels->els[0][0] = '#';pels->els[0][1] = '#';pels->els[0][2] = '#';pels->els[0][3] = '#';pels->els[1][2] = '#';pels->els[1][3] = '#';pels->els[1][4] = '#';pels->els[1][5] = '#';}else if (no == 7){pels->els[0][2] = '#';pels->els[0][3] = '#';pels->els[1][0] = '#';pels->els[1][1] = '#';pels->els[1][2] = '#';pels->els[1][3] = '#';pels->els[2][0] = '#';pels->els[2][1] = '#';}else if (no == 8){pels->els[0][2] = '#';pels->els[0][3] = '#';pels->els[0][4] = '#';pels->els[0][5] = '#';pels->els[1][0] = '#';pels->els[1][1] = '#';pels->els[1][2] = '#';pels->els[1][3] = '#';}else {pels->els[0][0] = '#';pels->els[0][1] = '#';pels->els[1][0] = '#';pels->els[1][1] = '#';pels->els[1][2] = '#';pels->els[1][3] = '#';pels->els[2][2] = '#';pels->els[2][3] = '#';}}else if (no >= 10 && no <= 13) {pels->no = no;pels->nextno = (no == 13) ? 10 : no + 1;if (no == 10){pels->els[0][2] = '#';pels->els[0][3] = '#';pels->els[1][0] = '#';pels->els[1][1] = '#';pels->els[1][2] = '#';pels->els[1][3] = '#';pels->els[1][4] = '#';pels->els[1][5] = '#';}else if (no == 11){pels->els[0][0] = '#';pels->els[0][1] = '#';pels->els[1][0] = '#';pels->els[1][1] = '#';pels->els[1][2] = '#';pels->els[1][3] = '#';pels->els[2][0] = '#';pels->els[2][1] = '#';}else if (no == 12){pels->els[0][0] = '#';pels->els[0][1] = '#';pels->els[0][2] = '#';pels->els[0][3] = '#';pels->els[0][4] = '#';pels->els[0][5] = '#';pels->els[1][2] = '#';pels->els[1][3] = '#';}else {pels->els[0][2] = '#';pels->els[0][3] = '#';pels->els[1][0] = '#';pels->els[1][1] = '#';pels->els[1][2] = '#';pels->els[1][3] = '#';pels->els[2][2] = '#';pels->els[2][3] = '#';}}else if (no == 14 || no == 15) {pels->no = no;pels->nextno = no; for (j = 0; j < 2; j++) {for (i = 0; i < 4; i++) {pels->els[j][i] = '#';}}}else if (no >= 16 && no <= 19) {pels->no = no;pels->nextno = (no == 19) ? 16 : no + 1;if (no == 16) {pels->els[0][2] = '#';pels->els[0][3] = '#';pels->els[1][2] = '#';pels->els[1][3] = '#';pels->els[2][0] = '#';pels->els[2][1] = '#';pels->els[2][2] = '#';pels->els[2][3] = '#';}else if (no == 17) {pels->els[0][0] = '#';pels->els[0][1] = '#';pels->els[1][0] = '#';pels->els[1][1] = '#';pels->els[1][2] = '#';pels->els[1][3] = '#';pels->els[1][4] = '#';pels->els[1][5] = '#';}else if (no == 18) {pels->els[0][0] = '#';pels->els[0][1] = '#';pels->els[0][2] = '#';pels->els[0][3] = '#';pels->els[1][0] = '#';pels->els[1][1] = '#';pels->els[2][0] = '#';pels->els[2][1] = '#';}else { pels->els[0][0] = '#';pels->els[0][1] = '#';pels->els[0][2] = '#';pels->els[0][3] = '#';pels->els[0][4] = '#';pels->els[0][5] = '#';pels->els[1][4] = '#';pels->els[1][5] = '#';}return;
}
void movebox(struct els* pels, int y, int x)
{int j = 0;int i = 0;for (j = 0; j < ELS_HEIGHT; j++){for (i = 0; i < ELS_WIDTH; i++){if ('#' == pels->els[j][i]){frame[y + j][x + i] = pels->els[j][i];}}}return;
}
int can_movebox(struct els* pels, int y, int x)
{int j = 0;int i = 0;for (j = 0; j < ELS_HEIGHT; j++){for (i = 0; i < ELS_WIDTH; i++){if ('#' == pels->els[j][i] && frame[y + j][x + i] != ' '){return 0;}}}return 1;
}
void clear_movebox(struct els* pels, int y, int x)
{int j = 0;int i = 0;for (j = 0; j < ELS_HEIGHT; j++){for (i = 0; i < ELS_WIDTH; i++)if ('#' == pels->els[j][i] && frame[y + j][x + i] == '#'){frame[y + j][x + i] = ' ';}}return;
}void init_frame(void)
{int j = 0;int i = 0;memset(frame, ' ', sizeof(frame));for (i = 0; i < FRAME_WIDTH; i++){frame[0][i] = '*';frame[FRAME_HEIGHT - 1][i] = '*';}for (j = 0; j < FRAME_HEIGHT; j++){frame[j][0] = '*';frame[j][1] = '*';frame[j][FRAME_WIDTH - 2] = '*';frame[j][FRAME_WIDTH - 1] = '*';}for (j = 0; j < FRAME_HEIGHT; j++){frame[j][FRAME_WIDTH - FRAME_WIDTH / 3 - 2] = '*';}for (i = FRAME_WIDTH / 3 * 2; i < FRAME_WIDTH; i++){frame[FRAME_HEIGHT / 2][i] = '*';}return;
}void show_frame(void)
{int j = 0;int i = 0;printf("\033[2J");for (j = 0; j < FRAME_HEIGHT; j++){printf("\033[%d;%dH", FRAME_STARTPOS_Y + j, FRAME_STARTPOS_X);for (i = 0; i < FRAME_WIDTH; i++){if ('*' == frame[j][i]){printf("\033[31;41m");printf("%c", frame[j][i]);printf("\033[0m");}else if ('#' == frame[j][i]){printf("\033[32;42m");printf("%c", frame[j][i]);printf("\033[0m");}else{printf("%c", frame[j][i]);}}printf("\n");}printf("\033[%d;%dH", FRAME_STARTPOS_Y + (FRAME_HEIGHT / 4 * 3) - 3, FRAME_STARTPOS_X + (FRAME_WIDTH / 4 * 3) - 5);printf("\033[1;33;5m别笑,你试你也到不了\033[0m\n");printf("\033[%d;%dH", FRAME_STARTPOS_Y + (FRAME_HEIGHT / 4 * 3) - 2, FRAME_STARTPOS_X + (FRAME_WIDTH / 4 * 3) + 2);printf("\033[1;33;5m第二关\033[0m\n");printf("\033[%d;%dH", FRAME_STARTPOS_Y + (FRAME_HEIGHT / 4 * 3) - 1, FRAME_STARTPOS_X + (FRAME_WIDTH / 4 * 3) - 2);printf("\033[1;33m当前得分:%010d\033[0m\n", score);printf("\033[%d;%dH", FRAME_STARTPOS_Y + (FRAME_HEIGHT / 4 * 3), FRAME_STARTPOS_X + (FRAME_WIDTH / 4 * 3) - 2);printf("\033[1;33mw 旋转\033[0m\n");printf("\033[%d;%dH", FRAME_STARTPOS_Y + (FRAME_HEIGHT / 4 * 3) + 1, FRAME_STARTPOS_X + (FRAME_WIDTH / 4 * 3) - 2);printf("\033[1;33ma 左移\033[0m\n");printf("\033[%d;%dH", FRAME_STARTPOS_Y + (FRAME_HEIGHT / 4 * 3) + 2, FRAME_STARTPOS_X + (FRAME_WIDTH / 4 * 3) - 2);printf("\033[1;33md 右移\033[0m\n");printf("\033[%d;%dH", FRAME_STARTPOS_Y + (FRAME_HEIGHT / 4 * 3) + 3, FRAME_STARTPOS_X + (FRAME_WIDTH / 4 * 3) - 2);printf("\033[1;33ms 下移\033[0m\n");printf("\033[%d;%dH", FRAME_STARTPOS_Y + (FRAME_HEIGHT / 4 * 3) + 4, FRAME_STARTPOS_X + (FRAME_WIDTH / 4 * 3) - 2);printf("\033[1;33mp 暂停/取消暂停\033[0m\n");return;
}void clear_line(int n)
{int i = 0;int j = 0;for (j = n; j > 1; j--){for (i = 2; i < FRAME_WIDTH / 3 * 2; i++){frame[j][i] = frame[j - 1][i];}}for (i = 2; i < FRAME_WIDTH / 3 * 2; i++){frame[1][i] = ' ';}score += 10;return;
}void check_line(void)
{int j = 0;int i = 0;int canclear = 1;for (j = 0; j < 4 && cury + j < FRAME_HEIGHT - 1; j++){canclear = 1;for (i = 2; i < FRAME_WIDTH / 3 * 2; i++){if (' ' == frame[j + cury][i]){canclear = 0;}}if (canclear){clear_line(j + cury);}}return;
}
主函数
#include <stdio.h>
#include "els.h"
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>int curx;
int cury;
int gamestat; void handler(int signo)
{clear_movebox(&curbox, cury, curx);if (can_movebox(&curbox, cury + 1, curx)){movebox(&curbox, cury + 1, curx);cury += 1;}else{movebox(&curbox, cury, curx);check_line();if (score >= 0) {exit(0);}curbox = nextbox;clear_movebox(&nextbox, NEXT_BOX_POS_Y, NEXT_BOX_POS_X);memset(&nextbox, 0, sizeof(nextbox));create_box(&nextbox, rand() % 20);movebox(&nextbox, NEXT_BOX_POS_Y, NEXT_BOX_POS_X);if (can_movebox(&curbox, ELS_START_POS_Y, ELS_START_POS_X)){movebox(&curbox, ELS_START_POS_Y, ELS_START_POS_X);cury = ELS_START_POS_Y;curx = ELS_START_POS_X;}else{system("stty echo icanon");exit(0);}}show_frame();alarm(1);return;
}int main(void)
{char ch = 0;struct els tmpbox;curx = ELS_START_POS_X;cury = ELS_START_POS_Y;system("stty -echo");system("stty -icanon");gamestat = GAME_STAT_RUNNING;signal(SIGALRM, handler);alarm(1);init_frame();srand(time(NULL));create_box(&curbox, rand() % 20);movebox(&curbox, cury, curx);create_box(&nextbox, rand() % 20);movebox(&nextbox, NEXT_BOX_POS_Y, NEXT_BOX_POS_X);show_frame();while (1){ch = getchar();if ('A' == ch || 'a' == ch){clear_movebox(&curbox, cury, curx);if (can_movebox(&curbox, cury, curx - 2)){movebox(&curbox, cury, curx - 2);curx -= 2;}else{movebox(&curbox, cury, curx);}show_frame();}else if ('D' == ch || 'd' == ch){clear_movebox(&curbox, cury, curx);if (can_movebox(&curbox, cury, curx + 2)){movebox(&curbox, cury, curx + 2);curx += 2;}else{movebox(&curbox, cury, curx);}show_frame();}else if ('S' == ch || 's' == ch){clear_movebox(&curbox, cury, curx);if (can_movebox(&curbox, cury + 1, curx)){movebox(&curbox, cury + 1, curx);cury += 1;}else{movebox(&curbox, cury, curx);}show_frame();}else if ('w' == ch || 'W' == ch){clear_movebox(&curbox, cury, curx);memset(&tmpbox, 0, sizeof(tmpbox));create_box(&tmpbox, curbox.nextno);if (can_movebox(&tmpbox, cury, curx)){movebox(&tmpbox, cury, curx);curbox = tmpbox;}else{movebox(&curbox, cury, curx);}show_frame();}else if ('p' == ch || 'P' == ch){if (gamestat == GAME_STAT_RUNNING){alarm(0);printf("\033[%d;%dH", FRAME_STARTPOS_Y + (FRAME_HEIGHT / 2), FRAME_STARTPOS_X + (FRAME_WIDTH / 4 * 1));printf("\033[1;33m暂停中\033[0m\n");gamestat = GAME_STAT_PAUSE;}else if (gamestat == GAME_STAT_PAUSE){alarm(1);gamestat = GAME_STAT_RUNNING;}}}return 0;
}