#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 0
typedef 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] = {HIDE}; //游戏地图初始化,Map[0][]与Map[][0],用于判断行列是否已满
void main()
{
GAME_PLAY();
getchar();
}
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;
}
else
return 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;
else
Map[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;
else
Map[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 ");
char Player_inPut;
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] = HIDE;
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();
else
goto 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("游戏结束 ");
printf("是否再来一次?(Y)/(N)");
Again:
Player_inPut = getchar();
if (Player_inPut == 'Y' || Player_inPut == 'y')
main();
else if (Player_inPut == 'N' || Player_inPut == 'n')
return OK;
else
goto Again;
}
C语言2048C实现
最新推荐文章于 2023-12-07 18:16:18 发布