c语言写俄罗斯方块(源码)
?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#define ? ROW ? ?19 ? ? // 游戲區域的行數
#define ? COL ? ?12 ? ? // 游戲區域的列數
#define ? ?NR ? ?4 ?// 方塊數據大小
#define ? ?TYPE ?7 ?// 方塊類型數
/* 按鍵枚舉 */
enum key {
? ?DOWN, ? ??? ??? ??? ?// 上
? ?LEFT, ? ??? ??? ??? ?// 左
? ?RIGHT, ? ?? ??? ??? ?// 右
? ?CHANGE, ??? ??? ??? ?// 變化
? ?STOP, ? ??? ??? ??? ?// 停止
? ?EXIT, ? ??? ??? ??? ?// 退出
? ?UNKNOW, ??? ??? ??? ?// 未知
};
/***** 函數聲明區域 ******/
void initalGameArea(void); ? ? ? ? ? ? ? ? ?// 初始化游戲區域
void drawBlock(char bl[NR][NR]); ? ? ? ? ? ?// 畫方塊
void cleanBlock(char bl[NR][NR]); ? ? ? ? ? // 清除方塊
void turnBlock(char bl[NR][NR]); ? ? ? ? ? ?// 旋轉方塊
void gameEnd(void); ? ? ? ? ? ? ? ? ? ? ? ? // 結束游戲
void gameStop(void); ? ? ? ? ? ? ? ? ? ? ? ?// 暫停游戲
void showGame(void); ? ? ? ? ? ? ? ? ? ? ? ?// 顯示游戲
void gameSelf(int signo); ? ? ? ? ? ? ? ? ? // 游戲自動運行
void checkDeleteLine(void); ? ? ? ? ? ? ? ? // 檢查是否滿一行
void checkGameOver(char bl[NR][NR]); ? ? ? ?// 檢查是否游戲結束
int ?checkMove(char bl[NR][NR], int flag); ?// 檢查方塊是否可移動
void ?setBufferedInput(bool enable); ? ? ? ? ? ? ? ? ? ? ? ?// 獲取輸入
/* 全局變量區域 */
static char gameArea[ROW][COL] = {0}; ? ?? ?// 游戲區域數據
static int startX = 4, startY = 6; ? ? ??? ?// 方塊出現的起始位置
static int type = 0; ? ? ? ? ? ? ? ? ? ??? ?// 方塊當前類型
static int nextType = 0; ? ? ? ? ? ? ? ??? ?// 方塊的下一種類型
static int diret = 0; ? ? ? ? ? ? ? ? ? ?? ?// 方塊的方向
char *state = "\033[32m游戲中...\033[0m";?? ?// 游戲運行狀態
static unsigned int level = 0; ? ? ? ? ??? ?// 游戲等級
static unsigned int score = 0; ? ? ? ? ??? ?// 游戲分數
static unsigned int maxScore = 0; ? ? ? ?? ?// 游戲最高記錄
static FILE *fp = NULL; ? ? ? ? ? ? ? ? ?? ?// 用于把記錄保存到文件
/* 方塊數據 */
char bl[TYPE][NR][NR][NR] = {
? ? /* 第一種方塊 */
?{
? ?? ?{ /* 第一種方向 */
? ?? ? {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},
? ?? ?},
?},
?/* 第二種方塊 */
?{
? ?? ?{ /* 第一種方向 */
? ?? ? {2,2,2,2},
? ?? ? {0,0,0,0},
? ?? ? {0,0,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第二種方向 */
? ?? ? {0,2,0,0},
? ?? ? {0,2,0,0},
? ?? ? {0,2,0,0},
? ?? ? {0,2,0,0},
? ?? ?},
? ?? ?{ /* 第三種方向 */
? ?? ? {2,2,2,2},
? ?? ? {0,0,0,0},
? ?? ? {0,0,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第四種方向 */
? ?? ? {0,2,0,0},
? ?? ? {0,2,0,0},
? ?? ? {0,2,0,0},
? ?? ? {0,2,0,0},
? ?? ?},
?},
?/* 第三種方塊 */
?{
? ?? ?{ /* 第一種方向 */
? ?? ? {3,0,0,0},
? ?? ? {3,3,3,0},
? ?? ? {0,0,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第二種方向 */
? ?? ? {0,3,3,0},
? ?? ? {0,3,0,0},
? ?? ? {0,3,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第三種方向 */
? ?? ? {3,3,3,0},
? ?? ? {0,0,3,0},
? ?? ? {0,0,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第四種方向 */
? ?? ? {0,0,3,0},
? ?? ? {0,0,3,0},
? ?? ? {0,3,3,0},
? ?? ? {0,0,0,0},
? ?? ?},
?},
?/* 第四種方塊 */
?{
? ?? ?{ /* 第一種方向 */
? ?? ? {0,0,4,0},
? ?? ? {4,4,4,0},
? ?? ? {0,0,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第二種方向 */
? ?? ? {0,4,0,0},
? ?? ? {0,4,0,0},
? ?? ? {0,4,4,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第三種方向 */
? ?? ? {0,4,4,4},
? ?? ? {0,4,0,0},
? ?? ? {0,0,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第四種方向 */
? ?? ? {0,4,4,0},
? ?? ? {0,0,4,0},
? ?? ? {0,0,4,0},
? ?? ? {0,0,0,0},
? ?? ?},
?},
?/* 第五種方塊 */
?{
? ?? ?{ /* 第一種方向 */
? ?? ? {0,5,0,0},
? ?? ? {5,5,5,0},
? ?? ? {0,0,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第二種方向 */
? ?? ? {0,5,0,0},
? ?? ? {0,5,5,0},
? ?? ? {0,5,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第三種方向 */
? ?? ? {5,5,5,0},
? ?? ? {0,5,0,0},
? ?? ? {0,0,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第四種方向 */
? ?? ? {0,5,0,0},
? ?? ? {5,5,0,0},
? ?? ? {0,5,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
?},
?/* 第六種方塊 */
?{
? ?? ?{ /* 第一種方向 */
? ?? ? {6,6,0,0},
? ?? ? {0,6,6,0},
? ?? ? {0,0,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第二種方向 */
? ?? ? {0,0,6,0},
? ?? ? {0,6,6,0},
? ?? ? {0,6,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第三種方向 */
? ?? ? {6,6,0,0},
? ?? ? {0,6,6,0},
? ?? ? {0,0,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第四種方向 */
? ?? ? {0,0,6,0},
? ?? ? {0,6,6,0},
? ?? ? {0,6,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
?},
?/* 第七種方塊 */
?{
? ?? ?{ /* 第一種方向 */
? ?? ? {0,7,7,0},
? ?? ? {7,7,0,0},
? ?? ? {0,0,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第二種方向 */
? ?? ? {0,7,0,0},
? ?? ? {0,7,7,0},
? ?? ? {0,0,7,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第三種方向 */
? ?? ? {0,0,7,7},
? ?? ? {0,7,7,0},
? ?? ? {0,0,0,0},
? ?? ? {0,0,0,0},
? ?? ?},
? ?? ?{ /* 第四種方向 */
? ?? ? {0,7,0,0},
? ?? ? {0,7,7,0},
? ?? ? {0,0,7,0},
? ?? ? {0,0,0,0},
? ?? ?},
? },
};
/*
?* 主函數:控制全局流程
*/
int main(void)
{
? ? /*
? ? ?* 設置鬧鐘:
? ? ?* 當前時間間隔為0.7秒,下一次時間間隔為0.7秒
? ? */
? ? struct itimerval ?timer = {{0,700000},{0,700000}};
? ? setitimer(ITIMER_REAL, &timer,NULL);
? ? /* 初始化游戲區域 */
? ? initalGameArea();
? ? /* 設置游戲信號 */
? ? signal(SIGALRM, gameSelf);
? ? /* 初始化方塊類型 */
? ? srand(time(NULL));
? ? type ? ? = rand()%7;
? ? nextType = rand()%7;
? ? /* 讀取文件的最高記錄 */
? ? fp = fopen("./record","r+");
? ? if (NULL == fp)
? ? {
? ? ? ? /*
? ? ? ? ?* 文件不存在則創建并打開?
? ? ? ? ?* "w"方式打開會自動創建不存在的文
? ? ? ? ?*/
? ? ? ? fp = fopen("./record","w");
? ? }
? ? fscanf(fp,"%u",&maxScore);
? ? /* 用戶操作 */
?? ?char c;
? ? int key;
?? ?setBufferedInput(false);
? ? while (1)
? ? {
? ? ? ? c=getchar();
?? ??? ?switch(c) {
?? ??? ??? ?case 97:?? ?// 'a' key
?? ??? ??? ?case 104:?? ?// 'h' key
?? ??? ??? ?case 68:?? ?// left arrow
?? ??? ??? ?case 52:?? ?// 4 arrow
?? ??? ??? ??? ?key = LEFT; ?break;
?? ??? ??? ?case 100:?? ?// 'd' key
?? ??? ??? ?case 108:?? ?// 'l' key
?? ??? ??? ?case 67:?? ?// right arrow
?? ??? ??? ?case 54:?? ?// 6 arrow
?? ??? ??? ??? ?key = RIGHT; break;
?? ??? ??? ?case 119:?? ?// 'w' key
?? ??? ??? ?case 107:?? ?// 'k' key
?? ??? ??? ?case 65:?? ?// up arrow
?? ??? ??? ?case 50:?? ?// 2 arrow
?? ??? ??? ??? ?key = CHANGE; ? ?break;
?? ??? ??? ?case 115:?? ?// 's' key
?? ??? ??? ?case 106:?? ?// 'j' key
?? ??? ??? ?case 66:?? ?// down arrow
?? ??? ??? ?case 56:?? ?// 8 arrow
?? ??? ??? ??? ?key = DOWN; ?break;
?? ??? ??? ?case 32:?? ?//space
?? ??? ??? ??? ?key=STOP;break;
?? ??? ??? ?default: key = UNKNOW;
?? ??? ?}
?? ??? ?
? ? ? ? switch (key)
? ? ?? ?{
? ? ?? ? ? ?case RIGHT : checkMove(bl[type][diret],RIGHT);
? ? ?? ? ? ? ? ? ? ? ? ? break;
? ? ?? ? ? ?case LEFT ?: checkMove(bl[type][diret],LEFT);
? ? ?? ? ? ? ? ? ? ? ? ? break;
? ? ?? ? ? ?case DOWN ?: checkMove(bl[type][diret],DOWN);
? ? ?? ? ? ? ? ? ? ? ? ? break;
? ? ?? ? ? ?case CHANGE: turnBlock(bl[type][(diret+1)%4]);
? ? ?? ? ? ? ? ? ? ? ? ? break;
? ? ?? ? ? ?case STOP ?: gameStop();
? ? ?? ? ? ? ? ? ? ? ? ? break;
? ? ?? ? ? ?case EXIT ?: gameEnd();
? ? ?? ? ? ? ? ? ? ? ? ? break;
? ? ?? ? ? ?case UNKNOW: continue;
? ? ?? ?}
? ? ? ? /* 畫方塊 */
? ? ? ? drawBlock(bl[type][diret]);
? ? ? ? /* 顯示游戲 */
? ? ? ? showGame();
? ? ? ? /* 清除方塊 */
? ? ? ? cleanBlock(bl[type][diret]);
? ? }
? ? return 0;
}
void setBufferedInput(bool enable) {
?? ?static bool enabled = true;
?? ?static struct termios old;
?? ?struct termios new;
?? ?if (enable && !enabled) {
?? ??? ?// restore the former settings
?? ??? ?tcsetattr(STDIN_FILENO,TCSANOW,&old);
?? ??? ?// set the new state
?? ??? ?enabled = true;
?? ?} else if (!enable && enabled) {
?? ??? ?// get the terminal settings for standard input
?? ??? ?tcgetattr(STDIN_FILENO,&new);
?? ??? ?// we want to keep the old setting to restore them at the end
?? ??? ?old = new;
?? ??? ?// disable canonical mode (buffered i/o) and local echo
?? ??? ?new.c_lflag &=(~ICANON & ~ECHO);
?? ??? ?// set the new settings immediately
?? ??? ?tcsetattr(STDIN_FILENO,TCSANOW,&new);
?? ??? ?// set the new state
?? ??? ?enabled = false;
?? ?}
}
/*
?* 函數名:initalGameArea
?* 函數功能:初始化游戲區域
?* 參數:無
?* 返回值:無
*/
void initalGameArea(void)
{
? ? int i;
?? ?/* 屏幕設置 */
?? ?printf("\033[2J");?? ??? ??? ? ?// 清屏
? ? system("stty -icanon");?? ??? ? ?// 關緩沖
? ? system("stty -echo");?? ??? ? ?// 關回顯
? ? fprintf(stdout,"\033[?25l"); ?// 關閉鼠標顯示
? ? /* 初始化行 */
? ? for (i = 0; i < COL; i++)
? ? {
? ? ? ? gameArea[0][i] ? ? = 8; ? // 第0行
? ? ? ? gameArea[5][i] ? ? = 8; ? // 第5行
? ? ? ? gameArea[ROW-1][i] = 8; ? // 最后一行
? ? }
? ? /* 初始化列 */
? ? for (i = 0; i < ROW; i++)
? ? {
? ? ? ? gameArea[i][0] ? ? = 8; ?// 第0列
? ? ? ? gameArea[i][COL-1] = 8; ?// 最后一列
? ? }
? ? /* 中間一小列 */
? ? for (i = 1; i < 5; i++)
? ? {
? ? ? ? gameArea[i][6] = 8;
? ? }
}
/*
?* 函數名:gameSelf
?* 函數功能:作為信號函數,鬧鐘時間一到就自動下落
?* 參數:信號
?* 返回值:無
*/
void gameSelf(int signo)
{
? ? /* 畫方塊 */
? ? drawBlock(bl[type][diret]);
? ? /* 顯示游戲 */
? ? showGame();
? ? /* 清除方塊 */
? ? cleanBlock(bl[type][diret]);
? ? /* 如果方塊已經到底 */
? ? if (!checkMove(bl[type][diret],DOWN))
? ? {
? ? ?? ?/* 檢查是否游戲結束 */
? ? ?? ?checkGameOver(bl[type][diret]);
? ? ?? ?/* 保留已經到底的方塊 */
? ? ?? ?drawBlock(bl[type][diret]);
? ? ?? ?/* 顯示游戲結果 */
? ? ?? ?showGame();
? ? ?? ?/* 到達邊界后檢查是否可消行 */
? ? ?? ?checkDeleteLine();
? ? ?? ?/* 重新開始下一個方塊 */
? ? ?? ?startY = 6;
? ? ?? ?startX = 4;
? ? ?? ?type = nextType;
? ? ?? ?nextType = rand()%7;
? ? ?? ?diret = 0;
? ? }
}
/*
?* 函數名:checkDeleteLine
?* 函數功能:檢查是否可消行
?* 參數:無
?* 返回值:無
*/
void checkDeleteLine(void)
{
? ? int i, j;
? ? int x, y;
? ? /* 檢查當前方塊的四行區域內 */
? ? for (i = 3; i >= 0; i--)
? ? {
? ? ? ? for (j = 1; j < COL-1; j++)
? ? ?? ?{
? ? ?? ? ? ?/* 檢測方塊是否滿一行 */
? ? ?? ? ? ?if (gameArea[startY+i][j] == 0)
? ? ?? ? ? ? ? ?break;
? ? ?? ? ? ?/* 跳過邊框區域 */
? ? ?? ? ? ?else if (gameArea[startY+i][j] == 8)
? ? ?? ? ? ? ? ?break;
? ? ?? ?}
? ? ?? ?/* 如果滿了一行則刪除一行 */
? ? ?? ?if (j == COL-1)
? ? ?? ?{
? ? ?? ? ? ?/* 刪除滿了的一行 */
? ? ?? ? ? ?for (j = 1; j < COL-1; j++)
? ? ?? ? ? ?{
? ? ?? ? ? ? ? ?gameArea[startY+i][j] = 0;
? ? ?? ? ? ?}
? ? ?? ? ? ?/* 分數累加 */
? ? ?? ? ? ?score += 100;
? ? ?? ? ? ?/* 記錄最高分 */
? ? ?? ? ? ?if (score > maxScore)
? ? ?? ? ? ?{
? ? ?? ? ? ? ? ?maxScore = score;
? ? ?? ??? ? ? ?/* 保存最高分 */
? ? ? ? ? ? ? ? rewind(fp);
? ? ?? ??? ? ? ?fprintf(fp,"%u\n",maxScore);
? ? ?? ? ? ?}
? ? ?? ? ? ?/* 記錄級別 */
? ? ?? ? ? ?if (score%200 == 0)
? ? ?? ? ? ?{
? ? ?? ??? ? ? ?/* 每200分加一級 */
? ? ?? ? ? ? ? ?level++;
? ? ?? ? ? ?}
? ? ?? ? ? ?/* 刪除后往下移動一行 */
? ? ?? ? ? ?for (x = 1; x < COL-1; x++)
? ? ?? ? ? ?{
? ? ?? ? ? ? ? ?for (y = startY+i; y >= 7; y--)
? ? ? ? ?? ??? ?{
? ? ? ? ?? ??? ? ? ?gameArea[y][x] = gameArea[y-1][x];
? ? ? ? ?? ??? ?}
? ? ?? ? ? ?}
? ? ?? ? ? ?/* 移動的一行需要檢測范圍加一行 */
? ? ?? ? ? ?i++;
? ? ?? ?}
? ? }
}
/*
?* 函數名:checkGameOver
?* 函數功能:檢查游戲是否結束
?* 參數:待檢查方塊數據數據
?* 返回值:無
*/
void checkGameOver(char block[NR][NR])
{
? ? int i;
? ? for (i = 0; i < NR; i++)
? ? {
? ? ? ? /* 方塊碰到上方邊界則游戲結束 */
? ? ? ? if (block[0][i] != 0 && gameArea[startY-1][startX+i] == 8)
? ? ?? ?{
? ? ?? ? ? ?gameEnd();
? ? ?? ?}
? ? }
}
/*
?* 函數名:turnBlock
?* 函數功能:旋轉方塊
?* 參數:需要旋轉的方塊數組數據
?* 返回值:無
*/
void turnBlock(char bl[NR][NR])
{
? ? int x, y;
? ? /* 檢查是否越界 */
? ? for (y = 0; y < NR; y++)
? ? {
? ? ? ? for (x = 0; x < NR; x++)
? ? ?? ?{
? ? ?? ? ? ?/* 只能判斷到達了邊界 */
? ? ?? ? ? ?if (bl[y][x] != 0 && gameArea[startY+y][startX+x] != 0)
? ? ?? ? ? ?{
? ? ?? ? ? ? ? ?return;
? ? ?? ? ? ?}
? ? ?? ?}
? ? }
? ? /* 兩邊都沒有越界則旋轉方塊方向 */
? ? diret = (diret+1)%4;
}
/*
?* 函數名:gameStop
?* 函數功能:暫停游戲,等待用戶再次啟動游戲
?* 參數:無
?* 返回值:無
*/
void gameStop(void)
{
? ? /* 創建一個暫停的是時鐘 */
? ? struct itimerval stop = {0}, older;
? ? /* 設置新鬧鐘并存儲舊鬧鐘 */
? ? setitimer(ITIMER_REAL,&stop,&older);
? ? /* 配置暫停后的界面 */
? ? state = "\033[31m暫停中...\033[0m";
? ? startY--; ? ? ? ? ? ? // 為了防止按下暫停鍵后方塊下滑一格
? ? drawBlock(bl[type][diret]);
? ? showGame();
? ? cleanBlock(bl[type][diret]);
? ? /* 等待用戶按開始鍵或退出鍵 */
? ? int key;
? ? while (1)
? ? {
? ? ? ? key =getchar();;
? ? ?? ?/* 空格開始 */
? ? ?? ?if (key == ' ')
? ? ?? ? ? ?break;
? ? ?? ?/* q 退出 */
? ? ?? ?else if (key == 'q')
? ? ?? ? ? ?gameEnd();
? ? }
? ? /* 恢復鬧鐘和游戲 */
? ? setitimer(ITIMER_REAL,&older,NULL);
? ? state = "\033[32m游戲中...\033[0m";
}
/*
?* 函數名:checkMove
?* 函數功能:檢查方塊是否可移動,能移則移
?* 參數:1.方塊數組數據 2.方向標志位
?* 返回值:可移動返回1,不能移動返回0
*/
int checkMove(char bl[NR][NR], int flag)
{
? ? int m, n; ? // 用于標明可移動方向
? ? int x, y; ? // 用于循環
? ? switch (flag)
? ? {
? ? ? ? case RIGHT : n = 0; m = 1; ?break;
? ? ?? ?case LEFT ?: n = 0; m = -1; break;
? ? ?? ?case DOWN ?: n = 1; m = 0; ?break;
? ? }
? ? /* 全局檢查 */
? ? for (y = 0; y < NR; y++)
? ? {
? ? ? ? for (x = 0; x < NR; x++)
? ? ?? ?{
? ? ?? ? ? ?/* 只能判斷到達了邊界 */
? ? ?? ? ? ?if (bl[y][x] != 0 && gameArea[startY+y+n][startX+x+m] != 0)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return 0;
? ? ? ? ? ? }
? ? ?? ?}
? ? }
? ? /* 出來說明沒有到達邊界 */
? ? startY += n;
? ? startX += m;
? ? return 1;
}
/*
?* 函數名:drawBlock
?* 函數功能:填充方塊數據
?* 參數:方塊數組數據
?* 返回值:無
*/
void drawBlock(char block[NR][NR])
{
? ? int x, y;
? ? /* 畫當前方塊 */
? ? for (y = 0; y < NR; y++)
? ? {
? ? ? ? for (x = 0; x < NR; x++)
? ? ?? ?{
? ? ?? ? ? ?if (block[y][x] != 0)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? gameArea[startY+y][startX+x] = block[y][x];
? ? ? ? ? ? }
? ? ?? ?}
? ? }
? ? /* 畫提示的下一個方塊 */
? ? for (x = 0; x < 2; x++)
? ? {
? ? ? ? for (y = 0; y < NR; y++)
? ? ?? ?{
? ? ?? ? ? ?if (bl[nextType][0][x][y] != 0)
? ? ?? ? ? ? ? ?gameArea[3+x][2+y] = bl[nextType][0][x][y];
? ? ? ? ? ? else
? ? ?? ? ? ? ? ?gameArea[3+x][2+y] = 0;
? ? ?? ?}
? ? }
}
/*
?* 函數名:cleanBlock
?* 函數功能:清除方塊數據
?* 參數:方塊數組數據
?* 返回值:無
*/
void cleanBlock(char bl[NR][NR])
{
? ? int x, y;
? ? for (y = 0; y < NR; y++)
? ? {
? ? ? ? for (x = 0; x < NR; x++)
? ? ?? ?{
? ? ?? ? ? ?if (bl[y][x] != 0)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? gameArea[startY+y][startX+x] = 0;
? ? ? ? ? ? }
? ? ?? ?}
? ? }
}
/*
?* 函數名:showGame
?* 函數功能:顯示游戲
?* 參數:無
?* 返回值:無
*/
void showGame(void)
{
? ? int i, j;
? ? /* 定位到第一行第一列 */
? ? fprintf(stdout,"\033[1;1H");
? ? fflush(stdout);
? ? /* 打印所有數據 */
? ? for (i = 0; i < ROW; i++)
? ? {
? ? ? ? for (j = 0; j < COL; j++)
? ? ?? ?{
? ? ? ? ? ? if (gameArea[i][j] == 0) ? ? ? // 空白區域
? ? ? ? ? ? {
? ? ? ? ? ? ? ? fprintf(stdout," ?");
? ? ? ? ? ? }
? ? ?? ? ? ?else if (gameArea[i][j] == 8) ?// 邊界區域
? ? ? ? ? ? {
? ? ? ? ? ? ? ? fprintf(stdout,"\033[43m ?\033[0m");
? ? ? ? ? ? }
? ? ? ? ? ? else ? ? ? ? ? ? ? ? ? ? ? ? ? // 方塊區域
? ? ? ? ? ? {
? ? ? ? ? ? ? ? fprintf(stdout,"\033[%dm[]\033[0m",gameArea[i][j]+40);
? ? ? ? ? ? }
? ? ?? ?}
?? ? ? ?fputc('\n',stdout);
? ? }
? ? /* 打印提示信息 */
? ? fprintf(stdout,"\033[2;3H\033[33m【下一個】\033[0m\n");
? ? fprintf(stdout,"\033[2;15H當前級別:\033[36m%u\033[0m\n",level);
? ? fprintf(stdout,"\033[3;15H當前分數:\033[32m%u\033[0m\n",score);
? ? fprintf(stdout,"\033[4;15H最高記錄:\033[35m%u\033[0m\n",maxScore);
? ? fprintf(stdout,"\033[5;15H當前狀態:%s\n",state);
?? ?
? ? fprintf(stdout,"\033[7;25H2鍵翻轉");
? ? fprintf(stdout,"\033[8;25H4,6,8 左右下");
? ? fprintf(stdout,"\033[9;25H空格鍵暫停");
}
/*
?* 函數名:gameEnd
?* 函數功能:處理游戲結束的設置
?* 參數:無
?* 返回值:無
*/
void gameEnd(void)
{
? ? /* 配置游戲結束后的界面 */
? ? state = "\033[31m游戲結束!!\033[0m";
? ? drawBlock(bl[type][diret]);
? ? showGame();
? ? /* 恢復終端設置 */
? ? system("stty icanon"); ? ? ? ? ?// 恢復緩沖
? ? system("stty echo"); ? ? ? ? ? ?// 恢復回顯
? ? fprintf(stdout,"\033[?25h"); ? ?// 恢復鼠標顯示
? ? /* 尾部處理 */
? ? fprintf(stdout,"\033[200;1H"); ?// 定位光標到最后一行
? ? fclose(fp); ? ? ? ? ? ? ? ? ? ? // 關閉文件
? ? exit(0); ? ? ? ? ? ? ? ? ? ? ? ?// 退出程序
}
?
總結
以上是生活随笔為你收集整理的c语言写俄罗斯方块(源码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: U-Boot源码目录分析(VScode工
- 下一篇: 自制Json解析工具(易语言)