2048 game C language source code with archive function

The freshman self-taught for two months, the C language code style is not good, sorry

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include <windows.h>

#define VK_W 119
#define VK_A 97
#define VK_S 115
#define VK_D 100
#define VK_Q 113
#define VK_M 109
#define VK_R 114
#define VK_N 110

void print_map(void); //Print the map and randomly print 2 or 4 squares on the map
void move_up(void);
void move_right(void);
void move_down(void);
void move_left(void);
void swap(int *a, int *b); //swap blocks
bool game_over(void); //Game failure judgment
void read_save(void); //Read game save
void save_data(void); //Save the game
void save_high_score(void); //Save the highest score
void read_high_score(void); //Read the highest score
void check_move(void); //Check if it can be moved (import the array M into the temporary array temp)
int is_move(void); //check if it can move (compare M and temp arrays, if they are the same, you can't move)

unsigned int M[4][4] = { 0 }, temp[4][4] = { 0 }; //M is the chessboard
int score = 0, step = 0, high_score = 0, flag = 0; //flag is used to determine whether it is possible to move or whether the keyboard input command is legal
int *q = &score, *p = &high_score;

int main(void)
{
	int key_command;
	printf("--------------------GAME:2048---------------------\nPress Press R to read the game save file, press the M key to delete the save file and start the game, and press other keys to start the game quickly\nOperation instructions:W move up\tD move right\tS move down\tA move left.\n");
	key_command = getch();
	switch (key_command)
	{
	    case VK_R:read_save(); break;
		case VK_M:remove("save_data.bin"); break;
		default:break;
	}
	for (;;)
	{
		if (flag == 0)
		{
			system("cls");
			printf("----------------GAME:2048-----------------\nScore:%-10d Steps:% -4d highest score:%d\n",score, step, high_score);
			print_map();
			step++;
		}
		key_command = getch();
		if (key_command == VK_M)save_data();
		else if (key_command == VK_Q)return 0;
		else if (key_command == VK_A)move_left();
		else if (key_command == VK_W)move_up();
		else if (key_command == VK_D)move_right();
		else if (key_command == VK_S)move_down();
		else { flag = -1; continue; }
		if (game_over() == false)return 0;
	}
	return 0;
}

void print_map(void)
{
	int i, j, m1, n1, m2, n2,num_zero=0,check;
	srand(time(0));
	if (step == 0) //At the beginning of the game, randomly import 2 and 4 blocks into the map
	{
		m1 = rand() % 4, n1 = rand() % 4;
		M[m1][n1] = 2;
		m2 = rand ()% 4, n2 = rand ()% 4;
		M[m2][n2] = 4;
	}
	for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) if (M[i][j] == 0) num_zero++; // record the number of empty blocks
	if (step != 0 && num_zero != 0) //The second step starts, if there is an empty square, write 2 or 4 in the empty square.
		for (;;)
		{
			m1 = rand() % 4, n1 = rand() % 4; m2 = edge() % 4;
			if (M[m1][n1] == 0)
				if (m2 < 4 && m2>1) { M[m1][n1] = 2; break; }
				else { M[m1][n1] = 4; break; }
		}
	for (i = 0; i < 4; i++)
	{
		printf("     |-----|-----|-----|-----|\n");
		printf("     |%5d|%5d|%5d|%5d|\n", M[i][0], M[i][1], M[i][2], M[i][3]);
	}
	printf("     |-----|-----|-----|-----|\n");
	printf("\nPress M to save, press Q to exit the game.\n");
}

void move_left(void)
{
	int i, k;
	check_move();
	for (i = 0; i < 4; i++) // 4 permutations of a row of squares
		for (k = 1; k < 4; k++)
		{
			if (M[i][0] == 0 && M[i][1] != 0) swap(&M[i][0], &M[i][1]);
			if (M[i][1] == 0 && M[i][2] != 0) swap(&M[i][1], &M[i][2]);
			if (M[i][2] == 0 && M[i][3] != 0) swap(&M[i][2], &M[i][3]);
	    }
	for (i = 0; i < 4; i++) //If the two adjacent squares are the same, the addition operation is performed, and the other square becomes an empty square
	{
		if (M[i][0] == M[i][1]) M[i][0] *= 2, M[i][1] = 0, score += M[i][0] * 2;
		if (M[i][1] == M[i][2]) M[i][1] *= 2, M[i][2] = 0, score += M[i][1] * 2;
		if (M[i][2] == M[i][3]) M[i][2] *= 2, M[i][3] = 0, score += M[i][2] * 2;
	}
	for (i = 0; i < 4; i++) // permutation again
		for (k = 1; k < 4; k++)
		{
			if (M[i][0] == 0 && M[i][1] != 0) swap(&M[i][0], &M[i][1]);
			if (M[i][1] == 0 && M[i][2] != 0) swap(&M[i][1], &M[i][2]);
			if (M[i][2] == 0 && M[i][3] != 0) swap(&M[i][2], &M[i][3]);
	    }
	flag = is_move();
}

void move_right(void)
{
	int i, k;
	check_move();
	for (i = 0; i < 4; i++)
		for (k = 1; k < 4; k++)
		{
			if (M[i][3] == 0 && M[i][2] != 0) swap(&M[i][3], &M[i][2]);
			if (M[i][2] == 0 && M[i][1] != 0) swap(&M[i][1], &M[i][2]);
			if (M[i][1] == 0 && M[i][0] != 0) swap(&M[i][1], &M[i][0]);
		}
	for (i = 0; i < 4; i++)
	{
		if (M[i][3] == M[i][2]) M[i][3] *= 2, M[i][2] = 0, score += M[i][3] * 2;
		if (M[i][2] == M[i][1]) M[i][2] *= 2, M[i][1] = 0, score += M[i][2] * 2;
		if (M[i][1] == M[i][0]) M[i][1] *= 2, M[i][0] = 0, score += M[i][1] * 2;
	}
	for (i = 0; i < 4; i++)
		for (k = 1; k < 4; k++)
		{
			if (M[i][3] == 0 && M[i][2] != 0) swap(&M[i][3], &M[i][2]);
			if (M[i][2] == 0 && M[i][1] != 0) swap(&M[i][1], &M[i][2]);
			if (M[i][1] == 0 && M[i][0] != 0) swap(&M[i][1], &M[i][0]);
		}
	flag = is_move();
}

void move_up(void)
{
	int i, k;
	check_move();
	for (i = 0; i < 4; i++)
		for(k = 1; k < 4; k++)
		{
			if (M[0][i] == 0 && M[1][i] != 0) swap(&M[0][i], &M[1][i]);
			if (M[1][i] == 0 && M[2][i] != 0) swap(&M[1][i], &M[2][i]);
			if (M[2][i] == 0 && M[3][i] != 0) swap(&M[2][i], &M[3][i]);
		}
	for (i = 0; i < 4; i++)
	{
		if (M[0][i] == M[1][i]) M[0][i] *= 2, M[1][i] = 0, score += M[0][i] * 2;
		if (M[1][i] == M[2][i]) M[1][i] *= 2, M[2][i] = 0, score += M[1][i] * 2;
		if (M[2][i] == M[3][i]) M[2][i] *= 2, M[3][i] = 0, score += M[2][i] * 2;
	}
	for (i = 0; i < 4; i++)
		for (k = 1; k < 4; k++)
		{
			if (M[0][i] == 0 && M[1][i] != 0) swap(&M[0][i], &M[1][i]);
			if (M[1][i] == 0 && M[2][i] != 0) swap(&M[1][i], &M[2][i]);
			if (M[2][i] == 0 && M[3][i] != 0) swap(&M[2][i], &M[3][i]);
		}
	flag = is_move();
}

void move_down(void)
{
	int i, k;
	check_move();
	for (i = 0; i < 4; i++)
		for (k = 1; k < 4; k++)
		{
			if (M[3][i] == 0 && M[2][i] != 0) swap(&M[3][i], &M[2][i]);
			if (M[2][i] == 0 && M[1][i] != 0) swap(&M[2][i], &M[1][i]);
			if (M[1][i] == 0 && M[0][i] != 0) swap(&M[1][i], &M[0][i]);
		}
	for (i = 0; i < 4; i++)
	{
		if (M[3][i] == M[2][i]) M[3][i] *= 2, M[2][i] = 0, score += M[3][i] * 2;
		if (M[2][i] == M[1][i]) M[2][i] *= 2, M[1][i] = 0, score += M[2][i] * 2;
		if (M[1][i] == M[0][i]) M[1][i] *= 2, M[0][i] = 0, score += M[1][i] * 2;
	}
	for (i = 0; i < 4; i++)
		for (k = 1; k < 4; k++)
		{
			if (M[3][i] == 0 && M[2][i] != 0) swap(&M[3][i], &M[2][i]);
			if (M[2][i] == 0 && M[1][i] != 0) swap(&M[1][i], &M[2][i]);
			if (M[1][i] == 0 && M[0][i] != 0) swap(&M[1][i], &M[0][i]);
		}
	flag = is_move();
}

bool game_over(void)
{
	int i, j;
	for (i = 0; i < 4; i++)
		for (j = 0; j < 4; j++)
			if (M[i][j] == 0)return true;
	if (i == 0 && j == 0)
		if (M[0][0] == M[0][1] || M[0][0] == M[1][0])return true;
	if (i == 0 && j == 3)
		if (M[0][3] == M[0][2] || M[0][3] == M[1][3])return true;
	if (i == 3 && j == 0)
		if (M[3][0] == M[3][2] || M[3][0] == M[2][0])return true;
	if (i == 3 && j == 3)
		if (M[3][3] == M[3][2] || M[3][3] == M[2][3])return true;
	if (M[0][1] == M[0][2])return true;
	if (M[1][0] == M[2][0])return true;
	if (M[1][3] == M[2][3])return true;
	if (M[3][1] == M[3][2])return true;
	for (i = 1; i < 3; i++)
		for (j = 1; j < 3; j++)
			if (M[i][j] == M[i - 1][j] || M[i][j] == M[i][j - 1] || M[i][j] == M[i + 1][j] || M[i][j] == M[i][j + 1])
				return true;
	if (score > high_score)
	{
		high_score = score;
		printf("You created a new record: %d\n", high_score);
		save_high_score();
		return false;
	}
	else printf("Your score is: %d\n", score);
	return false;
}

void swap(int *a, int *b)
{
	int temp;
	temp = *a;
	*a = *b;
	*b = temp;
}

void read_save(void)
{
	FILE *fp = fopen("save_data.bin", "rb");
	if (fp == NULL)
	{
		printf("Unable to find or open the archive, press N to create a new archive and start\n");
		if (getch() == VK_N)save_data();
		return;
	}
	fread(M, sizeof(M[0][0]), sizeof(M) / sizeof(M[0][0]), fp);
	fread(q, sizeof(score), 1, fp);
	fclose(fp);
	read_high_score();
}

void save_data(void)
{
	FILE *fp = fopen("save_data.bin", "wb");
	if (fp == NULL)
	{
		printf("Could not find or open archive\n");
		return;
	}
	fwrite(M, sizeof(M[0][0]), sizeof(M) / sizeof(M[0][0]), fp);
	fwrite(q, sizeof(score), 1, fp);
	printf("Archive success.\n");
	fclose(fp);
}

void save_high_score(void)
{
	FILE *fp = fopen("save_data_highscore.bin", "wb");
	FILE *del = fopen("save_data.bin", "w");
	if (fp == NULL)
	{
		printf("Could not find or open archive\n");
		return;
	}
	fwrite(p, sizeof(high_score), 1, fp);
	fclose(fp);
	fclose(del);
}

void read_high_score(void)
{
	FILE *fp = fopen("save_data_highscore.bin", "rb");
	fread(p, sizeof(high_score), 1, fp);
	fclose(fp);
}

void check_move(void)
{
	for (int i = 0; i < 4; i++)
		for (int j = 0; j < 4; j++)
			temp[i][j] = M[i][j];
}

int is_move(void) //If M and temp are inconsistent, it means that it can be moved and returns 0; if they are consistent, it means that it cannot be moved and returns -1
{
	for (int i = 0; i < 4; i++)
		for (int j = 0; j < 4; j++)
			if (M[i][j] != temp[i][j])
				return 0;
	return -1;
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325989141&siteId=291194637