搞OI打代码闲暇时间的小作品 2019 / 6 / 11
Windows 10环境下需要将cmd环境改为旧版命令行环境
#include <bits/stdc++.h>
#include <windows.h>
#include <conio.h>
#define N 135
using namespace std;
HANDLE hOut, hIn;
INPUT_RECORD mouseRec;
DWORD res, mode;
//boom_map, opened_map, marked_map
bool bm[N][N], od[N][N], md[N][N];
int im[N][N], mcnt, ocnt;
bool sub_end, fal_end;
int n = 15, boom, blank;
//cursor_position ==> map_position
struct m_pos{ int x, y; } mp;
bool get_mp(COORD *c_pos) {
if(c_pos -> X & 1) {
mp.y = c_pos -> X >> 1;
mp.x = c_pos -> Y - 1;
if(mp.x < n && mp.y < n) return 0;
} return 1;
}
/**
地雷密度::
______初级: 0.12345679
______中级: 0.15625
______高级: 0.20625
*/
const char* difcc[] = {"简单", "中等", "困难"};
const double difity[] = {0.12345679, 0.15625, 0.20625};
int dif = 0; //难度
void cls() {
system("cls");
SetConsoleMode(hIn, mode);
}
void draw(short y, int len, char ch) {
SetConsoleCursorPosition(hOut, COORD{0, y});
printf(" ");
while(len--) putchar(ch);
}
int choose(int num, const char* title, const char* choices[]) {
cls();
printf(" %s:\n\n", title);
for(int i = 0;i < num;i++)
printf(" %s\n\n", choices[i]);
int id = -1, len = 0;
short ly = 0, y = 0;
while(1) {
ReadConsoleInput(hIn, &mouseRec, 1, &res);
y = mouseRec.Event.MouseEvent.dwMousePosition.Y;
if(!(y & 1)) {
id = (y >> 1) - 1;
if(!(~id && id < num)) continue;
if(ly != y) {
draw(ly + 1, len, ' ');
ly = y;
len = strlen(choices[id]);
draw(y + 1, len, '~');
}
if(mouseRec.Event.MouseEvent.dwEventFlags == 0)
if(mouseRec.Event.MouseEvent.dwButtonState == 1)
return id;
}
}
}
void show() {
cls();
printf("共有%d个炸弹,还剩%d个.\n", boom, boom - mcnt);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (md[i][j]) putchar(' '), putchar('X');
else if(!od[i][j]) putchar(' '), putchar('#');
else if(!im[i][j]) putchar(' '), putchar(' ');
else printf(" %d", im[i][j]);
} putchar('\n');
}
}
void show_all() {
cls();
printf(" Map:\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (bm[i][j]) putchar(' '), putchar('*');
else if(!im[i][j]) putchar(' '), putchar(' ');
else printf(" %d", im[i][j]);
} putchar('\n');
}
}
void reset() {
memset(bm, 0, sizeof(bm));
memset(od, 0, sizeof(od));
memset(md, 0, sizeof(md));
memset(im, 0, sizeof(im));
boom = n * n * difity[dif];
blank = n * n - boom;
fal_end = sub_end = 0;
mcnt = ocnt = 0;
mp = m_pos{0, 0};
}
void c_map() {
reset();
m_pos ls;
for (int cnt = 0;cnt < boom;) {
ls.x = rand() % n;
ls.y = rand() % n;
if (!bm[ls.x][ls.y]) {
bm[ls.x][ls.y] = 1;
for (int i = max(ls.x - 1, 0); i < min(ls.x + 2, n); i++)
for (int j = max(ls.y - 1, 0); j < min(ls.y + 2, n); j++)
im[i][j]++;
cnt++;
}
}
show();
}
void start() {
putchar('.');
srand(time(NULL));
putchar('.');
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
putchar('.');
hIn = GetStdHandle(STD_INPUT_HANDLE);
putchar('.');
GetConsoleMode(hIn, &mode);
putchar('.');
mode |= ENABLE_MOUSE_INPUT;
putchar('.');
}
void end() {
sub_end = 1;
show_all();
Sleep(2000);
}
void win() {
end();
static const char* cwin[] = {"再来一次", "我已经很满足了"};
if(choose(2, "你赢了", cwin)) fal_end = 1;
}
void fail() {
end();
static const char* clse[] = {"我不甘心", "没意思"};
if(choose(2, "你输了", clse)) fal_end = 1;
}
void ez(int x, int y) {
for (int i = max(x - 1, 0); i < min(x + 2, n); i++)
for (int j = max(y - 1, 0); j < min(y + 2, n); j++)
if (!od[i][j]) {
od[i][j] = 1;
ocnt++;
if (!im[i][j]) ez(i, j);
}
}
void open() {
if(md[mp.x][mp.y] || od[mp.x][mp.y]) return;
if(bm[mp.x][mp.y]) {
fail();
return;
} else {
od[mp.x][mp.y] = 1;
ocnt++;
if(!im[mp.x][mp.y]) ez(mp.x, mp.y);
}
if(ocnt == blank) {
win();
return;
}
show();
}
void mark() {
if(od[mp.x][mp.y]) return;
md[mp.x][mp.y] = !md[mp.x][mp.y];
if(md[mp.x][mp.y]) mcnt++;
else mcnt--;
show();
}
void dset() {
cls();
static char difc[30];
sprintf(difc, "难度设置(目前难度:%s)", difcc[dif]);
dif = choose(3, difc, difcc);
}
void nset() {
cls();
printf("目前地图大小: %d\n", n);
printf("请输入一个合法的值(10 ~ %d): ", N - 5);
int ls;
scanf("%d", &ls);
if(10 <= ls && ls <= N - 5) {
n = ls;
return;
}
printf("非法的值!");
Sleep(1000);
exit(0);
}
void main_page() {
while(1) {
cls();
static const char* menu[] = {"开始", "难度设置", "地图大小", "退出"};
int cres = choose(4, "Mine_Sweeping", menu);
switch(cres) {
case 0: {
return;
break;
}
case 1: {
dset();
break;
}
case 2: {
nset();
break;
}
case 3: {
exit(0);
break;
}
}
}
}
int main() {
printf(" Loading, please wait");
start();
while(1) {
main_page();
while(1) {
c_map();
while(1) {
ReadConsoleInput(hIn, &mouseRec, 1, &res);
//SetConsoleCursorPosition(hOut, mouseRec.Event.MouseEvent.dwMousePosition);
if(mouseRec.Event.MouseEvent.dwEventFlags == 0) {
if(!get_mp(&mouseRec.Event.MouseEvent.dwMousePosition)) {
switch(mouseRec.Event.MouseEvent.dwButtonState) {
case 1: {
open();
break;
}
case 2: {
mark();
break;
}
}
}
} if(sub_end) break;
} if(fal_end) break;
}
}
return 0;
}
/*
* program name: mine_sweeping
* programmer: saxiy
* lastest update: 2019/6/11
*/
版权声明:
© saxiy 2019.6.11 保留所有权利