用c++实现2048小游戏。
直接上代码,自己下载下来编译就可以玩。
可以自由的退步,终端字符页面,适合拿来摸鱼,也适合初学者朋友用来学习研究。
头文件game.h
#pragma once
#include
enum step_t {
STEP_UP,
STEP_DOWN,
STEP_LEFT,
STEP_RIGHT,
STEP_COUNT
};
class G2048 {
public:
G2048();
~G2048();
bool InitMap();
bool NextStep(step_t step);
bool BackStep();
private:
void PrintMap(int pos);
void FreeSteps();
unsigned int *map;
unsigned int step_counter;
std::list history_steps;
};
类的实现game.cpp:
#include
#include
#include
#include
#include "game.h"
void Printmap(unsigned int *map)
{
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
printf("%8u", map[i * 4 + j]);
}
printf("\n");
}
}
G2048::G2048()
{
map = nullptr;
}
G2048::~G2048()
{
FreeSteps();
}
bool G2048::InitMap()
{
FreeSteps();
map = (unsigned int*)malloc(16 * sizeof(unsigned int));
if (map == nullptr) {
printf("init error, memory out!\n");
return false;
}
memset(map, 0, 16 * sizeof(unsigned int));
int rdm_pos = rand() % 16;
int rdm_num = rand() % 2 + 1;
rdm_num = pow(2, rdm_num);
map[rdm_pos] = rdm_num;
PrintMap(rdm_pos);
return true;
}
bool G2048::NextStep(step_t step)
{
unsigned int* new_map = (unsigned int*)malloc(16 * sizeof(unsigned int));
if (new_map == nullptr) {
printf("step error, memory out!\n");
return false;
}
memset(new_map, 0, 16 * sizeof(unsigned int));
int align_num = -1;
int align_flag = -1;
switch (step) {
case STEP_UP:
for (int j = 0; j < 4; j++) {
align_num = -1;
align_flag = -1;
for (int i = 0; i < 4; i++) {
if (map[i * 4 + j] == 0)
{
continue;
}
if (map[i * 4 + j] == align_num) {
new_map[align_flag * 4 + j] += map[i * 4 + j];
align_num = -1;
} else {
align_flag += 1;
new_map[align_flag * 4 + j] = map[i * 4 + j];
align_num = map[i * 4 + j];
}
}
}
break;
case STEP_DOWN:
for (int j = 0; j < 4; j++) {
align_num = -1;
align_flag = 4;
for (int i = 3; i >= 0; i--) {
if (map[i * 4 + j] == 0) {
continue;
}
if (map[i * 4 + j] == align_num) {
new_map[align_flag * 4 + j] += map[i * 4 + j];
align_num = -1;
} else {
align_flag -= 1;
new_map[align_flag * 4 + j] = map[i * 4 + j];
align_num = map[i * 4 + j];
}
}
}
break;
case STEP_LEFT:
for (int i = 0; i < 4; i++) {
align_num = -1;
align_flag = -1;
for (int j = 0; j < 4; j++) {
if (map[i * 4 + j] == 0) {
continue;
}
if (map[i * 4 + j] == align_num) {
new_map[i * 4 + align_flag] += map[i * 4 + j];
align_num = -1;
} else {
align_flag += 1;
new_map[i * 4 + align_flag] = map[i * 4 + j];
align_num = map[i * 4 + j];
}
}
}
break;
case STEP_RIGHT:
for (int i = 0; i < 4; i++) {
align_num = -1;
align_flag = 4;
for (int j = 3; j >= 0; j--) {
if (map[i * 4 + j] == 0) {
continue;
}
if (map[i * 4 + j] == align_num) {
new_map[i * 4 + align_flag] += map[i * 4 + j];
align_num = -1;
} else {
align_flag -= 1;
new_map[i * 4 + align_flag] = map[i * 4 + j];
align_num = map[i * 4 + j];
}
}
}
break;
default:
printf("step error, unkown step!\n");
free(new_map);
return false;
}
int max_pos = -1;
int max_value = -1;
int rdm_num = rand() % 2 + 1;
bool changed = false;
for (int i = 0; i < 16; i++)
{
if (new_map[i] == 0)
{
int rdm = rand();
if (rdm > max_value)
{
max_value = rdm;
max_pos = i;
}
}
if (new_map[i] != map[i])
{
changed = true;
}
}
if (!changed)
{
free(new_map);
PrintMap(-1);
return true;
}
if (max_pos == -1)
{
printf("game is over!\n");
free(new_map);
return false;
}
rdm_num = pow(2, rdm_num);
new_map[max_pos] = rdm_num;
history_steps.push_back(map);
while (history_steps.size() > 100)
{
history_steps.pop_front();
}
map = new_map;
step_counter++;
PrintMap(max_pos);
return true;
}
bool G2048::BackStep()
{
if (history_steps.size() == 0)
{
printf("back error, no history steps!\n");
return false;
}
free(map);
map = history_steps.back();
history_steps.pop_back();
step_counter--;
PrintMap(-1);
return true;
}
void G2048::PrintMap(int pos)
{
printf("step %u:\n", step_counter);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (pos == i * 4 + j)
{
printf(" *%u", map[i * 4 + j]);
} else {
printf("%8u", map[i * 4 + j]);
}
}
printf("\n");
}
}
void G2048::FreeSteps()
{
while (history_steps.size() > 0) {
unsigned int* step = history_steps.front();
free(step);
history_steps.pop_front();
}
if (nullptr != map) {
free(map);
map = nullptr;
}
step_counter = 0;
}
main函数:
#include
#include "game.h"
#ifdef _WIN32
const char * CLEAR_STR = "CLS";
#else
const char * CLEAR_STR = "clear";
#endif
char GetCommand()
{
printf("input char:\n");
printf("w, s, a, d is up, down, left, right\n");
printf("q, r, b is quit, restart, back step\n");
char c = getchar();
char last_c = c;
while ((c = getchar()) != '\n')
{
last_c = c;
}
return last_c;
}
int main(int argc, char ** argv)
{
G2048 game;
game.InitMap();
char c = GetCommand();
while (c != 'q')
{
fflush(stdin);
switch (c) {
case 'w':
system(CLEAR_STR);
game.NextStep(STEP_UP);
break;
case 's':
system(CLEAR_STR);
game.NextStep(STEP_DOWN);
break;
case 'a':
system(CLEAR_STR);
game.NextStep(STEP_LEFT);
break;
case 'd':
system(CLEAR_STR);
game.NextStep(STEP_RIGHT);
break;
case 'r':
printf("confirm restarting the game\n");
c = getchar();
if (c == 'r')
{
game.InitMap();
}
break;
case 'b':
game.BackStep();
break;
default:
break;
}
c = GetCommand();
}
return 0;
}
Makefile:
SRC=$(wildcard *.cpp)
OBJS=$(patsubst %.cpp, %.o, $(SRC))
TARGET=test
$(TARGET):$(OBJS)
g++ $(OBJS) -o $(TARGET)
%.o:%.cpp
g++ -c $< -o $@
.PHONY:clean
clean:
rm -rf $(OBJS) $(TARGET)
执行test即可。