文章目录

  • 游戏介绍
  • 效果展示
  • 游戏代码
    • 游戏基础代码详解
      • 光标操作与界面操作
        • 光标位置定义
        • 隐藏光标
      • 代码可读性
      • 数据存放
      • 数据生成
      • 数据处理
        • 指针初始化
        • 数据处理代码
          • 行处理
          • 列处理
          • 向左或向右处理
          • 向上或向下处理
          • 检查是否有可以合并的数字
          • 数据查重
          • 数据合并
      • 游戏界面与数据打印
        • 边框打印(界面初始化)
        • 数据打印
        • 节点美化
      • 游戏结束条件
        • 游戏结束判断
        • 四个方向的判断
        • 行列查满
      • 游戏运行框架整合
      • main函数
  • 游戏完整代码

游戏介绍

  1. 按方向键上下左右,可以实现“2048”游戏数据的整合。
  2. 按R键重开游戏。
  3. 游戏拥有计分系统

效果展示

游戏代码

游戏源代码如下,可以直接在自己的编译器里运行。

游戏基础代码详解

光标操作与界面操作

光标位置定义

static void _SetPos(int x, int y)
{COORD position;HANDLE handle;position.X = x;position.Y = y;handle = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleCursorPosition(handle, position);
}

隐藏光标

static void HidePos()
{CONSOLE_CURSOR_INFO cursor_info = {1, FALSE};SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

代码可读性

一些宏定义

//函数返还
#define FALSE 0
#define OK 1
//操作输入
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
//游戏数据
#define SIZE 4
#define HIDE 0
#define TOWER 0

双指针

typedef struct Sentry//用于处理游戏数据
{Map_2048 *TravelSentry;Map_2048 *CheckSentry;
} SentryDouble;

数据存放

将游戏数据存放在二位数组中

// 2048游戏数据的存放
typedef int Map_2048;
Map_2048 Map[SIZE + 1][SIZE + 1];
//游戏地图初始化,Map[0][]与Map[][0],用于判断行列是否已满

数据生成

在随机位置生成2或4(2的生成概率为90%,4的生成概率为10%)

static status GAME_DataCreate()
{int x, y;//地图坐标int Weight;//生成概率Weight = rand() % 10;//0~9srand(time(NULL));if (Map[TOWER][TOWER])return FALSE;while (1){x = rand() % SIZE + 1;//1~4y = rand() % SIZE + 1;//1~4if (!Map[x][y])if (Weight)//非0则生成2{Map[x][y] = 2;break;}else{Map[x][y] = 4;break;}}return OK;
}

数据处理

在按下方向键上下左右后处理游戏数据

#mermaid-svg-4Lr0q2Fp6mqHnsm9 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .error-icon{fill:#552222;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .marker.cross{stroke:#333333;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .cluster-label text{fill:#333;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .cluster-label span{color:#333;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .label text,#mermaid-svg-4Lr0q2Fp6mqHnsm9 span{fill:#333;color:#333;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .node rect,#mermaid-svg-4Lr0q2Fp6mqHnsm9 .node circle,#mermaid-svg-4Lr0q2Fp6mqHnsm9 .node ellipse,#mermaid-svg-4Lr0q2Fp6mqHnsm9 .node polygon,#mermaid-svg-4Lr0q2Fp6mqHnsm9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .node .label{text-align:center;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .node.clickable{cursor:pointer;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .arrowheadPath{fill:#333333;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .cluster text{fill:#333;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 .cluster span{color:#333;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-4Lr0q2Fp6mqHnsm9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

数据处理
行处理
列处理
向 左 处理
向 右 处理
向 上 处理
向 下 处理
处理完毕

指针初始化

static status SentryInitialize(int Player_Input, SentryDouble *Sentry, int i)
{switch (Player_Input){case UP:Sentry->TravelSentry = Sentry->CheckSentry = &Map[1][i];break;case LEFT:Sentry->TravelSentry = Sentry->CheckSentry = &Map[i][1];break;case DOWN:Sentry->TravelSentry = Sentry->CheckSentry = &Map[SIZE][SIZE - i + 1];break;case RIGHT:Sentry->TravelSentry = Sentry->CheckSentry = &Map[SIZE - i + 1][SIZE];break;default:break;}return OK;
}

数据处理代码

static status GAME_DataDeal(int Player_Input)
{switch (Player_Input){case UP:case DOWN:GAME_YDataDeal(Player_Input);break;case LEFT:case RIGHT:GAME_XDataDeal(Player_Input);break;default:break;}return OK;
}
行处理
static status GAME_XDataDeal(int Player_Input)
{SentryDouble Sentry;for (int i = 1; i <= SIZE; i++)GAME_XPartDataDeal(Player_Input, &Sentry, i);return OK;
}
列处理
static status GAME_YDataDeal(int Player_Input)
{SentryDouble Sentry;for (int i = 1; i <= SIZE; i++)GAME_YPartDataDeal(Player_Input, &Sentry, i);return OK;
}
向左或向右处理
static status GAME_XPartDataDeal(int Player_Input, SentryDouble *Sentry, int i)
{SentryInitialize(Player_Input, Sentry, i); //指针初始化Map_2048 *ExSentry;//哨兵ExSentry = (Player_Input == LEFT ? (&Map[i][SIZE]) : (&Map[SIZE - i + 1][1])); //向左或向右处理int Sew = Player_Input == LEFT ? 1 : -1; //向左或向右处理                                while ((*Sentry->TravelSentry == 0) && (Sentry->TravelSentry != ExSentry)) //排除零Sentry->CheckSentry = Sentry->TravelSentry = Sentry->TravelSentry + Sew;while (Sentry->TravelSentry != ExSentry){Sentry->CheckSentry = Sentry->TravelSentry;while (Sentry->CheckSentry != ExSentry)CheckSentryDeal(Player_Input, Sentry);//检查是否有可以合并的数字Sentry->TravelSentry = Sentry->TravelSentry + Sew;}return OK;
}
向上或向下处理
static status GAME_YPartDataDeal(int Player_Input, SentryDouble *Sentry, int i)
{SentryInitialize(Player_Input, Sentry, i); //指针初始化Map_2048 *ExSentry;//哨兵ExSentry = (Player_Input == UP ? &Map[SIZE][i] : &Map[1][SIZE - i + 1]); //向上或向下处理int Sew = (Player_Input == UP ? (SIZE + 1) : -(SIZE + 1));               //向上或向下处理while ((*Sentry->TravelSentry == 0) && (Sentry->TravelSentry != ExSentry)) //排除零Sentry->CheckSentry = Sentry->TravelSentry = Sentry->TravelSentry + Sew;while (Sentry->TravelSentry != ExSentry){Sentry->CheckSentry = Sentry->TravelSentry;while (Sentry->CheckSentry != ExSentry)CheckSentryDeal(Player_Input, Sentry);//检查是否有可以合并的数字,并处理Sentry->TravelSentry = Sentry->TravelSentry + Sew;}return OK;
}
检查是否有可以合并的数字
#mermaid-svg-Ne3KTEqlCRKFapKy {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Ne3KTEqlCRKFapKy .error-icon{fill:#552222;}#mermaid-svg-Ne3KTEqlCRKFapKy .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ne3KTEqlCRKFapKy .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-Ne3KTEqlCRKFapKy .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ne3KTEqlCRKFapKy .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ne3KTEqlCRKFapKy .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ne3KTEqlCRKFapKy .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ne3KTEqlCRKFapKy .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ne3KTEqlCRKFapKy .marker.cross{stroke:#333333;}#mermaid-svg-Ne3KTEqlCRKFapKy svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ne3KTEqlCRKFapKy .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Ne3KTEqlCRKFapKy .cluster-label text{fill:#333;}#mermaid-svg-Ne3KTEqlCRKFapKy .cluster-label span{color:#333;}#mermaid-svg-Ne3KTEqlCRKFapKy .label text,#mermaid-svg-Ne3KTEqlCRKFapKy span{fill:#333;color:#333;}#mermaid-svg-Ne3KTEqlCRKFapKy .node rect,#mermaid-svg-Ne3KTEqlCRKFapKy .node circle,#mermaid-svg-Ne3KTEqlCRKFapKy .node ellipse,#mermaid-svg-Ne3KTEqlCRKFapKy .node polygon,#mermaid-svg-Ne3KTEqlCRKFapKy .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Ne3KTEqlCRKFapKy .node .label{text-align:center;}#mermaid-svg-Ne3KTEqlCRKFapKy .node.clickable{cursor:pointer;}#mermaid-svg-Ne3KTEqlCRKFapKy .arrowheadPath{fill:#333333;}#mermaid-svg-Ne3KTEqlCRKFapKy .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Ne3KTEqlCRKFapKy .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Ne3KTEqlCRKFapKy .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-Ne3KTEqlCRKFapKy .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-Ne3KTEqlCRKFapKy .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Ne3KTEqlCRKFapKy .cluster text{fill:#333;}#mermaid-svg-Ne3KTEqlCRKFapKy .cluster span{color:#333;}#mermaid-svg-Ne3KTEqlCRKFapKy div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Ne3KTEqlCRKFapKy :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

查找重复的数字
判断两个数字之间是否有其他数字
合并
不合并
static status CheckSentryDeal(int Player_Input, SentryDouble *Sentry)
{switch (Player_Input){case UP:Sentry->CheckSentry = Sentry->CheckSentry + SIZE + 1;break;case DOWN:Sentry->CheckSentry = Sentry->CheckSentry - (SIZE + 1);break;case LEFT:Sentry->CheckSentry = Sentry->CheckSentry + 1;break;case RIGHT:Sentry->CheckSentry = Sentry->CheckSentry - 1;break;default:break;}if ((*Sentry->CheckSentry == *Sentry->TravelSentry) && (*Sentry->CheckSentry != 0))if (RangeSentryDeal(Player_Input, *Sentry) && *Sentry->TravelSentry != 2048)//查重且可以合并{DataMerge(Sentry);//合并return OK;}return FALSE;
}
数据查重

找到两个相同的数据,并判断是否可以合并

static status RangeSentryDeal(int Player_Input, SentryDouble Sentry)
{int I;int Sew;Map_2048 *RangeSentry;switch (Player_Input){case UP:case LEFT:Sew = Player_Input == UP ? (SIZE + 1) : 1;I = (Sentry.CheckSentry - Sentry.TravelSentry) / Sew;RangeSentry = Sentry.TravelSentry;while (I--){RangeSentry = RangeSentry + Sew;if (*RangeSentry != 0 && *RangeSentry != *Sentry.TravelSentry)return FALSE;}break;case DOWN:case RIGHT:Sew = Player_Input == DOWN ? (SIZE + 1) : 1;I = (Sentry.TravelSentry - Sentry.CheckSentry) / Sew;RangeSentry = Sentry.CheckSentry;while (I--){RangeSentry = RangeSentry + Sew;if (*RangeSentry != 0 && *RangeSentry != *Sentry.CheckSentry)return FALSE;}break;default:break;}return OK;
}
数据合并

将两个数据合并

static status DataMerge(SentryDouble *Sentry)
{*Sentry->TravelSentry = (*Sentry->TravelSentry) * 2;*Sentry->CheckSentry = HIDE;return OK;
}

游戏界面与数据打印

边框打印(界面初始化)

打印游戏运行的边框

static status GAME_DataInitialize()
{for (int i = 0; i < 2; i++){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),51);_SetPos(0, i * 13);printf("■■■■■■■■■■■■■■");for (int j = 0; j < 14; j++){_SetPos(i * 26, j);printf("■");}}return OK;
}
数据打印

根据Map打印数据

static status GAME_DataShow()
{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);for (int i = 0; i < 4; i++){for (int j = 0; j < 4; j++){switch (Map[j + 1][i + 1]){case 2:Node_Beautiy(i, j, 191);break;case 4:Node_Beautiy(i, j, 159);break;case 8:Node_Beautiy(i, j, 175);break;case 16:Node_Beautiy(i, j, 223);break;case 32:Node_Beautiy(i, j, 207);break;case 64:Node_Beautiy(i, j, 71);break;case 128:Node_Beautiy(i, j, 143);break;case 256:Node_Beautiy(i, j, 63);break;case 512:Node_Beautiy(i, j, 31);break;case 1024:Node_Beautiy(i, j, 79);break;case 2048:Node_Beautiy(i, j, 78);break;case 0:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 255);_SetPos(2 + 6 * i, 1 + 3 * j);printf("      ");_SetPos(2 + 6 * i, 2 + 3 * j);printf("      ");_SetPos(2 + 6 * i, 3 + 3 * j);printf("      ");break;default:break;}}}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);return OK;
}
节点美化

将数据美化

static status Node_Beautiy(int i, int j, int color)//在i,j坐标打印并根据 color 美化数据
{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);for (int w = 1; w <= 3; w++){_SetPos(2 + 6 * i, w + 3 * j);w == 2 ? printf("%4d  ", Map[j + 1][i + 1]) : printf("      ");}return OK;
}

游戏结束条件

#mermaid-svg-ZINVsn5YvrT5uhg0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ZINVsn5YvrT5uhg0 .error-icon{fill:#552222;}#mermaid-svg-ZINVsn5YvrT5uhg0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ZINVsn5YvrT5uhg0 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-ZINVsn5YvrT5uhg0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ZINVsn5YvrT5uhg0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ZINVsn5YvrT5uhg0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ZINVsn5YvrT5uhg0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ZINVsn5YvrT5uhg0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ZINVsn5YvrT5uhg0 .marker.cross{stroke:#333333;}#mermaid-svg-ZINVsn5YvrT5uhg0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ZINVsn5YvrT5uhg0 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ZINVsn5YvrT5uhg0 .cluster-label text{fill:#333;}#mermaid-svg-ZINVsn5YvrT5uhg0 .cluster-label span{color:#333;}#mermaid-svg-ZINVsn5YvrT5uhg0 .label text,#mermaid-svg-ZINVsn5YvrT5uhg0 span{fill:#333;color:#333;}#mermaid-svg-ZINVsn5YvrT5uhg0 .node rect,#mermaid-svg-ZINVsn5YvrT5uhg0 .node circle,#mermaid-svg-ZINVsn5YvrT5uhg0 .node ellipse,#mermaid-svg-ZINVsn5YvrT5uhg0 .node polygon,#mermaid-svg-ZINVsn5YvrT5uhg0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ZINVsn5YvrT5uhg0 .node .label{text-align:center;}#mermaid-svg-ZINVsn5YvrT5uhg0 .node.clickable{cursor:pointer;}#mermaid-svg-ZINVsn5YvrT5uhg0 .arrowheadPath{fill:#333333;}#mermaid-svg-ZINVsn5YvrT5uhg0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ZINVsn5YvrT5uhg0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ZINVsn5YvrT5uhg0 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-ZINVsn5YvrT5uhg0 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-ZINVsn5YvrT5uhg0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ZINVsn5YvrT5uhg0 .cluster text{fill:#333;}#mermaid-svg-ZINVsn5YvrT5uhg0 .cluster span{color:#333;}#mermaid-svg-ZINVsn5YvrT5uhg0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ZINVsn5YvrT5uhg0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

如果游戏数据数组已满
判断是否还有数据看可以合并
游戏未结束
游戏已结束

游戏结束判断

static status GAME_OverJudge()
{if (Map[TOWER][TOWER]){Map_2048 Over[SIZE + 1][SIZE + 1];Map_2048 DataSumTemp, DataSum;for (int i = 0; i <= SIZE; i++)for (int j = 0; j <= SIZE; j++){DataSumTemp += Map[i][j];Over[i][j] = Map[i][j];}DataSumTemp -= 9;if (!GAME_OverPartJudge(UP, DataSumTemp, DataSum, Over))return 2;if (!GAME_OverPartJudge(DOWN, DataSumTemp, DataSum, Over))return 2;if (!GAME_OverPartJudge(LEFT, DataSumTemp, DataSum, Over))return 2;if (!GAME_OverPartJudge(RIGHT, DataSumTemp, DataSum, Over))return 2;return OK;}elsereturn FALSE;
}

四个方向的判断

static status GAME_OverPartJudge(int Player_Input, Map_2048 DataSumTemp, Map_2048 DataSum, Map_2048 Over[][SIZE + 1])
{DataSum = 0;GAME_DataDeal(Player_Input);GAME_DataCreate();for (int i = 1; i <= SIZE; i++)for (int j = 1; j <= SIZE; j++){if (Over[i][j] != Map[i][j]){for (int w = 0; w <= SIZE; w++)for (int r = 0; r <= SIZE; r++){Map[w][r] = Over[w][r];}return FALSE;}}return OK;
}

行列查满

static status GAME_DataTowerDeal()
{int j, i;for (i = 1; i <= SIZE; i++){for (j = 1; j <= SIZE; j++)if (!Map[i][j])break;if (j == SIZE + 1)Map[i][TOWER] = 1;elseMap[i][TOWER] = 0;}for (i = 1; i <= SIZE; i++){for (j = 1; j <= SIZE; j++)if (!Map[j][i])break;if (j == SIZE + 1)Map[TOWER][i] = 1;elseMap[TOWER][i] = 0;}for (i = 1; i <= SIZE; i++)if (!Map[i][TOWER] || !Map[TOWER][i])break;Map[TOWER][TOWER] = (i == SIZE + 1 ? 1 : 0);return OK;
}

游戏运行框架整合

static status GAME_PLAY()
{system("mode con cols=28 lines=17 ");//游戏窗口大小定义HidePos();GAME_DataInitialize();//界面初始化int Player_Input, count = 0;for (int i = 0; i <= SIZE; i++)//数据全零for (int j = 0; j <= SIZE; j++)Map[i][j] = 0;for (int i = 0; i < 3; i++) //初始化GAME_DataCreate();GAME_DataShow();//数据打印_SetPos(0, 14);printf("                                  ");_SetPos(0, 15);printf("                                  ");//数据显示while (1){_SetPos(0, 14);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);printf("得分:%5d ", count);printf("重开:R");//得分显示InputAgain:Player_Input = _getch();if (Player_Input == 224)Player_Input = _getch();//识别玩家输入else if (Player_Input == (int)'R' || Player_Input == (int)'r')main();elsegoto InputAgain;GAME_DataDeal(Player_Input);//数据处理DataReorganize(Player_Input);//数据整理GAME_DataTowerDeal();//数据插满GAME_DataShow();//数据显示Sleep(100);//等待新数据生成GAME_DataCreate();//数据生成GAME_DataTowerDeal();//数据插满GAME_DataShow();//数据显示if (GAME_OverJudge() == 1)//游戏结束查询break;else if (!GAME_OverJudge())count++;HidePos();}_SetPos(0, 15);printf("游戏结束 ");Again:printf("是否再来一次?(Y)/(N)");char Player_in;Player_in = getchar();if (Player_in == 'Y' || Player_in == 'y')main();else if (Player_in == 'N' || Player_in == 'n')return OK;elsegoto Again;
}

main函数

int main()
{GAME_PLAY();return 0;
}

游戏完整代码

游戏源代码如下,可以直接在自己的编译器里运行。

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <strsafe.h>//函数返还
#define FALSE 0
#define OK 1
//操作输入
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
//游戏数据
#define SIZE 4
#define HIDE 0
#define TOWER 0typedef int status;
typedef int Map_2048;
typedef struct Sentry
{Map_2048 *TravelSentry;Map_2048 *CheckSentry;
} SentryDouble; //哨兵工具包static void _SetPos(int x, int y); //移动光标到X、Y位置
static void HidePos();             //隐藏光标static status GAME_PLAY();                                                                                             //游戏启动
static status GAME_DataShow();                                                                                         //打印游戏数据
static status GAME_DataInitialize();                                                                                   //图案初始化
static status GAME_DataCreate();                                                                                       //随机生成的2
static status GAME_DataDeal(int Player_Input);                                                                         //根据输入处理已有数据
static status GAME_XDataDeal(int Player_Input);                                                                        //行处理
static status GAME_YDataDeal(int Player_Input);                                                                        //列处理
static status GAME_XPartDataDeal(int Player_Input, SentryDouble *Sentry, int i);                                       //行部分处理
static status GAME_YPartDataDeal(int Player_Input, SentryDouble *Sentry, int i);                                       //列部分处理
static status SentryInitialize(int Player_Input, SentryDouble *Sentry, int i);                                         //根据Player_Input推进哨兵进入下一阶段
static status CheckSentryDeal(int Player_Input, SentryDouble *Sentry);                                                 // CheckSentry运行
static status DataMerge(SentryDouble *Sentry);                                                                         //数据合并
static status RangeSentryDeal(int Player_Input, SentryDouble Sentry);                                                  //通过RangeSentry查询CheckSentry——TravelSentry之间是否全零
static status DataReorganize(int Player_Input);                                                                        //数据整理
static status GAME_DataTowerDeal();                                                                                    //数据查满
static status GAME_OverJudge();                                                                                        //结束查询
static status GAME_OverPartJudge(int Player_Input, Map_2048 DataSumTemp, Map_2048 DataSum, Map_2048 Over[][SIZE + 1]); //四方向判断
static status Node_Beautiy(int i, int j, int color);                                                                   //节点美化
Map_2048 Map[SIZE + 1][SIZE + 1];                                                                          //游戏地图初始化,Map[0][]与Map[][0],用于判断行列是否已满int main()
{GAME_PLAY();return 0;
}static status GAME_DataInitialize()
{for (int i = 0; i < 2; i++){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),51);_SetPos(0, i * 13);printf("■■■■■■■■■■■■■■");for (int j = 0; j < 14; j++){_SetPos(i * 26, j);printf("■");}}return OK;
}static status GAME_OverPartJudge(int Player_Input, Map_2048 DataSumTemp, Map_2048 DataSum, Map_2048 Over[][SIZE + 1])
{DataSum = 0;GAME_DataDeal(Player_Input);GAME_DataCreate();for (int i = 1; i <= SIZE; i++)for (int j = 1; j <= SIZE; j++){if (Over[i][j] != Map[i][j]){for (int w = 0; w <= SIZE; w++)for (int r = 0; r <= SIZE; r++){Map[w][r] = Over[w][r];}return FALSE;}}return OK;
}static status GAME_OverJudge()
{if (Map[TOWER][TOWER]){Map_2048 Over[SIZE + 1][SIZE + 1];Map_2048 DataSumTemp, DataSum;for (int i = 0; i <= SIZE; i++)for (int j = 0; j <= SIZE; j++){DataSumTemp += Map[i][j];Over[i][j] = Map[i][j];}DataSumTemp -= 9;if (!GAME_OverPartJudge(UP, DataSumTemp, DataSum, Over))return 2;if (!GAME_OverPartJudge(DOWN, DataSumTemp, DataSum, Over))return 2;if (!GAME_OverPartJudge(LEFT, DataSumTemp, DataSum, Over))return 2;if (!GAME_OverPartJudge(RIGHT, DataSumTemp, DataSum, Over))return 2;return OK;}elsereturn FALSE;
}static void _SetPos(int x, int y)
{COORD position;HANDLE handle;position.X = x;position.Y = y;handle = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleCursorPosition(handle, position);
}static void HidePos()
{CONSOLE_CURSOR_INFO cursor_info = {1, FALSE};SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}static status GAME_DataCreate()
{int x, y;int Weight;Weight = rand() % 10;srand(time(NULL));if (Map[TOWER][TOWER])return FALSE;while (1){x = rand() % SIZE + 1;y = rand() % SIZE + 1;if (!Map[x][y])if (Weight){Map[x][y] = 2;break;}else{Map[x][y] = 4;break;}}return OK;
}static status GAME_YDataDeal(int Player_Input)
{SentryDouble Sentry;for (int i = 1; i <= SIZE; i++)GAME_YPartDataDeal(Player_Input, &Sentry, i);return OK;
}static status GAME_XDataDeal(int Player_Input)
{SentryDouble Sentry;for (int i = 1; i <= SIZE; i++)GAME_XPartDataDeal(Player_Input, &Sentry, i);return OK;
}static status GAME_DataDeal(int Player_Input)
{switch (Player_Input){case UP:case DOWN:GAME_YDataDeal(Player_Input);break;case LEFT:case RIGHT:GAME_XDataDeal(Player_Input);break;default:break;}return OK;
}static status CheckSentryDeal(int Player_Input, SentryDouble *Sentry)
{switch (Player_Input){case UP:Sentry->CheckSentry = Sentry->CheckSentry + SIZE + 1;break;case DOWN:Sentry->CheckSentry = Sentry->CheckSentry - (SIZE + 1);break;case LEFT:Sentry->CheckSentry = Sentry->CheckSentry + 1;break;case RIGHT:Sentry->CheckSentry = Sentry->CheckSentry - 1;break;default:break;}if ((*Sentry->CheckSentry == *Sentry->TravelSentry) && (*Sentry->CheckSentry != 0))if (RangeSentryDeal(Player_Input, *Sentry) && *Sentry->TravelSentry != 2048){DataMerge(Sentry);return OK;}return FALSE;
}static status RangeSentryDeal(int Player_Input, SentryDouble Sentry)
{int I;int Sew; //缀Map_2048 *RangeSentry;switch (Player_Input){case UP:case LEFT:Sew = Player_Input == UP ? (SIZE + 1) : 1;I = (Sentry.CheckSentry - Sentry.TravelSentry) / Sew;RangeSentry = Sentry.TravelSentry;while (I--){RangeSentry = RangeSentry + Sew;if (*RangeSentry != 0 && *RangeSentry != *Sentry.TravelSentry)return FALSE;}break;case DOWN:case RIGHT:Sew = Player_Input == DOWN ? (SIZE + 1) : 1;I = (Sentry.TravelSentry - Sentry.CheckSentry) / Sew;RangeSentry = Sentry.CheckSentry;while (I--){RangeSentry = RangeSentry + Sew;if (*RangeSentry != 0 && *RangeSentry != *Sentry.CheckSentry)return FALSE;}break;default:break;}return OK;
}static status SentryInitialize(int Player_Input, SentryDouble *Sentry, int i)
{switch (Player_Input){case UP:Sentry->TravelSentry = Sentry->CheckSentry = &Map[1][i];break;case LEFT:Sentry->TravelSentry = Sentry->CheckSentry = &Map[i][1];break;case DOWN:Sentry->TravelSentry = Sentry->CheckSentry = &Map[SIZE][SIZE - i + 1];break;case RIGHT:Sentry->TravelSentry = Sentry->CheckSentry = &Map[SIZE - i + 1][SIZE];break;default:break;}return OK;
}static status GAME_XPartDataDeal(int Player_Input, SentryDouble *Sentry, int i)
{SentryInitialize(Player_Input, Sentry, i); //哨兵初始化Map_2048 *ExSentry;ExSentry = (Player_Input == LEFT ? (&Map[i][SIZE]) : (&Map[SIZE - i + 1][1])); //塔int Sew = Player_Input == LEFT ? 1 : -1;                                       //缀while ((*Sentry->TravelSentry == 0) && (Sentry->TravelSentry != ExSentry)) //排除零Sentry->CheckSentry = Sentry->TravelSentry = Sentry->TravelSentry + Sew;while (Sentry->TravelSentry != ExSentry){Sentry->CheckSentry = Sentry->TravelSentry;while (Sentry->CheckSentry != ExSentry){CheckSentryDeal(Player_Input, Sentry);}Sentry->TravelSentry = Sentry->TravelSentry + Sew;}return OK;
}static status GAME_YPartDataDeal(int Player_Input, SentryDouble *Sentry, int i)
{SentryInitialize(Player_Input, Sentry, i); //哨兵初始化Map_2048 *ExSentry;ExSentry = (Player_Input == UP ? &Map[SIZE][i] : &Map[1][SIZE - i + 1]); //塔int Sew = (Player_Input == UP ? (SIZE + 1) : -(SIZE + 1));               //缀while ((*Sentry->TravelSentry == 0) && (Sentry->TravelSentry != ExSentry)) //排除零Sentry->CheckSentry = Sentry->TravelSentry = Sentry->TravelSentry + Sew;while (Sentry->TravelSentry != ExSentry){Sentry->CheckSentry = Sentry->TravelSentry;while (Sentry->CheckSentry != ExSentry)CheckSentryDeal(Player_Input, Sentry);Sentry->TravelSentry = Sentry->TravelSentry + Sew;}return OK;
}static status DataMerge(SentryDouble *Sentry)
{*Sentry->TravelSentry = (*Sentry->TravelSentry) * 2;*Sentry->CheckSentry = HIDE;return OK;
}static status DataReorganize(int Player_Input)
{SentryDouble Sentry;Map_2048 *ExSentry; //塔int Sew;            //缀for (int i = 1; i <= SIZE; i++){if (Player_Input == LEFT || Player_Input == RIGHT){ExSentry = (Player_Input == LEFT ? &Map[i][SIZE] : &Map[SIZE - i + 1][1]); //塔Sew = (Player_Input == LEFT ? 1 : -1);                                     //缀}else if (Player_Input == UP || Player_Input == DOWN){ExSentry = (Player_Input == UP ? &Map[SIZE][i] : &Map[1][SIZE - i + 1]); //塔Sew = (Player_Input == UP ? SIZE + 1 : -(SIZE + 1));                     //缀}SentryInitialize(Player_Input, &Sentry, i);while (Sentry.TravelSentry != ExSentry){if (*Sentry.TravelSentry == 0){Sentry.CheckSentry = Sentry.TravelSentry;while (Sentry.CheckSentry != ExSentry){Sentry.CheckSentry = Sentry.CheckSentry + Sew;if (*Sentry.CheckSentry != 0){*Sentry.TravelSentry = *Sentry.CheckSentry;*Sentry.CheckSentry = 0;break;}}}Sentry.TravelSentry = Sentry.TravelSentry + Sew;}}return OK;
}static status Node_Beautiy(int i, int j, int color)
{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);for (int w = 1; w <= 3; w++){_SetPos(2 + 6 * i, w + 3 * j);w == 2 ? printf("%4d  ", Map[j + 1][i + 1]) : printf("      ");}return OK;
}static status GAME_DataShow()
{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);for (int i = 0; i < 4; i++){for (int j = 0; j < 4; j++){switch (Map[j + 1][i + 1]){case 2:Node_Beautiy(i, j, 191);break;case 4:Node_Beautiy(i, j, 159);break;case 8:Node_Beautiy(i, j, 175);break;case 16:Node_Beautiy(i, j, 223);break;case 32:Node_Beautiy(i, j, 207);break;case 64:Node_Beautiy(i, j, 71);break;case 128:Node_Beautiy(i, j, 143);break;case 256:Node_Beautiy(i, j, 63);break;case 512:Node_Beautiy(i, j, 31);break;case 1024:Node_Beautiy(i, j, 79);break;case 2048:Node_Beautiy(i, j, 78);break;case 0:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 255);_SetPos(2 + 6 * i, 1 + 3 * j);printf("      ");_SetPos(2 + 6 * i, 2 + 3 * j);printf("      ");_SetPos(2 + 6 * i, 3 + 3 * j);printf("      ");break;default:break;}}}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);return OK;
}static status GAME_DataTowerDeal()
{int j, i;for (i = 1; i <= SIZE; i++){for (j = 1; j <= SIZE; j++)if (!Map[i][j])break;if (j == SIZE + 1)Map[i][TOWER] = 1;elseMap[i][TOWER] = 0;}for (i = 1; i <= SIZE; i++){for (j = 1; j <= SIZE; j++)if (!Map[j][i])break;if (j == SIZE + 1)Map[TOWER][i] = 1;elseMap[TOWER][i] = 0;}for (i = 1; i <= SIZE; i++)if (!Map[i][TOWER] || !Map[TOWER][i])break;Map[TOWER][TOWER] = (i == SIZE + 1 ? 1 : 0);return OK;
}static status GAME_PLAY()
{system("mode con cols=28 lines=17 ");HidePos();GAME_DataInitialize();int Player_Input, count = 0;for (int i = 0; i <= SIZE; i++)for (int j = 0; j <= SIZE; j++)Map[i][j] = 0;for (int i = 0; i < 3; i++) //初始化GAME_DataCreate();GAME_DataShow();/*_SetPos(0, 14);printf("                                  ");_SetPos(0, 15);printf("                                  ");*/while (1){HidePos();_SetPos(0, 14);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);printf("得分:%5d ", count);printf("重开:R");HidePos();InputAgain:Player_Input = _getch();if (Player_Input == 224)Player_Input = _getch();else if (Player_Input == (int)'R' || Player_Input == (int)'r')main();elsegoto InputAgain;GAME_DataDeal(Player_Input);DataReorganize(Player_Input);GAME_DataTowerDeal();GAME_DataShow();Sleep(100);GAME_DataCreate();GAME_DataTowerDeal();GAME_DataShow();if (GAME_OverJudge() == 1)break;else if (!GAME_OverJudge())count++;HidePos();}_SetPos(0, 15);printf("游戏结束 ");Again:printf("是否再来一次?(Y)/(N)");char Player_in;Player_in = getchar();if (Player_in == 'Y' || Player_in == 'y')main();else if (Player_in == 'N' || Player_in == 'n')return OK;elsegoto Again;
}

(C语言)2048游戏实现相关推荐

  1. c语言程序2048_C语言2048小游戏演示和说明

    2048游戏是风靡一时的小游戏,我们提供的2048小游戏不依赖 TC 环境,不依赖任何第三方库,可以在 VS.CodeBlocks.DEV C++ 等常见 IDE中编译通过.我们提供给大家的 2048 ...

  2. 花了一个深夜,才用C语言写了一个2048游戏雏形

    12年我毕业的第二个月工资,我就买了一个IPAD,然后在IPAD上下了一个2048游戏,玩起来非常爽. 然后这几天看到好几个公众号都发了自己写这个游戏的代码,然后我自己也想试试,所以就有了这篇文章,写 ...

  3. 2048游戏c语言linux简易代码,C语言实现2048游戏代码

    本文实例为大家分享了C语言实现2048游戏具体代码,供大家参考,具体内容如下 效果图: 使用文本界面的屏幕绘图库 ncurses. 设计思路: 在满足条件情况下消除方块 允许在游戏主界面(16 宫格) ...

  4. 2048游戏c语言实验报告,2048游戏语言实验报告.doc

    2048游戏语言实验报告 成绩评定 教师签名 评定日期 嘉应学院 计算机学院 实验报告 课程名称: C程序设计 开课学期: 2015-2016学年第1学期 班 级: 计算机1505 指导老师: 陈广明 ...

  5. c语言2048代码linux,C语言2048小游戏课设(附源码).doc

    PAGE PAGE 1 C语言2048小游戏课设 项目说明 本系统基于C语言开发,适用于刚入门的C语言新手项目课设,开发软件采用VC++6.0开发,VS,DEV C++等均可运行.(书生) 项目运行截 ...

  6. c语言2048代码linux,C语言实现2048小游戏(示例代码)

    2048 一.设计思路 1.游戏规则 想要制作游戏,首先需要了解游戏的规则,下面就来介绍2048的游戏规则 2048游戏共有16个格子,初始时初始数字由2或者4构成. 手指向一个方向滑动,所有格子会向 ...

  7. C语言小游戏: 2048.c

    概要:2048.c是一个C语言编写的2048游戏,本文将详细分析它的源码和实现.C语言是一种经典实用的编程语言,本身也不复杂,但是学会C语言和能够编写实用的程序还是有一道鸿沟的.本文试图通过一个例子展 ...

  8. 一个用 C 语言写的迷你版 2048 游戏,只有 500个字符

    Jay Chan 用 C 语言写的一个迷你版 2048 游戏,只有 487 个字符.来围观吧 M[16],X=16,W,k;main(){T(system("stty cbreak" ...

  9. 一个用 C 语言写的迷你版 2048 游戏,仅仅有 500个字符

    Jay Chan 用 C 语言写的一个迷你版 2048 游戏,仅仅有 487 个字符. 来围观吧 M[16],X=16,W,k;main(){T(system("stty cbreak&qu ...

  10. C++学习(三十九)(C语言部分)之 游戏项目(2048游戏)

    /***************************项目 2048********************** c语言编写 图形库制作 时间:2019.04.03 准备工具: vs2013 图形库 ...

最新文章

  1. qt LNK2019 无法解析的外部符号
  2. MySQL删除存储过程(DROP PROCEDURE)
  3. 结对编程Wordcount
  4. App设计灵感之十二组精美的移动支付App设计案例
  5. run sequence between odata request and controller init
  6. linux线程多参数传递参数,Linux中多线程编程并传递多个参数
  7. 钱线观察:货币基金T+0驾到 活期存款将死?
  8. c 调用java程序_C ++可以调用Java代码吗?
  9. 四年级打字计算机上册教案,2019四年级上信息技术教案(A)打字速度靠指法_泰山版教育.doc.docx...
  10. oracle 11g dataguard创建的简单方法
  11. github issue 如何写多行代码块
  12. Fix Bug的五个阶段
  13. 重建大师5.0成为首款支持国产麒麟操作系统的自动实景三维建模软件
  14. flutter之dart语言发展
  15. JLA服务器性能测试,Shell脚本 | 性能测试之CPU占有率
  16. 多重网格法-松弛迭代法-二维泊松方程-python实现
  17. 应聘时要问HR的7个问题
  18. Hadoop HA集群配置问题记录
  19. Linux中Kill进程的N种方法
  20. Linux 判断文件或文件夹是否存在

热门文章

  1. 计算机网络中的ttl怎么理解,Ping值中“TTL”是什么意思,为什么使用“TTL”这个概念?...
  2. python无限循环怎么停止,如何在Python中安全地停止无限循环?
  3. nvme装系统不能自引导_电脑安装了NVME SSD固态硬盘无法进入系统该怎么办?
  4. 图数据库-Nebula部署手册
  5. CentOS7搭建FLV和RTMP流媒体服务器
  6. python 使用 python-socketio 400 错误
  7. [转]file_get_contents(php://input)
  8. 计算机不能删除用户,删除用户时提示无法在内置账户上运行此操作 -电脑资料...
  9. OISPT 内网安全项目组A1-渗透测试基础项目训练文档
  10. 万字综述 | 一文读懂知识蒸馏