image.png
#include"stdafx.h"
#include"stdlib.h"
#include"stdio.h"
#include"time.h"
#include"conio.h"
#include"windows.h"
int grid[4][4] = { 0 }; //保存4*4的格子数字
int score = 0;//游戏分数
void gotoXY(int x, int y) //设定输出位置
{
COORD c; //光标位置
c.X = x - 1;
c.Y = y - 1;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);//获取句柄,设置位置
HANDLE hOutStd = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci; //控制台光标信息结构类型
cci.dwSize = 1; //光标大小
cci.bVisible = 0; //是否显示光标 true显示
SetConsoleCursorInfo(hOutStd, &cci); //设置控制台屏幕光标大小和可见性
}
void printGrid() { //打印游戏表格
system("cls");
printf("======C语言控制台版2048游戏======\n");
for (int i = 0; i < 4; i++) {
printf("---------------------------------\n");
for (int j = 0; j < 4; j++) {
if (grid[i][j] == 0) { printf("| \t"); }//打印空数
else printf("| %d\t", grid[i][j]);//打印数字
}
printf("|\n");//换行
}
printf("---------------------------------\n");
gotoXY(18 * 2, 5);//定位输出
printf("目前得分:%d", score);
gotoXY(18 * 2, 7);
printf("《请按四个方向箭头进行操作》");
}
void randomNum() {
srand((unsigned int)time(NULL));
int x = rand() % 4; //随机坐标
int y = rand() % 4;
while (grid[x][y] != 0) {//生成的位置已经有数字就重新生成
x = rand() % 4;
y = rand() % 4;
}
int z = rand() % 5;//概率媒介
if (z == 0)grid[x][y] = 4;//五分之一的概率产生数字4
else grid[x][y] = 2;//五分之四的概率产生数字2
}
//获取格子中的最大的数字
int getMax() {
int max = 0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (grid[i][j] > max) {
max = grid[i][j];
}
}
}
return max;
}
int gameOver() {
int result = 1;//等于0继续游戏,等于1结束游戏
//计算最大的数为2048时赢得游戏结束
if (getMax() == 2048) {
result = 1;
printf("恭喜你赢得游戏!/n");
system("pause");
}
//判断存在空格子,继续
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (grid[i][j] == 0) result = 0;
break;
}
}
//如果格子都不为空,需要进一步判断相邻格子数字是否相同
if (result == 1) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (i != 0 && grid[i][j] == grid[i - 1][j]) result = 0; //与上面的数比较
if (i != 3 && grid[i][j] == grid[i + 1][j]) result = 0; //与下面的数比较
if (j != 0 && grid[i][j] == grid[i][j - 1]) result = 0;//与左边的数比较
if (j != 3 && grid[i][j] == grid[i][j + 1]) result = 0;//与右边的数比较
}
}
}
return result;
}
//向上划
int toUp() {
int col, row;
int isMove = 0;//默认0不移动,设置为1表明已经移动
for (col = 0; col < 4; col++) {
for (row = 1; row < 4; row++) {//纵向开始
if (grid[row][col] && grid[row - 1][col] == 0) { //本格不为空,上一格数为空,补空位
grid[row - 1][col] = grid[row][col];
grid[row][col] = 0;//补位后置空
//重置row,补位到最终位置
if (row > 1) row -= 2;
isMove = 1;
}
}
//纵向相邻相同的数字则累加合位
for (int row = 1; row < 4; row++) {
if (grid[row][col] && grid[row - 1][col] == grid[row][col]) {//本格不为空,且与上一格数字相同则合并
grid[row - 1][col] *= 2;
score += grid[row][col];
grid[row][col] = 0;//合并完后置空
isMove = 1;
}
}
//合并后再次补空位
for (row = 1; row < 4; row++) {
if (grid[row][col] && grid[row - 1][col] == 0) { //本格数不为空,上一格数为空,补空位
grid[row - 1][col] = grid[row][col];
grid[row][col] = 0;//补位后置空
//重置row,补位到最终位置
if (row > 1) row -= 2;
}
}
}
return isMove;
}
//向下划
int toDown() {
int col, row;
int isMove = 0;//默认0不移动
for (col = 0; col < 4; col++) {
for (row = 2; row >= 0; row--) {//纵向开始
if (grid[row][col] && grid[row + 1][col] == 0) { //本格数不为空,下一格数为空,补空位
grid[row + 1][col] = grid[row][col];
grid[row][col] = 0;//补位后置空
//重置row,补位到最终位置
if (row < 2) row += 2;
isMove = 1;
}
}
//纵向相邻相同的数字则累加合位
for (row = 2; row >= 0; row--) {
if (grid[row][col] && grid[row + 1][col] == grid[row][col]) {//本格不为空,且与下一格数字相同则合并
grid[row + 1][col] *= 2;
score += grid[row][col];
grid[row][col] = 0;//合并完后置空
isMove = 1;
}
}
//合并后再次补空位
for (row = 2; row >= 0; row--) {
if (grid[row][col] && grid[row + 1][col] == 0) { //本格数不为空,下一格数为空,补空位
grid[row + 1][col] = grid[row][col];
grid[row][col] = 0;//补位后置空
//重置row,补位到最终位置
if (row < 2) row += 2;
}
}
}
return isMove;
}
//向左划
int toLeft() {
int col, row;
int isMove = 0;//默认0不移动
for (row = 0; row < 4; row++) {
for (col = 1; col < 4; col++) {//横向开始
if (grid[row][col] && grid[row][col - 1] == 0) { //本格数不为空,左格数为空,补空位
grid[row][col - 1] = grid[row][col];
grid[row][col] = 0;//补位后置空
//重置col,补位到最终位置
if (col > 1) col -= 2;
isMove = 1;
}
}
//横向相邻相同的数字则累加合位
for (int col = 1; col < 4; col++) {
if (grid[row][col] && grid[row][col - 1] == grid[row][col]) {//本格不为空,且与左边数字相同则合并
grid[row][col - 1] *= 2;
score += grid[row][col];
grid[row][col] = 0;//合并完后置空
isMove = 1;
}
}
//合并后再次补空位
for (col = 1; col < 4; col++) {
if (grid[row][col] && grid[row][col - 1] == 0) { //本格数不为空,左格数为空,补空位
grid[row][col - 1] = grid[row][col];
grid[row][col] = 0;//补位后置空
//重置col,补位到最终位置
if (col > 1) col -= 2;
}
}
}
return isMove;
}
//向右划
int toRight() {
int col, row;
int isMove = 0;//默认0不移动
for (row = 0; row < 4; row++) {
for (col = 2; col >= 0; col--) {//横向开始
if (grid[row][col] && grid[row][col + 1] == 0) { //本格数不为空,右格数为空,补空位
grid[row][col + 1] = grid[row][col];
grid[row][col] = 0;//补位后置空
//重置col,补位到最终位置
if (col < 2) col += 2;
isMove = 1;
}
}
//横向相邻相同的数字则累加合位
for (col = 2; col >= 0; col--) {
if (grid[row][col] && grid[row][col + 1] == grid[row][col]) {//本格不为空,且与右边数字相同则合并
grid[row][col + 1] *= 2;
score += grid[row][col];
grid[row][col] = 0;//合并完后置空
isMove = 1;
}
}
//合并后再次补空位
for (col = 2; col >= 0; col--) {
if (grid[row][col] && grid[row][col + 1] == 0) { //本格数不为空,右格数为空,补空位
grid[row][col + 1] = grid[row][col];
grid[row][col] = 0;//补位后置空
//重置col,补位到最终位置
if (col < 2) col += 2;
}
}
}
return isMove;
}
//接收移动按键并刷新格子移动
void moveDirection() {
int ch = _getch();
switch (ch) {
//向上箭头 224 72 判断接收两次
case 72: //上划
if (toUp() == 1) {
randomNum();
printGrid();
}
break;
//向下箭头 224 80 判断接收两次
case 80://下划
if (toDown() == 1) {
randomNum();
printGrid();
}
break;
//向左箭头 224 75 判断接收两次
case 75: //左划
if (toLeft() == 1) {
randomNum();
printGrid();
}
break;
//向右箭头 224 77 判断接收两次
case 77://右划
if (toRight() == 1) {
randomNum();
printGrid();
}
break;
default:break;
}
}
void playGame() { //开始游戏
int flag = 1;
while (flag) {
//初始化格子,设置为0
memset(grid, 0, sizeof(grid));
//产生两个随机数字
randomNum();
randomNum();
//打印格子
printGrid();
//游戏没有结束就可以一直操作,1是结束游戏
while (gameOver() == 0) {
//接收移动按键并进行移动
moveDirection();
}
system("cls");
printf("游戏结束,您的分数为:%d\n", score);
printf("按y继续游戏,按n退出游戏!\n");
//切换英文输入法
keybd_event(VK_SHIFT, 0, 0, 0);
Sleep(100);
keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
int mark = 1;
while (mark) {
//接收按键
char ch = _getch();
if (ch == 'y' || ch == 'Y') {
flag = 1;
mark = 0;
score = 0;
}
else if (ch == 'n' || ch == 'N') {
system("cls");
printf("欢迎下次来玩!\n");
system("pause");
exit(1);
}
else {
printf("输入错误,请重新输入!\n");
}
}
}
}
int main() {
//进行2048游戏
playGame();
system("pause");
return 0;
}
网友评论