回合制贪吃蛇

目录

一,回合制贪吃蛇

1,基本功能(代码1)

2,运行效果

3,记谱(代码2)

4,读谱(代码3)

5,霸屏

二,霸屏的遗忘算法

1,哈密顿回路

2,基于回路的遗忘算法


一,回合制贪吃蛇

其实贪吃蛇本就是回合制,只是每个回合的时候大概只有0.3秒。

我这里把时间改成不限制,变成真正的回合制。

1,基本功能(代码1)

#include <iostream>
#include <string>
#include <vector>
#include <time.h>
#include <functional>
#include <algorithm>
#include <vector>
#include <queue>
#include <numeric>
#include <map>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <array>
#include <functional>
#include <string.h>
#include <math.h>
#include <fstream>
#include <streambuf>
#include <stdio.h>
#include <mutex>
#include <unordered_map>
#include <iostream>
#include <vector>
#include <iomanip>
#include <string>
#include <algorithm>
#include <cmath>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <functional>
#include <limits>
#include <climits>
#include <stdint.h>
#include <windows.h>

using namespace std;


enum Nod {
    Head,
    Body,
    Apple,
    Empty
};

struct AllInfo {
    vector<vector<Nod>>m;
    int dir = 0;//0上1右2下3左
    deque<pair<int, int>>v;//贪吃蛇头即队列头
    bool dead = false;
};

int ROW = 10;
int COL = 10;
AllInfo g;

void makeApple()
{
    vector<pair<int, int>>s;
    for (int i = 0; i < ROW; i++) {
        for (int j = 0; j < COL; j++) {
            if (g.m[i][j]== Empty)s.push_back({i,j});
        }
    }
    int id = rand() % s.size();
    int r = s[id].first, c = s[id].second;
    g.m[r][c] = Apple;
}
void Init()
{
    g.m.resize(ROW);
    for (auto& v :g.m) {
        v.resize(COL);
        for (auto& x : v)x = Empty;
    }
    g.m[0][0] = Head;
    g.v.push_back({ 0,0 });
    makeApple();
}

void show()
{
    system("cls");
    for (int i = 0; i < ROW; i++) {
        for (int j = 0; j < COL; j++) {
            if (g.m[i][j] == Head)cout << "●";
            else if (g.m[i][j] == Body)cout << "○";
            else if (g.m[i][j] == Apple)cout << "△";
            else if (g.m[i][j] == Empty)cout << "┼";
        }
        cout << endl;
    }
    cout << endl << "请输入运动方向,0上1右2下3左4不变方向" << endl;
}

void moved(int d)
{
    if (d == 4)d = g.dir;
    if (g.dir % 2 != d % 2)g.dir = d;  
    auto p = g.v.front();
    static vector<int> dr = { -1,0,1,0 };
    static vector<int> dc = { 0,1,0,-1 };
    int r = (p.first + dr[g.dir] + ROW) % ROW;
    int c = (p.second + dc[g.dir] + COL) % COL;
    if (g.m[r][c] == Body) {
        g.dead = true;
        return;
    }
    bool needMakeApple = (g.m[r][c] == Apple);
    g.m[p.first][p.second] = Body;
    g.m[r][c] = Head;
    if (needMakeApple) {
        makeApple();
    }
    else {
        p = g.v.back();
        g.m[p.first][p.second] = Empty;
        g.v.pop_back();
    }
    g.v.push_front({ r,c });
}

int main()
{
    Init();
    while (g.v.size() < ROW * COL) {
        show();
        int d;
        cin >> d;
        moved(d);
        if (g.dead) {
            cout << "LOSE!!!";
            return 0;
        }
        if (g.v.size() == ROW * COL) {
            cout << "WIN!!!";
            return 0;
        }
    }
    return 0;
}

2,运行效果

实心圆是蛇头,空心圆是蛇身,三角形是苹果。

4其实就是跳过输入(有时候贪吃蛇玩家不是主动跳过,是反应不过来)

3,记谱(代码2)

#include <iostream>
#include <string>
#include <vector>
#include <time.h>
#include <functional>
#include <algorithm>
#include <vector>
#include <queue>
#include <numeric>
#include <map>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <array>
#include <functional>
#include <string.h>
#include <math.h>
#include <fstream>
#include <streambuf>
#include <stdio.h>
#include <mutex>
#include <unordered_map>
#include <iostream>
#include <vector>
#include <iomanip>
#include <string>
#include <algorithm>
#include <cmath>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <functional>
#include <limits>
#include <climits>
#include <stdint.h>
#include <windows.h>

using namespace std;


#define LOCAL


/*
#include<opencv2/opencv.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/core/mat.hpp>

using namespace cv;


#ifdef NDEBUG
#pragma comment(lib,"../x64/vc14/lib/opencv_world452.lib")
#pragma comment(lib,"../x64/vc14/lib/opencv_world452d.lib")
#else
#pragma comment(lib,"../x64/vc14/lib/opencv_world452d.lib")
#pragma comment(lib,"../x64/vc14/lib/opencv_world452.lib")
#endif

*/

//
//int main()
//{
//    int s = 0;
//    for (int i = 0; i < 10000; i++) {
//        s += getMinTime();
//    }
//    cout << s / 10000;
//    return 0;
//}

//auto img = imread("C:/Users/28024/Downloads/组件/7.jfif", 0);
//cv::resize(img, img,Size(918, 918));
//imwrite("C:/Users/28024/Downloads/组件/new7.png",img);
//cout << img.rows;

//freopen("D:/in.txt", "r", stdin);



enum Nod {
    Head,
    Body,
    Apple,
    Empty
};

struct AllCurrentInfo {
    vector<vector<Nod>>m;
    int dir = 0;//0上1右2下3左
    deque<pair<int, int>>v;//贪吃蛇头即队列头
    bool dead = false;
};
struct HistoryInfo {
    unsigned seed;
    vector<int>dirs;
};

int ROW = 10;
int COL = 10;
unsigned seed = time(NULL);
AllCurrentInfo g;
HistoryInfo h;

void makeApple()
{
    vector<pair<int, int>>s;
    for (int i = 0; i < ROW; i++) {
        for (int j = 0; j < COL; j++) {
            if (g.m[i][j]== Empty)s.push_back({i,j});
        }
    }
    int id = rand() % s.size();
    int r = s[id].first, c = s[id].second;
    g.m[r][c] = Apple;
}
void Init()
{
    g.m.resize(ROW);
    for (auto& v :g.m) {
        v.resize(COL);
        for (auto& x : v)x = Empty;
    }
    g.m[0][0] = Head;
    g.v.push_back({ 0,0 });
    makeApple();
    h.seed = seed;
}

void show()
{
    system("cls");
    for (int i = 0; i < ROW; i++) {
        for (int j = 0; j < COL; j++) {
            if (g.m[i][j] == Head)cout << "●";
            else if (g.m[i][j] == Body)cout << "○";
            else if (g.m[i][j] == Apple)cout << "△";
            else if (g.m[i][j] == Empty)cout << "┼";
        }
        cout << endl;
    }
    cout << endl << "请输入运动方向,0上1右2下3左,4不变方向, 5显示棋谱" << endl;
}

void moved(int d)
{
    h.dirs.push_back(d);
    if (d == 4)d = g.dir;
    if (g.dir % 2 != d % 2)g.dir = d;  
    auto p = g.v.front();
    static vector<int> dr = { -1,0,1,0 };
    static vector<int> dc = { 0,1,0,-1 };
    int r = (p.first + dr[g.dir] + ROW) % ROW;
    int c = (p.second + dc[g.dir] + COL) % COL;
    if (g.m[r][c] == Body) {
        g.dead = true;
        return;
    }
    bool needMakeApple = (g.m[r][c] == Apple);
    g.m[p.first][p.second] = Body;
    g.m[r][c] = Head;
    if (needMakeApple) {
        makeApple();
    }
    else {
        p = g.v.back();
        g.m[p.first][p.second] = Empty;
        g.v.pop_back();
    }
    g.v.push_front({ r,c });
}

int main()
{
    Init();
    while (g.v.size() < ROW * COL) {
        show();
        int d;
        cin >> d;
        if (d == 5) {
            cout << h.seed;
            for (auto d : h.dirs)cout << " " << d;
            Sleep(5000);
        } else {
            moved(d);
            if (g.dead) {
                cout << "LOSE!!!";
                return 0;
            }
            if (g.v.size() == ROW * COL) {
                cout << "WIN!!!";
                return 0;
            }
        }
    }
    return 0;
}

4,读谱(代码3)

#include <iostream>
#include <string>
#include <vector>
#include <time.h>
#include <functional>
#include <algorithm>
#include <vector>
#include <queue>
#include <numeric>
#include <map>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <array>
#include <functional>
#include <string.h>
#include <math.h>
#include <fstream>
#include <streambuf>
#include <stdio.h>
#include <mutex>
#include <unordered_map>
#include <iostream>
#include <vector>
#include <iomanip>
#include <string>
#include <algorithm>
#include <cmath>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <functional>
#include <limits>
#include <climits>
#include <stdint.h>
#include <windows.h>

using namespace std;


#define LOCAL


/*
#include<opencv2/opencv.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/core/mat.hpp>

using namespace cv;


#ifdef NDEBUG
#pragma comment(lib,"../x64/vc14/lib/opencv_world452.lib")
#pragma comment(lib,"../x64/vc14/lib/opencv_world452d.lib")
#else
#pragma comment(lib,"../x64/vc14/lib/opencv_world452d.lib")
#pragma comment(lib,"../x64/vc14/lib/opencv_world452.lib")
#endif

*/

//
//int main()
//{
//    int s = 0;
//    for (int i = 0; i < 10000; i++) {
//        s += getMinTime();
//    }
//    cout << s / 10000;
//    return 0;
//}

//auto img = imread("C:/Users/28024/Downloads/组件/7.jfif", 0);
//cv::resize(img, img,Size(918, 918));
//imwrite("C:/Users/28024/Downloads/组件/new7.png",img);
//cout << img.rows;

//freopen("D:/in.txt", "r", stdin);



enum Nod {
    Head,
    Body,
    Apple,
    Empty
};

struct AllCurrentInfo {
    vector<vector<Nod>>m;
    int dir = 0;//0上1右2下3左
    deque<pair<int, int>>v;//贪吃蛇头即队列头
    bool dead = false;
};
struct HistoryInfo {
    unsigned seed;
    vector<int>dirs;
};

int ROW = 10;
int COL = 10;
unsigned seed = time(NULL);
AllCurrentInfo g;
HistoryInfo h;

void makeApple()
{
    vector<pair<int, int>>s;
    for (int i = 0; i < ROW; i++) {
        for (int j = 0; j < COL; j++) {
            if (g.m[i][j]== Empty)s.push_back({i,j});
        }
    }
    if (s.empty())return;
    int id = rand() % s.size();
    int r = s[id].first, c = s[id].second;
    g.m[r][c] = Apple;
}
void Init()
{
    srand(seed);
    g.m.resize(ROW);
    for (auto& v :g.m) {
        v.resize(COL);
        for (auto& x : v)x = Empty;
    }
    g.m[0][0] = Head;
    g.v.push_back({ 0,0 });
    makeApple();
    h.seed = seed;
}

void show()
{
    system("cls");
    for (int i = 0; i < ROW; i++) {
        for (int j = 0; j < COL; j++) {
            if (g.m[i][j] == Head)cout << "●";
            else if (g.m[i][j] == Body)cout << "○";
            else if (g.m[i][j] == Apple)cout << "△";
            else if (g.m[i][j] == Empty)cout << "┼";
        }
        cout << endl;
    }
    cout << endl << "请输入运动方向,0上1右2下3左,4不变方向, 5显示棋谱" << endl;
}

void moved(int d)
{
    h.dirs.push_back(d);
    if (d == 4)d = g.dir;
    if (g.dir % 2 != d % 2)g.dir = d;  
    auto p = g.v.front();
    static vector<int> dr = { -1,0,1,0 };
    static vector<int> dc = { 0,1,0,-1 };
    int r = (p.first + dr[g.dir] + ROW) % ROW;
    int c = (p.second + dc[g.dir] + COL) % COL;
    if (g.m[r][c] == Body) {
        g.dead = true;
        return;
    }
    bool needMakeApple = (g.m[r][c] == Apple);
    g.m[p.first][p.second] = Body;
    g.m[r][c] = Head;
    if (needMakeApple) {
        makeApple();
    }
    else {
        p = g.v.back();
        g.m[p.first][p.second] = Empty;
        g.v.pop_back();
    }
    g.v.push_front({ r,c });
}

int main()
{
    cin >> seed;
    Init();
    while (g.v.size() < ROW * COL) {
        show();
        int d;
        cin >> d;
        if (d == 5) {
            cout << h.seed;
            for (auto d : h.dirs)cout << " " << d;
            Sleep(5000);
        }
        else if (d >= 0 && d <= 4) {
            moved(d);
            if (g.dead) {
                cout << "LOSE!!!";
                return 0;
            }
            if (g.v.size() == ROW * COL) {
                cout << "WIN!!!";
                return 0;
            }
        }
    }
    return 0;
}

5,霸屏

哪个贪吃蛇玩家没有一个霸屏梦?

需要注意的是,及时识别作茧自缚的陷阱。

比如:

还有:

这2个例子都还没有陷入死局,但是如果直奔着苹果去,把苹果吃了就陷入了死局了。

第一次尝试结果:

到这里卡死了

棋谱:

1748794151 2 2 2 1 1 1 1 1 0 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 0 4 4 4 4 4 4 4 3 3 3 2 2 2 2  2 2 1 1 1 1 1 1 1 0 4 4 4 4 4 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 1 1 1 0 4 4 4 4 4 4 4 4 3 3 2 2 2 2 2 1 1 1 1 1 1 1 2 2 1 1 1 1 1 1 1 0 3 0 0 1 1 0 0 0 3 3 3 3 2 2 2 2 2 2 2 1 1 1 1 0 4 4 3 3 0 4 4 4 4 4 3 3 3 3 0 3 3 0 4 4 4 1 1 1 1 1 1 1 1 1 2 2 2 2 3 0 4 3 3 3 3 3 3 2 2 2 2 2 2 1 1 1 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 3 3 3 3 3 3 0 1 1 1 1 0 3 3 3 3 3 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 0 4 4 4 4 4 4 3 3 3 3 3 3 3 0 1 1 1 1 1 0 3 3 3 3 3 3 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 0 0 1 1 1 1 1 2 2 1 1 2 3 3 3 3 3 3 2 2 3 3 3 3 3 3 3 3 3 2 1 1 1 1 1 1 1 1 2 3 3 3 2 2 2 2 3 0 4 4 3 2 2 2 2 1 1 1 2 3 3 3 3 0 4 4 4 3 3 3 3 2 2 1 1 1 2 2 2 2 1 1 1 1 1 1 1 1 2 3 3 3 3 3 3 3 3 2 1 1 1 1 1 1 2 2 2 2 3 0 4 4 3 3 3 3 3 3 0 3 3 2 2 1 2 2 2 2 3 3 3 3 3 3 3 3 3 0 0 0 0 1 1 1 1 1 2 3 3 3 3 2 2 1 0 1 2 1 1 1 1 1 0 3 3 0 0 0 1 0 4 4 3 2 2 3 3 3 3 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 2 1 2 2 3 2 2 2 1 1 1 1 1 2 3 3 3 3 3 2 1 1 1 1 1 1 1 1 0 0 0 0 0 0 3 2 2 2 2 2 3 0 0 3 3 3 0 1 1 1 0 3 3 3 3 0 1 1 1 1 0 1 1 1 2 1 0 1 1 1 1 1 0 3 3 3 3 3 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 2 3 3 2 2 2 1 1 1 1 1 1 1 1 0 0 0 0 0 3 2 2 2 2 3 0 3 2 3 0 0 1 1 0 0 0 3 2 2 3 0 0 0 3 2 2 3 0 0 3 2 2 3 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 2 2 3 0 3 3 2 2 2 2 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 3 2 2 2 2 2 2 2 3 3 3 3 3 3 0 1 1 1 1 1 0 3 3 0 1 1 0 0 0 0 3 2 2 2 3 0 0 0 3 2 2 3 0 0 3 2 2 3 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 1 0 1 1 1 0 0 3 2 3 0 3 3 3 2 2 2 2 2 3 3 3 3 3 3 3 3 0

第二次尝试结果:

手误

第三次尝试结果:

霸屏成功

棋谱:

1748795253 4 4 4 4 4 4 4 3 3 3 3 3 3 3 0 0 0 1 1 1 1 1 1 2 2 2 3 3 3 3 0 0 3 3 3 0 4 4 1 1 1 1 1 0 0 3 3 3 3 3 0 4 4 4 1 1 1 2 2 2 2 3 3 3 3 3 0 0 1 1 1 1 1 0 1 1 0 4 4 3 3 3 2 3 3 2 2 2 2 2 1 1 2 2 1 2 3 3 3 3 0 4 4 4 4 4 4 4 4 1 2 2 2 2 2 2 2 1 1 1 1 1 1 0 0 3 0 0 0 0 0 0 0 1 1 1 2 2 1 1 1 1 1 1 2 3 3 3 3 3 3 3 2 2 3 3 3 3 0 3 3 3 3 3 2 2 2 2 2 2 1 1 1 1 1 1 2 3 3 3 3 3 3 3 0 0 0 0 0 3 3 3 3 3 3 3 3 0 1 1 1 1 1 1 0 0 3 3 3 3 3 3 3 3 3 0 3 3 3 3 3 3 3 3 3 0 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 1 2 2 2 2 2 2 1 1 1 1 0 0 0 3 0 0 1 1 1 1 0 0 3 3 3 3 3 3 3 3 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 3 0 4 4 4 3 2 2 2 2 3 0 0 0 0 0 0 0 3 3 3 3 3 2 1 1 1 2 2 2 3 0 3 3 3 0 0 0 0 1 1 1 1 1 0 0 0 3 2 3 3 3 3 0 0 0 3 2 2 2 2 2 2 2 2 2 3 3 3 3 0 1 1 0 4 4 4 4 1 0 0 3 3 2 2 2 2 2 3 3 3 3 3 3 2 1 1 1 1 2 3 3 3 3 2 1 1 1 1 2 3 3 3 3 2 1 1 1 1 2 3 3 3 3 2 1 1 1 1 1 0 4 4 4 4 4 1 2 2 2 2 2 2 1 1 1 0 0 0 0 0 0 0 0 0 3 2 2 2 2 2 2 2 2 3 0 0 0 0 0 0 0 0 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 1 1 1 1 1 0 0 0 3 2 2 3 3 3 0 0 0 0 0 0 0 1 1 1 1 1 2 3 3 3 3 2 2 2 2 2 1 0 0 0 0 1 2 2 1 1 2 2 2 2 1 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2 2 2 1 0 4 4 4 4 4 4 4 4 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 1 1 1 1 1 0 3 3 3 3 0 4 4 4 4 4 4 1 1 1 1 1 2 3 3 3 3 2 2 2 2 2 1 1 1 1 2 2 1 1 1 0 3 3 0 1 1 0 3 3 3 3 3 3 0 1 1 1 1 1 1 0 3 3 3 3 3 3 0 1 1 1 1 1 1 0 3 3 0 1 1 0 3 3 3 3 3 3 3 3 3 0 4 4 4 4 4 0 4 4 1 1 1 1 1 1 2 3 3 3 3 3 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 0 3 3 3 3 3 3 3 0 1 1 1 1 1 1 1 0 3 3 3 3 3 3 3 0 1 1 1 1 1 1 1 0 3 3 3 3 3 3 3 0 1 1 1 1 1 1 1 0 0 0 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 2 3 3 3 3 3 3 3 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 0 3 3 3 3 3 3 3 0 1 1 1 1 1 1 1 0 3 3 3 3 3 3 3 0 1 1 1 1 1 1 1 0 3 3 3 3 3 3 3 0 1 1 1 1 1 1 1 0 0 0 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 2 3 3 3 3 3 3 3 2 2 2 2 2

二,霸屏的遗忘算法

针对回合制贪吃蛇,能不能用一个遗忘算法,确保最后能霸屏呢?

1,哈密顿回路

如果ROW*COL是偶数,那很容易构造回路:

如果ROW*COL是奇数,就稍微复杂一点点:

2,基于回路的遗忘算法

只要保持贪吃蛇的蛇头沿着回路运动,最终一定会收尾相接,即霸屏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值