c++摸鱼小游戏,2048的实现

用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即可。

你可能感兴趣的:(c++,开发语言)