- C20250069's blog
You see
- 2023-5-15 15:41:57 @
一个简单的按键小游戏。
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;
}