C語言實現2048遊戲
阿新 • • 發佈:2018-12-17
文章目錄
2048遊戲在很長一段時間內是一款很火的小遊戲。 遊戲要求:- 最開始兩個隨機數
- 每次生成一個隨機數2或者4,生成4的概率是1/10
- 鍵盤上下左右鍵控制遊戲的走向
- 當出現2048數字時,玩家獲勝
列印介面
//列印 void GamePrint(int row, int col) { printf("SCORE = %d", score); SetCurPos(0, 2); int i = 0; for (i = 0; i < row; i++) { for (int k = 0; k < 4; k++) { printf(" "); for (int j = 0; j < 4; j++) { printf("-"); } } printf("\n"); for (int k = 0; k < 4; k++) { printf("|"); if (arr[i][k]) { printf("%4d", arr[i][k]); } else { for (int j = 0; j < 4; j++) { printf(" "); } } } printf("|\n"); if (i == row - 1) { for (int k = 0; k < 4; k++) { printf(" "); for (int j = 0; j < 4; j++) { printf("-"); } } printf("\n"); } } SetCurPos(0, 12); printf("上下左右表示方向\n"); }
生成隨機數
要求生成4的概率為1/10, 生成一個10以內的數字(或者將生成的數字對10取餘) 判斷其是否為4 如果是4就生成4, 如果不是4,就生成2
void RandNum(int row, int col) //生成隨機數
{
int x = 0;
int y = 0;
do
{
x = rand() % 4;
y = rand() % 4;
} while (arr[x][y]);
arr[x][y] = (rand() % 10 ? 2 : 4);
}
是否獲勝
int IfWin(int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (arr[i][j] == 2048) { return 1; //表示贏了 } if (arr[i][j] == 0) { return 0; //表示繼續遊戲 } } } return -1;//輸了 }
移動
移動這部分就是這個遊戲的核心。 以右移為例,我們把二維陣列抽象成一個4*4的方塊,值為0的是空方塊,其餘的是數字方塊。我們只抽取出來一行來做例項(其餘行就可以通過迴圈以同樣的方式來做)。一行就可以用一個一維陣列來表示b[j];運用兩個下標來遍歷這個以為陣列,k,j;j永遠在k的後面,k表示當前比較項,j表示下一個不為0的元素;可以分為以下三種情況: 移動: b[k] == 0;b[j]之前的全是空格子,就要讓b[j]移動到b[k]的位置處,然後K++,繼續向後走 合併: b[k] == b[j];就要讓b[k] = 2 * b[k] ;然後k++ 碰撞: b[k] != b[j];此時就要分兩種情況: k + 1 != j;表示兩者沒有靠在一起,b[k+1] = b[j]; b[j] = 0; k++; k + 1 == j;表示兩者原本就靠在一起,不用管
int j = 1;
int k = 0;
for (; j < 4; j++)
{
//找出k第一個不為0的塊,之後分為三種情況
if (b[j] > 0)
{
//移動
if (b[k] == 0)
{
b[k] = b[j];
b[j] = 0;
}
//合併
else if (b[k] == b[j])
{
b[k] = 2 * b[k];
b[j] = 0;
k = k + 1;
}
//碰撞
else
{
b[k + 1] = b[j];
if (j != k + 1)
{
b[j] = 0;
}
k = k + 1;
}
}
}
遊戲程式碼:
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <Windows.h>
#include <conio.h>
#define ROW 4
#define COL 4
//定義全域性變數的好處:在函式之間不用傳參
// 缺點:只能完成一次遊戲,要想繼續玩就必須將陣列重置為全0;
int arr[ROW][COL] = { 0 };
int score = 0;
//設定游標的控制代碼,通俗的說,就是設定游標的位置
void SetCurPos(int x, int y)
{
HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coord = { x, y };
SetConsoleCursorPosition(hStdOutput, coord);
}
//隱藏游標
void ViewInit(int width, int height)
{
HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO info;
GetConsoleCursorInfo(hStdOutput, &info);
info.bVisible = 0;
SetConsoleCursorInfo(hStdOutput, &info);
}
//列印
void GamePrint(int row, int col)
{
printf("SCORE = %d", score);
SetCurPos(0, 2);
int i = 0;
for (i = 0; i < row; i++)
{
for (int k = 0; k < 4; k++)
{
printf(" ");
for (int j = 0; j < 4; j++)
{
printf("-");
}
}
printf("\n");
for (int k = 0; k < 4; k++)
{
printf("|");
if (arr[i][k])
{
printf("%4d", arr[i][k]);
}
else
{
for (int j = 0; j < 4; j++)
{
printf(" ");
}
}
}
printf("|\n");
if (i == row - 1)
{
for (int k = 0; k < 4; k++)
{
printf(" ");
for (int j = 0; j < 4; j++)
{
printf("-");
}
}
printf("\n");
}
}
SetCurPos(0, 12);
printf("上下左右表示方向\n");
}
//生成隨機數
void RandNum(int row, int col) //生成隨機數
{
int x = 0;
int y = 0;
do
{
x = rand() % 4;
y = rand() % 4;
} while (arr[x][y]);
arr[x][y] = (rand() % 10 ? 2 : 4);
}
//判斷是否獲勝
int IfWin(int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (arr[i][j] == 2048)
{
return 1; //表示贏了
}
if (arr[i][j] == 0)
{
return 0; //表示繼續遊戲
}
}
}
return -1;//輸了
}
//向左移
void MoveLeft()
{
for (int i = 0; i < ROW; i++)
{
int j = 1;
int k = 0;
for (; j < 4; j++)
{
if (arr[i][j] > 0)
{
if (arr[i][k] == 0)
{
arr[i][k] = arr[i][j];
arr[i][j] = 0;
}
else if(arr[i][k] == arr[i][j])
{
arr[i][k] = 2 * arr[i][k];
score += arr[i][k];
arr[i][j] = 0;
k++;
}
else
{
arr[i][++k] = arr[i][j];
if (j != k)
{
arr[i][j] = 0;
}
}
}
}
}
}
//向右移
void MoveRight()
{
for (int i = 0; i < ROW; i++)
{
int j = 2;
int k = 3;
for (; j >= 0; j--)
{
if (arr[i][j] > 0)
{
if (arr[i][k] == 0)
{
arr[i][k] = arr[i][j];
arr[i][j] = 0;
}
else if (arr[i][k] == arr[i][j])
{
arr[i][k] = 2 * arr[i][k];
score += arr[i][k];
arr[i][j] = 0;
k--;
}
else
{
arr[i][--k] = arr[i][j];
if (j != k)
{
arr[i][j] = 0;
}
}
}
}
}
}
//向上移
void MoveUp()
{
for (int j = 0; j < COL; j++)
{
int i = 1;
int k = 0;
for (; i < 4; i++)
{
if (arr[i][j] > 0)
{
if (arr[k][j] == arr[i][j])
{
score += arr[k++][j] *= 2;
arr[i][j] = 0;
}
else if (arr[k][j] == 0)
{
arr[k][j] = arr[i][j];
arr[i][j] = 0;
}
else
{
arr[++k][j] = arr[i][j];
if (i != k)
{
arr[i][j] = 0;
}
}
}
}
}
}
//向下移
void MoveDown()
{
for (int j = 0; j < COL; j++)
{
int i = 2;
int k = 3;
for (; i >= 0; i--)
{
if (arr[i][j] > 0)
{
if (arr[k][j] == 0)
{
arr[k][j] = arr[i][j];
arr[i][j] = 0;
}
else if (arr[k][j] == arr[i][j])
{
arr[k][j] = 2 * arr[k][j];
score += arr[k][j];
arr[i][j] = 0;
k--;
}
else
{
arr[--k][j] = arr[i][j];
if (i != k)
{
arr[i][j] = 0;
}
}
}
}
}
}
//遊戲繼續
void GameContinue()
{
//為了判斷在鍵盤上按下的哪個鍵
int ch1 = 0;
int ch2 = 0;
while (1)
{
if (ch1 = _getch())
{
ch2 = _getch();
if (ch2 == 72)
{
MoveUp();
break;
}
if (ch2 == 80)
{
MoveDown();
break;
}
if (ch2 == 75)
{
MoveLeft();
break;
}
if (ch2 == 77)
{
MoveRight();
break;
}
}
}
}
void game()
{
srand((unsigned int)time(NULL));
ViewInit(20, 10);
RandNum(ROW, COL);
RandNum(ROW, COL);
GamePrint(ROW, COL);
while (1)
{
if (IfWin(ROW, COL) == 1)
{
printf("YOU WIN!\n");
return;
}
else if (IfWin(ROW, COL) == -1)
{
printf("GAME OVER\n");
return;
}
else
{
GameContinue();
system("cls");
RandNum(ROW, COL);
GamePrint(ROW, COL);
}
}
}
int main()
{
game();
system("pause");
return 0;
}