用C語言完整實現2048遊戲
前言
遊戲規則:遊戲開始,在4×4的棋盤上隨機兩個方塊出現數字2,通過方向鍵控制所有方塊向同一個方向移動,兩個相同數字方塊撞在一起之後合並成為他們的和。每次移動,棋盤上還會在一個隨機位置增加一個數字2或者數字4,當最終得到一個“2048”的方塊就算勝利瞭。
簡單吧?簡單……個鬼啊,我以前玩瞭幾個小時都失敗瞭最後放棄瞭。
一、遊戲思路
1、程序開始時出現菜單,讓玩傢選擇開始遊戲或者退出遊戲。
2、玩傢選擇開始遊戲後,出現棋盤,通過方向鍵選擇移動的方向。
3、移動後會將所有方塊向該方向移動直至補全空格,同樣數字的方塊合並成它們的和,還會生成一個隨機位置的2或4。
4、當出現“2048”時,遊戲勝利;當棋盤滿且無法消除時,遊戲失敗。
二、遊戲框架
1.菜單界面
菜單
void menu() { printf("**************************\n"); printf("*****按 1 開 始 遊 戲*****\n"); printf("*****按 0 退 出 遊 戲*****\n"); printf("**************************\n"); }
菜單的選擇
int main() { int input = 0; do { menu(); printf("請選擇:"); scanf("%d", &input); switch (input) { case 1: game2048(); break; case 0: printf("退出遊戲,客官常來玩呀~)\n"); break; default: printf("給你一次重新選擇的機會\n"); break; } } while (input); return 0; }
實際效果
菜單我覺得還是挺順眼的,就是有點醜,畢竟是初學者就不要要求太高瞭。
2.遊戲主體
1.初始化界面:
生成一個4行4列的數組(此處的行數和列數已在頭文件中用#define宏定義)。
並且打印出來。
void DisplayBoard(int board[ROW][COL],int row, int col) { int i = 0; int j = 0; for (int j = 0; j < COL; j++) printf("+-----"); printf("+\n"); for (int i = 0; i < ROW; i++) { for (int j= 0; j < COL; j++) { printf("|"); if (board[i][j]!=0) printf("%5d", board[i][j]); else printf(" "); } printf("|\n"); for (int j = 0; j < COL; j++) { printf("+-----"); } printf("+\n"); } }
效果如下:
方嗎?方就對瞭,方就是個好界面!
2.隨機生成初始數字
遊戲的界面我們現在已經有瞭,接下來要做的就是加入兩個隨機位置的”2″。
void get_num(int board[ROW][COL]) { int x, y; x = rand() % ROW; y = rand() % COL; board[x][y] = 2;//一開始隨機的數為2 x = rand() % ROW; y = rand() % COL; while (board[x][y] == 2) { x = rand() % ROW; y = rand() % COL; } board[x][y] = 2; system("cls"); //清屏,美觀界面 return; }
(這裡照例還是使用瞭時間戳獲取隨機數的方法)
可以看到每一次出現的兩個位置都是隨機的。
3.實現移動
這裡我們以向上為例,我們要實現移動,以及判定兩個方塊數字相同就合並成為它們的和,並且當合並後存在空格時繼續向上移動。
簡單來說,就是 移動 → 合並 → 再次移動補空。其他三個方向也是一樣的道理,隻需要改變其中的數值便可實現。
void up(int board[ROW][COL]) { int i = 0; int j = 0; int x = 0; int y = 0; for (i = 0; i < ROW; i++) { //移動 j = 0; y = 0; while (j < COL-1 && y < COL-1 ) { if (board[j][i] == 0) { for (x = j; x < ROW-1; x++) board[x][i] = board[x + 1][i]; board[ROW-1][i] = 0; y++; } else j++; } //合並 for (j = 0; j < COL-1; j++) if (board[j][i] == board[j + 1][i] && board[j][i] != 0) { board[j][i] = board[j][i] * 2; //和 board[j + 1][i] = 0; } //再次移動補空 j = 0; y = 0; while (j < COL - 1 && y < COL - 1) { if (board[j][i] == 0) { for (x = j; x < ROW - 1; x++) board[x][i] = board[x + 1][i]; board[ROW - 1][i] = 0; y++; } else j++; } } }
4.增加新數字
每次移動會在隨機位置出現一個新的數字,可能是2,可能是4。
通過查詢網上資料得知,隨機到2的概率約為 9/10,隨機到4的概率約為 1/10。
void put_num(int board[ROW][COL]) { int x = 0; int y = 0; int z = 0; x = rand() % ROW; y = rand() % COL; while (board[x][y] !=0) { x = rand() % ROW; y = rand() % COL; } z = rand() % 10; if (z<9) board[x][y] = 2; else board[x][y] = 4; return; }
5.判定勝負
當出現2048時勝利,當格子滿瞭且無法消除時失敗。
int is_fail(int board[ROW][COL]) { int i = 0; int j = 0; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { if (board[i][j] == 0) return 0; if (i > 0) { if (board[i - 1][j] == board[i][j]) return 0; } if (j > 0) { if (board[i][j - 1] == board[i][j]) return 0; } } } return 1; } int is_win(int board[ROW][COL]) { int i = 0; int j = 0; int num = 0; for (i = 0; i < ROW; i++) for (j = 0; j < COL; j++) { if (board[i][j] > num) num = board[i][j]; } if (num >= 2048) return 1; else return 0; }
6.遊戲函數
將上述代碼結合起來
void game2048() { int board[ROW][COL] = { {0} }; int control = 0; DisplayBoard(board); init_num(board); system("cls"); //清屏,美觀界面 DisplayBoard(board); while ((control = _getch()) != 0x1b) { switch (control) { case 0xe0: switch (control = getch()) { case 72: up(board); break; case 80: down(board); break; case 75: left(board); break; case 77: right(board); break; default: break; } system("cls"); DisplayBoard(board); if (is_win(board) == 1) { printf("恭喜你贏瞭!"); } if (is_fail(board) == 1) { printf("哈哈哈哈哈哈哈好菜\n"); } } } }
三、遊戲運行
已知目前遊戲存在bug,當格子滿瞭的時候假定一個方向可以消除,另一個方向不可以消除,按瞭那個不可以消除的方向的話,就會無法操作瞭,鑒於本人目前初學者並未能夠想到很好的解決方法。若有大佬有好的方法也可指點一下。
我太菜瞭玩瞭好久都玩不到2048,最高隻有512,1024還是舍友打出來的。
更新:修復瞭bug
先判斷數組是否相同再選擇是否添加新的隨機位置的數字。
在此感謝各位幫助我測試的朋友,無論成功與否,當然特別感謝提供瞭這張圖片的朋友。
四、所有代碼
game2048.h
#pragma once #include <stdio.h> #include <time.h> #include <stdlib.h> #include <windows.h> #include<conio.h> #define ROW 4 #define COL 4 const int copy[ROW][COL]; //初始化並打印遊戲界面 void DisplayBoard(int board[ROW][COL]); //開局隨機生成兩個2 void init_num(int board[ROW][COL]); //在移動後隨機放置數字2或4 void put_num(int board[ROW][COL]); //移動 void up(int board[ROW][COL]); void down(int board[ROW][COL]); void left(int board[ROW][COL]); void right(int board[ROW][COL]); //判定勝負 int is_win(int board[ROW][COL]); int is_fail(int board[ROW][COL]);
game2048.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game2048.h" void DisplayBoard(int board[ROW][COL]) { int i = 0; int j = 0; printf("tip:*方向鍵控制方塊移動*ESC鍵返回菜單*\n"); for (int j = 0; j < COL; j++) printf("+-----"); printf("+\n"); for (int i = 0; i < ROW; i++) { for (int j= 0; j < COL; j++) { printf("|"); if (board[i][j]!=0) printf("%5d", board[i][j]); else printf(" "); } printf("|\n"); for (int j = 0; j < COL; j++) { printf("+-----"); } printf("+\n"); } } void init_num(int board[ROW][COL]) { int x, y; x = rand() % ROW; y = rand() % COL; board[x][y] = 2;//隨機在一個位置生成2 x = rand() % ROW; y = rand() % COL; while (board[x][y] == 2) { x = rand() % ROW; y = rand() % COL; } board[x][y] = 2; return; } void put_num(int board[ROW][COL]) { int x = 0; int y = 0; int z = 0; x = rand() % ROW; y = rand() % COL; while (board[x][y] !=0) { x = rand() % ROW; y = rand() % COL; } z = rand() % 10; if (z<9) board[x][y] = 2; else board[x][y] = 4; return; } void up(int board[ROW][COL]) { int i = 0; int j = 0; int x = 0; int y = 0; for (i = 0; i < ROW; i++) { //移動 j = 0; y = 0; while (j < COL-1 && y < COL-1 ) { if (board[j][i] == 0) { for (x = j; x < ROW-1; x++) board[x][i] = board[x + 1][i]; board[ROW-1][i] = 0; y++; } else j++; } //合並 for (j = 0; j < COL-1; j++) if (board[j][i] == board[j + 1][i] && board[j][i] != 0) { board[j][i] = board[j][i] * 2; board[j + 1][i] = 0; } //再次移動補空 j = 0; y = 0; while (j < COL - 1 && y < COL - 1) { if (board[j][i] == 0) { for (x = j; x < ROW - 1; x++) board[x][i] = board[x + 1][i]; board[ROW - 1][i] = 0; y++; } else j++; } } if (contrast(board) == 0) put_num(board); else return; } void down(int board[ROW][COL]) { int i = 0; int j = 0; int x = 0; int y = 0; for (i = 0; i < ROW; i++) { j = COL-1; y = 0; while (j > 0 && y < COL-1) { if (board[j][i] == 0) { for (x = j; x > 0; x--) board[x][i] = board[x - 1][i]; board[0][i] = 0; y++; } else j--; } for (j = COL-1; j > 0; j--) if (board[j][i] == board[j - 1][i] && board[j][i] != 0) { board[j][i] = board[j][i] * 2; board[j - 1][i] = 0; } j = COL - 1; y = 0; while (j > 0 && y < COL - 1) { if (board[j][i] == 0) { for (x = j; x > 0; x--) board[x][i] = board[x - 1][i]; board[0][i] = 0; y++; } else j--; } } if (contrast(board) == 0) put_num(board); else return; } void left(int board[ROW][COL]) { int i = 0; int j = 0; int x = 0; int y = 0; for (i = 0; i < ROW; i++) { j = 0; y = 0; while (j < 3 && y < 3 ) { if (board[i][j] == 0) { for (x = j; x < ROW-1; x++) board[i][x] = board[i][x + 1]; board[i][COL-1] = 0; y++; } else j++; } for (j = 0; j < 3; j++) if (board[i][j] == board[i][j + 1] && board[i][j] != 0) { board[i][j] = board[i][j] * 2; board[i][j + 1] = 0; } j = 0; y = 0; while (j < 3 && y < 3) { if (board[i][j] == 0) { for (x = j; x < ROW - 1; x++) board[i][x] = board[i][x + 1]; board[i][COL - 1] = 0; y++; } else j++; } } if (contrast(board) == 0) put_num(board); else return; } void right(int board[ROW][COL]) { int i = 0; int j = 0; int x = 0; int y = 0; for (i = 0; i < 4; i++) { j = COL-1; y = 0; while (j>0 && y < COL-1) { if (board[i][j] == 0) { for (x = j; x > 0; x--) board[i][x] = board[i][x - 1]; board[i][0] = 0; y++; } else j--; } for (j = 3; j > 0; j--) if (board[i][j] == board[i][j - 1] && board[i][j] != 0) { board[i][j] = board[i][j] * 2; board[i][j - 1] = 0; } j = COL - 1; y = 0; while (j > 0 && y < COL - 1) { if (board[i][j] == 0) { for (x = j; x > 0; x--) board[i][x] = board[i][x - 1]; board[i][0] = 0; y++; } else j--; } } if (contrast(board) == 0) put_num(board); else return; } int is_fail(int board[ROW][COL]) { int i = 0; int j = 0; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { if (board[i][j] == 0) return 0; if (i > 0) { if (board[i - 1][j] == board[i][j]) return 0; } if (j > 0) { if (board[i][j - 1] == board[i][j]) return 0; } } } return 1; } int is_win(int board[ROW][COL]) { int i = 0; int j = 0; int num = 0; for (i = 0; i < ROW; i++) for (j = 0; j < COL; j++) { if (board[i][j] > num) num = board[i][j]; } if (num >= 2048) return 1; else return 0; } void copyboard(int board[ROW][COL],int copy[ROW][COL]) { int i = 0; int j = 0; for (i = 0; i < ROW; i++) for (j = 0; j < COL; j++) copy[i][j] = board[i][j]; } int contrast(int board[ROW][COL]) { int i = 0; int j = 0; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) if (copy[i][j] != board[i][j]) return 0; return 1; }
test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game2048.h" void menu() { printf("**************************\n"); printf("*****按 1 開 始 遊 戲*****\n"); printf("*****按 0 退 出 遊 戲*****\n"); printf("**************************\n"); } void game2048() { int board[ROW][COL] = { {0} }; int control = 0; DisplayBoard(board); init_num(board); system("cls"); //清屏,美觀界面 DisplayBoard(board); while ((control = _getch()) != 0x1b) { switch (control) { case 0xe0: switch (control = getch()) { case 72: copyboard(board, copy); up(board); break; case 80: copyboard(board, copy); down(board); break; case 75: copyboard(board, copy); left(board); break; case 77: copyboard(board, copy); right(board); break; default: break; } system("cls"); DisplayBoard(board); if (is_win(board) == 1) { printf("恭喜你贏瞭!\n"); } if (is_fail(board) == 1) { printf("哈哈哈哈哈哈哈好菜\n"); } } } } int main() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("請選擇:"); scanf("%d", &input); switch (input) { case 1: game2048(); break; case 0: printf("退出遊戲,客官常來玩呀~)\n"); break; default: printf("給你一次重新選擇的機會\n"); break; } } while (input); return 0; }
總結
感謝各位幫我測試的朋友們!
很久以前看過一部小說,主人公的第一個C語言程序就是實現一個2048的小遊戲。
我不是生活中的主人公,但是我還是想要努力到能夠讓自己不再留下遺憾,努力到配得上自己喜歡的人。
三天時間,2048,願不忘初心。
到此這篇關於用C語言完整實現2048遊戲的文章就介紹到這瞭,更多相關C語言 2048遊戲內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!