我做了一个贪吃蛇游戏
OrangeCitrus · · 个人记录
rt
!!!请读完这几句话!!!
编译之前请选择适合自己(与自己系统)的
建议不要更改已经预设好的
如果有bug,那就将成为特性,我不会再更改了
提示:
- 在基本所有界面上
[Esc] 键都可以起作用 - 一开始先看一看
EsZy 难度(我知道是EaSy) - 在开始前可以使用
[W][A][S][D] 调整设置
玩法:(游戏内也有提示)
- 贪吃蛇怎么玩这个就怎么玩
- 游玩时使用
[W][A][S][D] 操控 -
#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include <conio.h>
#include <windows.h>
#include <random>
#include <atomic>
#include <mutex>
using namespace std;
// 是那个神经写代码用英文ui呀,偶是我这个苕呀~
// 如果icon只有占了一个格子,请按需修改
// 建议的icon注释在后面了
// 原来中的中文字符(Simplified Chinese)是所有系统通用的(没错,win10以前、win10和win11特殊字符不通用)
// 请确保icon占两个字符(显示,不是占用空间)
// 如果看不懂上面文字中的意思,不是你理解的问题,是我脑子的问题(
// Icon (before win10) (windows旧版命令提示符(开中文输入法之后下面有一行小字的))
//#define HEAD R"(●)"
//#define BODY R"(○)"
//#define WALL R"(▓)"
//#define DOORNM R"(☆)"
//#define DOORHL R"(★)"
//#define COIN R"(Θ)"
// Icon (win10) (windows命令提示符)
//#define HEAD R"(●)"
//#define BODY R"(○)"
//#define WALL R"(▓ )"
//#define DOORNM R"(☆)"
//#define DOORHL R"(★)"
//#define COIN R"(Θ)"
// Icon (win11) (Windows terminal(带标签页的))
//#define HEAD R"(@@)"
//#define BODY R"(〇)"
//#define WALL R"(▓▓)"
//#define DOORNM R"([])"
//#define DOORHL R"(%%)"
//#define COIN R"(币)"
// Icon ("Simplified Chinese")
#define HEAD R"(头)"
#define BODY R"(身)"
#define WALL R"(墙)"
#define DOORNM R"(门)"
#define DOORHL R"(闫)"
#define COIN R"(币)"
#define ARROWUP R"(/\)" // (↑)
#define ARROWLF R"(< )" // (←)
#define ARROWDN R"(\/)" // (↓)
#define ARROWRT R"( >)" // (→)
#define BLANK R"( )"
// Size: DO NOT change the Minimum value, or display may crash
#define MINIR 15
#define MINIC 15
#define DFTR 20
#define DFTC 20
#define MIDR 30
#define MIDC 40
#define MAXR 40
#define MAXC 60
// Setting Sort: EZ -> HD -> IN -> SP
// Wall: control walls' density (per block)
const double WALLST[10] = {2.0/40, 4.0/40, 6.0/40, 3.0/40};
// Coin: control coins' density (per block)
const double COINST[10] = {1.0/40, 1.0/60, 1.0/100, 1.0/40};
// Target: the target you need to get for the win of the game
const int TARGETST[10] = {20, 20, 20, -1};// val -1 means that it will change with the size of the screen
// RSpeed: control wait time that will wait after a single step and after "3,2,1,GO" (val*4)
const int RSPEEDST[10] = {200, 180, 160, 180};
// HP: if 0, you will dead immediately after knock the wall or body
const int HPST[10] = {3, 2, 2, 2};
// Len: starting lenth
const int LENST[10] = {3, 3, 3, int(1e9)};
// Special Number
#define KEYESC 27
atomic <int> Mode(2);
atomic <double> WALLDENSITY, COINDENSITY; // Some Settings
atomic <int> TARGET, RSPEED, HP, STARTLEN; // Some Settings
atomic <int> R, C; // map size
atomic <int> animationSpeed; // Animation speed (1~4)
string DOOR = DOORNM; // Door Pattern
string mp[205][205]; // map for display
atomic <int> dirI; // direction (1~4 with dir[dirI][])
atomic <int> screenSize; // Screen Size Level (1~4)
int nx, ny, rp; // position & score
atomic <bool> gameContinue(true), exitSignal(false), pauseSignal(false);
atomic <int> dirChange; // if direction change (1~10)
const int dir[4][2] = {-1, 0, 0, -1, 1, 0, 0, 1}; // direction
atomic <int> winR, winC; // window's Size
atomic <bool> showResizeTipsKill(false); // if this thread should be killed
atomic <bool> exitRightNow(false);// Back to menu Right Now
mutex mpLock, kbInp; // 声明一个互斥锁
vector< pair<int, int> > v;// snack's body position
void waitfor(long long t) {
this_thread::sleep_for(chrono::milliseconds(t));
}
void anWait(int TOT, int i) {
switch (animationSpeed) {
case 1: waitfor(pow(abs((TOT*9/20.0-i+1)/(TOT*9/80.0)), 3)+10); break;
case 2: waitfor(pow(abs((TOT*4/10.0-i+1)/(TOT*4/55.0)), 2)+10); break;
case 3: waitfor(pow(abs((TOT*4/10.0-i+1)/(TOT*4/40.0)), 2)+10); break;
case 4: waitfor(1); break;
}
}
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
int getRand(int s, int t) {
if(s > t) swap(s, t);
return (rnd() % (t - s + 1)) + s;
}
void cmdGoto(int x,int y) {
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = y*2, pos.Y = x;
SetConsoleCursorPosition(handle,pos);
}
void getConsoleSize(int& columns, int& rows) {
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) {
rows = csbi.srWindow.Right - csbi.srWindow.Left + 1;
rows /= 2;
columns = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
} else {
columns = 0;
rows = 0;
}
}
void showResizeTips() {
// 预处理Tips
string tmp = "";
const int line = 3;
string words[line] = {"Please resize(enlarge) the window", "until the box can be fully displayed", "请放大窗口"};
for(int j=0;j<=C+17;j++) {
tmp += WALL;
}
tmp += "\n";
for(int i=1;i<=R+2;i++) {
tmp += WALL;
for(int j=1;j<=C+16;j++) {
tmp += BLANK;
}
tmp += WALL;
tmp += "\n";
}
for(int j=0;j<=C+17;j++) {
tmp += WALL;
}
tmp += "\n";
while(!showResizeTipsKill) {
system("cls");
cout << tmp;
for(int i=1;i<=line;i++) {
cmdGoto(i, 1);
cout << words[i - 1];
}
for(int i=1;i<=5;i++) {
if(showResizeTipsKill) {
break;
}
waitfor(100);
}
}
showResizeTipsKill = 0;
}
void keepWindow() {
do {
// 隐藏cmd光标
CONSOLE_CURSOR_INFO cursor_info = {1, 0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
// 撤销cmd快速编辑模式
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
GetConsoleMode(handle, &mode);
mode &= ~ENABLE_QUICK_EDIT_MODE; // 移除快速编辑模式
mode &= ~ENABLE_INSERT_MODE; // 移除插入模式
mode &= ~ENABLE_MOUSE_INPUT;
SetConsoleMode(handle, mode);
// 检测窗口大小
int r, c;
getConsoleSize(r, c);
winR = r, winC = c;
// 窗口过小提醒
if(R + 3 > winR || C + 17 > winC) {
lock_guard<mutex> guard(mpLock);
thread thShow(showResizeTips);
while(R + 3 > winR || C + 17 > winC) {
waitfor(10);
int r, c;
getConsoleSize(r, c);
winR = r, winC = c;
}
showResizeTipsKill = 1;
thShow.join();
system("cls");
}
waitfor(50);
} while(!exitSignal);
}
void flick(int x, int y, string things) {
do {
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
if(mp[x][y] == BLANK) mp[x][y] = things;
else if(mp[x][y] == things) mp[x][y] = BLANK;}
for(int i=1;i<=5;i++) {
if(gameContinue || exitSignal) return;
waitfor(100);
}
} while(!gameContinue && !exitSignal);
}
bool fail(int ex, int ey, string things) {
bool returnVal;
const int CC = 13;
thread th;
{lock_guard<mutex> guard(kbInp);
gameContinue = 0;
if(ex != -1 && ey != -1)
th = thread(flick, ex, ey, things);
string tmp[7];
tmp[1] = "--------------------------";//13
tmp[2] = " GAME OVER :( ";
tmp[3] = " Press [R] to restart ";
tmp[4] = " Press [Esc] to exit ";
tmp[5] = "--------------------------";
string tmpBk[6] = {"", "+", "|", "|", "|", "+"};
string tmpFt[6] = {"", " +", " |", " |", " |", " +"};
for(int i=1;i<=5;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+3] = tmpBk[i];
}
for(int j=1;j<=CC;j++) {
anWait(CC+1, j);
lock_guard<mutex> guard(mpLock); // 使用互斥锁
for(int i=1;i<=5;i++)
mp[i][C+2] = tmp[i].substr(max(int(tmp[i].size()-j*2), 0));
}
anWait(CC+1, CC+1);
for(int i=1;i<=5;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+2] = tmpFt[i] + mp[i][C+2];
}
waitfor(100);
again:
switch(getch()) {
case 'r': returnVal = 0; break;
case KEYESC: returnVal = 1; break;
default: goto again; break;
}}
gameContinue = 1;
for(int i=1;i<=5;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+2] = mp[i][C+2].substr(2);
mp[i][C+3] += " ";
}
for(int j=1;j<=CC;j++) {
anWait(CC+1, j);
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[1][C+2] = mp[1][C+2].substr(2);
for(int i=2;i<=4;i++)
mp[i][C+2] = mp[i][C+2].substr(2);
mp[5][C+2] = mp[5][C+2].substr(2);
for(int i=1;i<=5;i++)
mp[i][C+3] += " ";
}
anWait(CC+1, CC+1);
for(int i=1;i<=5;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+3] = " ";
mp[i][C+2] = "";
}
waitfor(100);
if (th.joinable()) th.join();
if(returnVal) {
for(int j=0;j<=C+1;j++) {
if(j != 0)
anWait(C+6, j);
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
for(int i=0;i<=R+1;i++) {
mp[i][j] = "";
if(j <= 4) {
mp[i][C+2] += " ";
}
}}
}
for(int j=1;j<=5;j++) {
anWait(C+6, C+1+j);
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
for(int i=0;i<=R+1;i++) {
if(mp[i][C+2].size() > 2) {
mp[i][C+2] = mp[i][C+2].substr(3);
}
else {
mp[i][C+2] = "";
}
}}
}
for(int i=1;i<=5;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+3] = "";
}
}
return returnVal;
}
bool win() {
bool returnVal;
const int CC = 13;
{lock_guard<mutex> guard(kbInp);
gameContinue = 0;
string tmp[7];
tmp[1] = "--------------------------";//13
tmp[2] = " You win!!! :-) ";
switch(Mode) {
case 1: tmp[3] = " In EaZy Mode "; break;
case 2: tmp[3] = " In HarD Mode "; break;
case 3: tmp[3] = " In INsane Mode "; break;
case 4: tmp[3] = " In SPcial Mode "; break;
}
tmp[4] = " Press [R] to restart ";
tmp[5] = " Press [Esc] to exit ";
tmp[6] = "--------------------------";
string tmpBk[7] = {"", "+", "|", "|", "|", "|", "+"};
string tmpFt[7] = {"", " +", " |", " |", " |", " |", " +"};
for(int i=1;i<=6;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+3] = tmpBk[i];
}
for(int j=1;j<=CC;j++) {
anWait(CC+1, j);
lock_guard<mutex> guard(mpLock); // 使用互斥锁
for(int i=1;i<=6;i++)
mp[i][C+2] = tmp[i].substr(max(int(tmp[i].size()-j*2), 0));
}
anWait(CC+1, CC+1);
for(int i=1;i<=6;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+2] = tmpFt[i] + mp[i][C+2];
}
waitfor(100);
again:
switch(getch()) {
case 'r': returnVal = 0; break;
case KEYESC: returnVal = 1; break;
default: goto again; break;
}}
gameContinue = 1;
for(int i=1;i<=6;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+2] = mp[i][C+2].substr(2);
mp[i][C+3] += " ";
}
for(int j=1;j<=CC;j++) {
anWait(CC+1, j);
lock_guard<mutex> guard(mpLock); // 使用互斥锁
for(int i=1;i<=6;i++)
mp[i][C+2] = mp[i][C+2].substr(2);
for(int i=1;i<=6;i++)
mp[i][C+3] += " ";
}
anWait(CC+1, CC+1);
for(int i=1;i<=6;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+3] = " ";
mp[i][C+2] = "";
}
waitfor(100);
if(returnVal) {
for(int j=0;j<=C+1;j++) {
if(j != 0)
anWait(C+6, j);
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
for(int i=0;i<=R+1;i++) {
mp[i][j] = "";
if(j <= 4) {
mp[i][C+2] += " ";
}
}}
}
for(int j=1;j<=6;j++) {
anWait(C+6, C+1+j);
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
for(int i=0;i<=R+1;i++) {
if(mp[i][C+2].size() > 2) {
mp[i][C+2] = mp[i][C+2].substr(3);
}
else {
mp[i][C+2] = "";
}
}}
}
for(int i=1;i<=6;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+3] = "";
}
}
return returnVal;
}
int pause() {
int returnVal;
const int CC = 13;
{lock_guard<mutex> guard(kbInp);
gameContinue = 0;
string tmp[7];
tmp[1] = "--------------------------";//13
tmp[2] = " Game Pause ";
tmp[3] = " Press [E] to continue ";
tmp[4] = " Press [R] to restart ";
tmp[5] = " Press [Esc] to exit ";
tmp[6] = "--------------------------";
string tmpBk[7] = {"", "+", "|", "|", "|", "|", "+"};
string tmpFt[7] = {"", " +", " |", " |", " |", " |", " +"};
for(int i=1;i<=6;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+3] = tmpBk[i];
}
for(int j=1;j<=CC;j++) {
anWait(CC+1, j);
lock_guard<mutex> guard(mpLock); // 使用互斥锁
for(int i=1;i<=6;i++)
mp[i][C+2] = tmp[i].substr(max(int(tmp[i].size()-j*2), 0));
}
anWait(CC+1, CC+1);
for(int i=1;i<=6;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+2] = tmpFt[i] + mp[i][C+2];
}
waitfor(100);
again:
switch(getch()) {
case 'r': returnVal = 0; break;
case 'e': returnVal = -1; break;
case KEYESC: returnVal = 1; break;
default: goto again; break;
}}
gameContinue = 1;
for(int i=1;i<=6;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+2] = mp[i][C+2].substr(2);
mp[i][C+3] += " ";
}
for(int j=1;j<=CC;j++) {
anWait(CC+1, j);
lock_guard<mutex> guard(mpLock); // 使用互斥锁
for(int i=1;i<=6;i++)
mp[i][C+2] = mp[i][C+2].substr(2);
for(int i=1;i<=6;i++)
mp[i][C+3] += " ";
}
anWait(CC+1, CC+1);
for(int i=1;i<=6;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+3] = " ";
mp[i][C+2] = "";
}
waitfor(100);
if(returnVal == 1) {
for(int j=0;j<=C+1;j++) {
if(j != 0)
anWait(C+6, j);
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
for(int i=0;i<=R+1;i++) {
mp[i][j] = "";
if(j <= 4) {
mp[i][C+2] += " ";
}
}}
}
for(int j=1;j<=6;j++) {
anWait(C+6, C+1+j);
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
for(int i=0;i<=R+1;i++) {
if(mp[i][C+2].size() > 2) {
mp[i][C+2] = mp[i][C+2].substr(3);
}
else {
mp[i][C+2] = "";
}
}}
}
for(int i=1;i<=6;i++) {
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][C+3] = "";
}
}
return returnVal;
}
void doorSwitch() {
do{
for(int i=1; i<=9; i++) {
if(exitSignal) break;
waitfor(100);
}
if(DOOR == DOORNM)
DOOR = DOORHL;
else if(DOOR == DOORHL)
DOOR = DOORNM;
} while(!exitSignal);
}
void print() {
do{
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
// system("cls");
string tmp;
for(int i = 0; i <= R + 1; i++) {
for(int j = 0; j <= C + 3; j++) {
if(i == nx + dir[dirI][0] && j == ny + dir[dirI][1] && dirChange) {
switch(dirI) {
case 0: tmp += ARROWUP; break;
case 1: tmp += ARROWLF; break;
case 2: tmp += ARROWDN; break;
case 3: tmp += ARROWRT; break;
}
dirChange--;
continue;
}
if(mp[i][j] == "dr") tmp += DOOR;
else tmp += mp[i][j];
}
if(i == R-7) tmp += " score: ";
if(i == R-6) tmp += " " + to_string(rp) + R"(/)" + to_string(TARGET) + " ";
if(i == R-4) tmp += " tips: ";
if(i == R-3) tmp += " " + string(DOOR) + R"( -> Portals )";
if(i == R-2) tmp += " " + string(COIN) + R"( -> Coins )";
if(i == R-1) tmp += " " + string(WALL) + R"( -> Walls )";
// if(i == R) {
// for(auto i:v) tmp+=to_string(i.first)+":"+to_string(i.second)+" ";
// }// debug
if(R + 1 != i) tmp += "\n";
}
cmdGoto(0, 0);
cout << tmp;}
waitfor(10);
} while(!exitSignal);
}
void kbDetect() {
do{
lock_guard<mutex> guard(kbInp);
if(_kbhit()) {
switch(_getch()) {
case 'w': {
if(v.size() < 2 || make_pair(nx + dir[0][0], ny + dir[0][1]) != v[v.size() - 2]) {
dirI = 0;
dirChange = 10;
}
break;
}
case 'a': {
if(v.size() < 2 || make_pair(nx + dir[1][0], ny + dir[1][1]) != v[v.size() - 2]) {
dirI = 1;
dirChange = 10;
}
break;
}
case 's': {
if(v.size() < 2 || make_pair(nx + dir[2][0], ny + dir[2][1]) != v[v.size() - 2]) {
dirI = 2;
dirChange = 10;
}
break;
}
case 'd': {
if(v.size() < 2 || make_pair(nx + dir[3][0], ny + dir[3][1]) != v[v.size() - 2]) {
dirI = 3;
dirChange = 10;
}
break;
}
case KEYESC: {
pauseSignal = 1;
break;
}
}
}
} while(!exitSignal);
}
void spawnDoor() {
int lx = -1000, ly = -1000;
for(int i=1;i<=2;i++) {
int x, y;
do {
x = getRand(1, R), y = getRand(1, C);
} while((sqrt(pow(lx - x, 2) + pow(ly - y, 2)) < max(R, C) / 2) || mp[x][y] != BLANK || (x >= nx - 3 && x <= nx + 3 && y >= ny - 3 && y <= ny + 3));
lx = x, ly = y;
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[x][y] = "dr";
}
}
void spawnCoin(int t) {
while(t--) {
int x, y;
do {
x = getRand(1, R), y = getRand(1, C);
} while(mp[x][y] != BLANK || (x >= nx - 1 && x <= nx + 1 && y >= ny - 1 && y <= ny + 3));
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[x][y] = COIN;
}
}
int setup() {
int di;
{lock_guard<mutex> guard(kbInp);
dirI = getRand(0, 3);
di = dirI;
rp = 0;
STARTLEN = LENST[Mode - 1];
v.clear();
nx = getRand(3, R-2), ny = getRand(3, C-2);
// 初始化mp
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
for(int i=0;i<=R+1;i++) {
mp[i][C + 1] = WALL;
}}
for(int j=1;j<=C;j++) {
anWait(C+1, j);
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[0][j] = WALL;
for(int i=1;i<=R;i++) {
mp[i][j] = BLANK;
}
mp[R + 1][j] = WALL;
}
anWait(C+1, C+1);
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
for(int i=0;i<=R+1;i++) {
mp[i][0] = WALL;
}}
{lock_guard<mutex> gurad(mpLock);
for(int i=0;i<=R-8;i++){
mp[i][C+2] = " ";
}}
waitfor(500);
{lock_guard<mutex> gurad(mpLock);
for(int i=0;i<=R+1;i++){
mp[i][C+2] = "";
}}}
// 3
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[nx][ny] = HEAD;
v.push_back(make_pair(nx, ny));
mp[nx + dir[di][0]*2][ny + dir[di][1]*2] = "3 ";}
// 一些判断
if(pauseSignal) {
pauseSignal = 0;
switch(pause()) {
case 1: return 1; break;
case 0: return 0; break;
case -1: break;
}
}
if(exitRightNow) {
exitRightNow = false;
return 1;
}
waitfor(RSPEED*5);
// 2
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[nx + dir[di][0]][ny + dir[di][1]] = BLANK;
for(int i = 1; i <= R*C*WALLDENSITY; i++) {
int x, y;
do {
x = getRand(1, R), y = y = getRand(1, C);
} while(mp[x][y] != BLANK || (x >= nx - 1 && x <= nx + 1 && y >= ny - 1 && y <= ny + 3));
mp[x][y] = WALL;
}
mp[nx + dir[di][0]*2][ny + dir[di][1]*2] = "2 ";}
// 一些判断
if(pauseSignal) {
pauseSignal = 0;
switch(pause()) {
case 1: return 1; break;
case 0: return 0; break;
case -1: break;
}
}
if(exitRightNow) {
exitRightNow = false;
return 1;
}
waitfor(RSPEED*4);
// 1
spawnDoor();
spawnCoin(C*R*COINDENSITY);
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[nx + dir[di][0]*2][ny + dir[di][1]*2] = "1 ";}
// 一些判断
if(pauseSignal) {
pauseSignal = 0;
switch(pause()) {
case 1: return 1; break;
case 0: return 0; break;
case -1: break;
}
}
if(exitRightNow) {
exitRightNow = false;
return 1;
}
waitfor(RSPEED*4);
// GO
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[nx + dir[di][0]*2][ny + dir[di][1]*2] = "GO";}
// 一些判断
if(pauseSignal) {
pauseSignal = 0;
switch(pause()) {
case 1: return 1; break;
case 0: return 0; break;
case -1: break;
}
}
if(exitRightNow) {
exitRightNow = false;
return 1;
}
waitfor(RSPEED*4);
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[nx + dir[di][0]*2][ny + dir[di][1]*2] = BLANK;}
if(pauseSignal) {
pauseSignal = 0;
switch(pause()) {
case 1: return 1; break;
case 0: return 0; break;
case -1: break;
}
}
return -1;
}
void menu() {
start:
{lock_guard<mutex> guard(mpLock);
for(int i=0;i<=7;i++) {
mp[i][1] = "";
mp[i][2] = "";
mp[i][3] = "";
}}
{lock_guard<mutex> guard(kbInp); // 使用互斥锁
int j = 2;
{lock_guard<mutex> guard(mpLock);
mp[0][2] = " Menu: >Start< MapSize Animation About ";
mp[2][2] = "Choose your difficulty:";
mp[3][2] = " EaZy";
mp[4][2] = " HarD";
mp[5][2] = " INsane";
mp[6][2] = " SPcial";
mp[7][2] = "(Press [E] to start)";}
char ch = 0;
while(1) {
switch(ch) {
case 's': {
j += (j > 3) ? 0 : 1;
break;
}
case 'w': {
j -= (j < 2) ? 0 : 1;
break;
}
case 'a': {
break;
}
case 'd': {
goto MapSize;
break;
}
case KEYESC: {
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
cmdGoto(winR/2-3, winC/2-4);
puts("/------------------\\");
cmdGoto(winR/2-2, winC/2-4);
puts("| Ready to Exit? |");
cmdGoto(winR/2-1, winC/2-4);
puts("+--------+---------+");
cmdGoto(winR/2, winC/2-4);
puts("| [E]Yes | [Esc]No |");
cmdGoto(winR/2+1, winC/2-4);
puts("\\--------+---------/");
ch = 0;
while(1) {
switch(ch) {
case KEYESC: {
goto nxt;
}
case 'e': {
exitSignal = 1;
system("cls");
exit(0);
}
}
ch = getch();
}
nxt:
cmdGoto(winR/2-3, winC/2-4);
puts(" ");
cmdGoto(winR/2-2, winC/2-4);
puts(" ");
cmdGoto(winR/2-1, winC/2-4);
puts(" ");
cmdGoto(winR/2, winC/2-4);
puts(" ");
cmdGoto(winR/2+1, winC/2-4);
puts(" ");
}
break;
}
case 'e': {
Mode = j;
return;
break;
}
}
COINDENSITY = COINST[j-1];
WALLDENSITY = WALLST[j-1];
RSPEED = RSPEEDST[j-1];
TARGET = TARGETST[j-1];
STARTLEN = LENST[j-1];
HP = HPST[j-1];
if(TARGET == -1) {
TARGET = R*C/15;
}
{lock_guard<mutex> guard(mpLock);
for(int i=1;i<=7;i++) mp[i][1] = " ", mp[i][3] = " ";
mp[j+2][1] = " -> ";}
ch = getch();
}}
MapSize:
{lock_guard<mutex> guard(mpLock);
for(int i=0;i<=7;i++) {
mp[i][1] = "";
mp[i][2] = "";
mp[i][3] = "";
}}
{lock_guard<mutex> guard(kbInp); // 使用互斥锁
int k = screenSize;
{lock_guard<mutex> guard(mpLock);
mp[0][2] = " Menu: Start >MapSize< Animation About ";
mp[2][2] = "Choose your size of map:";
mp[3][2] = " Minimum";
mp[4][2] = " Default";
mp[5][2] = " Midium";
mp[6][2] = " Maximum";
mp[7][2] = "(Press [E] to set)";}
char ch = 0;
while(1) {
switch(ch) {
case 's': {
k += (k > 3) ? 0 : 1;
break;
}
case 'w': {
k -= (k < 2) ? 0 : 1;
break;
}
case 'a': {
goto start;
break;
}
case 'd': {
goto animation;
break;
}
case KEYESC: {
goto start;
}
case 'e': {
lock_guard<mutex> guard(mpLock);
if(screenSize != k) {
system("cls");
}
screenSize = k;
switch(screenSize) {
case 1: R = MINIR, C = MINIC; break;
case 2: R = DFTR, C = DFTC; break;
case 3: R = MIDR, C = MIDC; break;
case 4: R = MAXR, C = MAXC; break;
}
break;
}
}
{lock_guard<mutex> guard(mpLock);
for(int i=1;i<=7;i++) mp[i][1] = " ", mp[i][3] = " ";
mp[k+2][1] = " -> ";
mp[screenSize+2][3] = " <- now ";}
ch = getch();
}}
animation:
{lock_guard<mutex> guard(mpLock);
for(int i=0;i<=7;i++) {
mp[i][1] = "";
mp[i][2] = "";
mp[i][3] = "";
}}
{lock_guard<mutex> guard(kbInp); // 使用互斥锁
int k = animationSpeed;
{lock_guard<mutex> guard(mpLock);
mp[0][2] = " Menu: Start MapSize >Animation< About ";
mp[2][2] = "Choose animation speed:";
mp[3][2] = " Smooth";
mp[4][2] = " Default";
mp[5][2] = " Fast";
mp[6][2] = " Very Fast";
mp[7][2] = "(Press [E] to set)";}
char ch = 0;
while(1) {
switch(ch) {
case 's': {
k += (k > 3) ? 0 : 1;
break;
}
case 'w': {
k -= (k < 2) ? 0 : 1;
break;
}
case 'a': {
goto MapSize;
break;
}
case 'd': {
goto about;
break;
}
case KEYESC: {
goto start;
}
case 'e': {
animationSpeed = k;
break;
}
}
{lock_guard<mutex> guard(mpLock);
for(int i=1;i<=7;i++) mp[i][1] = " ", mp[i][3] = " ";
mp[k+2][1] = " -> ";
mp[animationSpeed+2][3] = " <- now ";}
ch = getch();
}}
about:
{lock_guard<mutex> guard(mpLock);
for(int i=0;i<=7;i++) {
mp[i][1] = "";
mp[i][2] = "";
mp[i][3] = "";
}}
{lock_guard<mutex> guard(kbInp); // 使用互斥锁
{lock_guard<mutex> guard(mpLock);
mp[0][2] = " Menu: Start MapSize Animation >About< ";
mp[2][2] = "Creat by OrangeCitrus";
mp[3][2] = "由橙子味的柑橘制作";
mp[4][2] = "为什么要用英文?因为我有病(";
mp[5][2] = R"( /|_/| )";
mp[6][2] = R"(|\_ | . .| )";
mp[7][2] = R"(|__] \ ^ \ )";}
char ch = 0;
while(1) {
switch(ch) {
case 's': {
break;
}
case 'w': {
break;
}
case 'a': {
goto animation;
break;
}
case 'd': {
break;
}
case KEYESC: {
goto start;
}
case 'e': {
break;
}
}
{lock_guard<mutex> guard(mpLock);
for(int i=1;i<=7;i++) mp[i][1] = " ", mp[i][3] = " ";}
ch = getch();
}}
}
int main() {
system("cls");
cmdGoto(0, 0);
screenSize = 2;
animationSpeed = 2;
R = 20, C = 20;
nx = R/2, ny = C/2;
// system((string("mode con cols=") + to_string(winC * 2) + string(" lines=") + to_string(winR)).c_str());
thread(keepWindow).detach();
thread(doorSwitch).detach();
thread(print).detach();
thread(kbDetect).detach();
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[6][0] = "\tPress any key to get start.";
mp[3][0] = "\tuse [W]/[A]/[S]/[D] to move,";
mp[4][0] = "\t[Esc]/[E] to Quit/Enter.";}
{lock_guard<mutex> guard(kbInp);
getch();}
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[6][0] = "";
mp[3][0] = "";
mp[4][0] = "";}
// 设置
menu:
menu();
{lock_guard<mutex> guard(mpLock);
for(int i=0;i<=7;i++) {
mp[i][1] = "";
mp[i][2] = "";
mp[i][3] = "";
}}
// 开始主程序
again:
switch(setup()) {
case 1: goto menu; break;
case 0: goto again; break;
case -1: break;
}
int hp = HP;
do {
int tx = nx + dir[dirI][0], ty = ny + dir[dirI][1];
if(tx > R || tx < 1 || ty > C || ty < 1) {
if(!hp) {
if(fail(tx, ty, mp[tx][ty]))
goto menu;
else
goto again;
}
hp--;
goto stay;
}
// 下一个是DOOR
if(mp[tx][ty] == "dr") {
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[tx][ty] = BLANK;}
for(int i = 1; i <= R; i++)
for(int j = 1; j <= C; j++)
if(mp[i][j] == "dr") {
tx = i, ty = j;
nx = tx, ny = ty;
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[i][j] = DOORNM;}
for(int k=15;k>=1;k--) {
waitfor(k*10);
lock_guard<mutex> guard(mpLock); // 使用互斥锁
if(mp[i][j] == DOORNM)
mp[i][j] = DOORHL;
else if(mp[i][j] == DOORHL)
mp[i][j] = DOORNM;
}
spawnDoor();
lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[v[0].first][v[0].second] = BLANK;
v.erase(v.begin());
goto nxt;
}
}
//下一个是COIN
else if(mp[tx][ty] == COIN) {
rp++;
spawnCoin(1);
goto nxt;
}
//下一个是WALL/BODY/HEAD
else if(mp[tx][ty] == WALL || mp[tx][ty] == BODY || mp[tx][ty] == HEAD) {
if(!hp) {
if(fail(tx, ty, mp[tx][ty]))
goto menu;
else
goto again;
}
hp--;
goto stay;
}
if(STARTLEN) {
STARTLEN--;
goto nxt;
}
// 删除蛇末尾
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[v[0].first][v[0].second] = BLANK;}
v.erase(v.begin());
// 蛇向前进
nxt:
v.push_back(make_pair(tx, ty));
{lock_guard<mutex> guard(mpLock); // 使用互斥锁
mp[v[v.size() - 2].first][v[v.size() - 2].second] = BODY;
nx = tx, ny = ty;
mp[tx][ty] = HEAD;}
hp = HP;
// 等待
stay:
// 是否暂停
if(pauseSignal) {
pauseSignal = 0;
switch(pause()) {
case 1: goto menu; break;
case 0: goto again; break;
case -1: break;
}
}
// 是否强制退出
if(exitRightNow) {
exitRightNow = false;
goto menu;
}
waitfor(RSPEED);
} while(rp < TARGET);
if(win())
goto menu;
else
goto again;
return 0;
}
感谢游玩。
改自某位dalao10分钟写的小游戏
11.3 update
能且仅能使用c++11编译
编译命令加入-std=c++11
(是谁之前说要用c++14来着的...)