一个简单的按键小游戏。 1 ~ 0 转移,q ~ p 升级,a ~ l 加多。 支持 Linux, Windows 等主流操作系统。 c++ 14+

#include <iostream>
#include <vector>
#include <thread>
#include <ctime>
#include <iomanip>

#if !(defined(__WINDOWS_) || defined(_WIN32))
#include <sys/select.h>
#else
#include <windows.h>
#endif

using namespace std;

#if !(defined(__WINDOWS_) || defined(_WIN32))
static void Sleep(unsigned int ms)
{
    timeval tval;
    tval.tv_sec = ms / 1000;
    tval.tv_usec = ms % 1000 * 1000;
    select(0, NULL, NULL, NULL, &tval);
}
#endif

static void System_Clear()
{
    system(
#if !(defined(__WINDOWS_) || defined(_WIN32))
        "clear"
#else
        "cls"
#endif
    );
}

class Game
{
public:
    int fps = 10;
    int on;
    thread *cvr;
    thread *lis;
    int dt = 0;
    int KEY_DOWN_VALUE = 0;
    static void update(Game *_this, function<bool(Game *, int, int)> cb, int tid, int *dt, int *KEY_DOWN_VALUE)
    {
        if (tid == 0)
        {
            while (_this->on)
            {
                (*dt)++;
                if (cb(_this, *dt, *KEY_DOWN_VALUE))
                {
                    _this->render(*dt, *KEY_DOWN_VALUE);
                    Sleep(1000 / _this->fps);
                }
                else
                {
                    throw "Error";
                }
            }
        }
        else if (tid == 1)
        {
            while (_this->on)
            {
                *KEY_DOWN_VALUE = '\0';
                char ch = getchar();
                if (31 < ch && ch < 127)
                {
                    *KEY_DOWN_VALUE = ch;
                }
                Sleep(1000 / _this->fps);
            }
        }
    }
    static bool ender(Game &cv, int *dt, int *KEY_DOWN_VALUE)
    {
        return true;
    }
    void render(int dt, int KEY_DOWN_VALUE)
    {
        System_Clear();
        cout << "frame " << dt << endl;
        cout << 1 << "(x" << setprecision(4) << setw(12) << this->multiplier[0] << "): " << setprecision(6) << setw(14) << this->cv[0] << " (" << setprecision(6) << setw(12) << this->multier[0] << " to upgrade)" << endl;
        for (int i = 1; i < 9; i++)
        {
            cout << i + 1 << "(x" << setprecision(4) << setw(12) << this->multiplier[i] << "): " << setprecision(6) << setw(14) << this->cv[i] << " (" << setprecision(6) << setw(12) << this->multier[i] << " to upgrade)"
                 << " (" << setprecision(6) << setw(12) << this->byer[i - 1] << " to add more)" << endl;
        }
        cout << 10 << "(x" << setprecision(4) << setw(12) << this->multiplier[9] << "): " << setprecision(6) << setw(13) << this->cv[9] << " (" << setprecision(6) << setw(12) << this->multier[9] << " to upgrade)"
             << " (" << setprecision(6) << setw(12) << this->byer[8] << " to add more)" << endl;
        if (KEY_DOWN_VALUE)
        {
            cout << KEY_DOWN_VALUE << endl;
        }
    }

    // public:
    vector<long double> cv;
    vector<long double> multiplier;
    vector<long double> adder;
    vector<long double> remainer;
    vector<long double> multier;
    vector<long double> byer;

    Game()
    {
        for (int i = 0; i < 10; i++)
        {
            multiplier.push_back(1.002);
            multier.push_back(4 * (i + 1));
        }
        for (int i = 1; i < 10; i++)
        {
            adder.push_back(0.001);
            remainer.push_back(0.01);
            byer.push_back(5 * (i + 1));
        }
        clear();
    }
    Game clear()
    {
        cv.clear();
        cv.push_back(1);
        for (int i = 1; i < 10; i++)
        {
            cv.push_back(0);
        }
        return *this;
    }
    Game setFps(int f)
    {
        fps = f;
        return *this;
    }
    Game start(function<bool(Game *, int, int)> cb)
    {
        cout << "starting." << endl;
        on = 1;
        thread t(update, this, cb, 0, &dt, &KEY_DOWN_VALUE);
        thread k(update, this, cb, 1, &dt, &KEY_DOWN_VALUE);
        cvr = &t;
        lis = &k;
        t.detach();
        k.detach();
        cout << "started." << endl;
        return *this;
    }
    Game end(function<bool(Game &, int *, int *)> cb = ender)
    {
        on = 0;
        if (cb(*this, &dt, &KEY_DOWN_VALUE))
        {
            return *this;
        }
        throw "Error";
    }
};

bool cb(Game *cv, int dt, int value)
{
    for (int i = 0; i < 10; i++)
    {
        cv->cv[i] *= cv->multiplier[i];
    }
    if (value)
    {
        if ('1' <= value && value <= '9')
        {
            cv->cv[value - '0'] += cv->cv[value - '1'] * cv->adder[value - '1'];
            cv->cv[value - '1'] *= cv->remainer[value - '1'];
        }
        else
        {
            switch (value)
            {
            case 'q':
                if (cv->cv[0] >= cv->multier[0])
                {
                    cv->cv[0] -= cv->multier[0];
                    cv->multiplier[0] *= 1.0002;
                    cv->multier[0] *= cv->multier[0] / 3;
                }
                break;
            case 'w':
                if (cv->cv[1] >= cv->multier[1])
                {
                    cv->cv[1] -= cv->multier[1];
                    cv->multiplier[1] *= 1.0004;
                    cv->multier[1] *= cv->multier[1] / 3;
                }
                break;
            case 'e':
                if (cv->cv[2] >= cv->multier[2])
                {
                    cv->cv[2] -= cv->multier[2];
                    cv->multiplier[2] *= 1.0006;
                    cv->multier[2] *= cv->multier[2] / 2.5;
                }
                break;
            case 'r':
                if (cv->cv[3] >= cv->multier[3])
                {
                    cv->cv[3] -= cv->multier[3];
                    cv->multiplier[3] *= 1.0008;
                    cv->multier[3] *= cv->multier[3] / 2.25;
                }
                break;
            case 't':
                if (cv->cv[4] >= cv->multier[4])
                {
                    cv->cv[4] -= cv->multier[4];
                    cv->multiplier[4] *= 1.001;
                    cv->multier[4] *= cv->multier[4] / 2;
                }
                break;
            case 'y':
                if (cv->cv[5] >= cv->multier[5])
                {
                    cv->cv[5] -= cv->multier[5];
                    cv->multiplier[5] *= 1.0015;
                    cv->multier[5] *= cv->multier[5] / 1.25;
                }
                break;
            case 'u':
                if (cv->cv[6] >= cv->multier[6])
                {
                    cv->cv[6] -= cv->multier[6];
                    cv->multiplier[6] *= 1.002;
                    cv->multier[6] *= cv->multier[6];
                }
                break;
            case 'i':
                if (cv->cv[7] >= cv->multier[7])
                {
                    cv->cv[7] -= cv->multier[7];
                    cv->multiplier[7] *= 1.003;
                    cv->multier[7] *= cv->multier[7] * 2;
                }
                break;
            case 'o':
                if (cv->cv[8] >= cv->multier[8])
                {
                    cv->cv[8] -= cv->multier[8];
                    cv->multiplier[8] *= 1.005;
                    cv->multier[8] *= cv->multier[8] * 5;
                }
                break;
            case 'p':
                if (cv->cv[9] >= cv->multier[9])
                {
                    cv->cv[9] -= cv->multier[9];
                    cv->multiplier[9] *= 1.0075;
                    cv->multier[9] *= cv->multier[9] * 10;
                }
                break;
            case 'a':
                if (cv->cv[1] >= cv->byer[0])
                {
                    cv->cv[1] -= cv->byer[0];
                    cv->adder[0] *= 1.01;
                    cv->remainer[0] *= 1.02;
                    cv->byer[0] *= cv->byer[0] / 5;
                }
                break;
            case 's':
                if (cv->cv[2] >= cv->byer[1])
                {
                    cv->cv[2] -= cv->byer[1];
                    cv->adder[1] *= 1.02;
                    cv->remainer[1] *= 1.035;
                    cv->byer[1] *= cv->byer[1] / 4.5;
                }
                break;
            case 'd':
                if (cv->cv[3] >= cv->byer[2])
                {
                    cv->cv[3] -= cv->byer[2];
                    cv->adder[2] *= 1.035;
                    cv->remainer[2] *= 1.05;
                    cv->byer[2] *= cv->byer[2] / 4;
                }
                break;
            case 'f':
                if (cv->cv[4] >= cv->byer[3])
                {
                    cv->cv[4] -= cv->byer[3];
                    cv->adder[3] *= 1.05;
                    cv->remainer[3] *= 1.075;
                    cv->byer[3] *= cv->byer[3] / 3.5;
                }
                break;
            case 'g':
                if (cv->cv[5] >= cv->byer[4])
                {
                    cv->cv[5] -= cv->byer[4];
                    cv->adder[4] *= 1.075;
                    cv->remainer[4] *= 1.1;
                    cv->byer[4] *= cv->byer[4] / 3;
                }
                break;
            case 'h':
                if (cv->cv[6] >= cv->byer[5])
                {
                    cv->cv[6] -= cv->byer[5];
                    cv->adder[5] *= 1.1;
                    cv->remainer[5] *= 1.15;
                    cv->byer[5] *= cv->byer[5] / 2.5;
                }
                break;
            case 'j':
                if (cv->cv[7] >= cv->byer[6])
                {
                    cv->cv[7] -= cv->byer[6];
                    cv->adder[6] *= 1.15;
                    cv->remainer[6] *= 1.225;
                    cv->byer[6] *= cv->byer[6] / 2;
                }
                break;
            case 'k':
                if (cv->cv[8] >= cv->byer[7])
                {
                    cv->cv[8] -= cv->byer[7];
                    cv->adder[7] *= 1.225;
                    cv->remainer[7] *= 1.5;
                    cv->byer[7] *= cv->byer[7] / 1.5;
                }
                break;
            case 'l':
                if (cv->cv[9] >= cv->byer[8])
                {
                    cv->cv[9] -= cv->byer[8];
                    cv->adder[8] *= 1.5;
                    cv->remainer[8] *= 1.75;
                    cv->byer[8] *= cv->byer[8];
                }
                break;

            default:
                break;
            }
        }
    }
    return true;
}

bool ender(Game cv, int *dt, int *KEY_DOWN_VALUE)
{
    System_Clear();
    cout << "You used " << *dt << " frames to reach 1000!" << endl;
    return true;
}

int main()
{
    cin.tie(0);
    cout.tie(0);
    Game g;
    System_Clear();
    cout << "Getting Numbers." << endl;
    getchar();
    g.setFps(24);
    g.start(cb);
    while (g.cv[9] <= 100000000.0L)
    {
        continue;
    }
    g.end(ender);
    return 0;
}