社区讨论
《扫雷》
灌水区参与者 2已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @lxldguyd
- 此快照首次捕获于
- 2024/06/19 13:07 2 年前
- 此快照最后确认于
- 2024/06/19 13:17 2 年前
CPP
#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
using namespace std;
COORD GetPos() {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO bInfo;
GetConsoleScreenBufferInfo(hOut, &bInfo);
return bInfo.dwCursorPosition;
}
void Gotoxy(int x, int y, int flag = 0) { //2全角 1相对 0绝对
COORD coord;
coord.X = x;
coord.Y = y;
if (flag & 1) {
COORD crd = GetPos();
coord.X += crd.X;
coord.Y += crd.Y;
}
if (flag & 2) {
coord.X <<= 1;
}
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void Fill(int left, int top, int right, int buttom, char c = 32, int mode = 1) {
if (mode) {
left <<= 1;
right <<= 1;
}
for (int i = top; i <= buttom; ++i) {
Gotoxy(left,i);
for (int i = left; i <= right; ++i) {
printf("%c",c);
}
}
}
double GetScreenPercentage() {
// 获取桌面窗口口句柄
HWND hWnd = GetDesktopWindow();
HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
// 获取监视器逻辑尺寸
MONITORINFOEX miex;
miex.cbSize = sizeof(miex);
GetMonitorInfo(hMonitor, &miex);
int cxLogical = (miex.rcMonitor.right - miex.rcMonitor.left);
int cyLogical = (miex.rcMonitor.bottom - miex.rcMonitor.top);
// 获取监视器物理宽度与高度
DEVMODE dm;
dm.dmSize = sizeof(dm);
dm.dmDriverExtra = 0;
EnumDisplaySettings(miex.szDevice, ENUM_CURRENT_SETTINGS, &dm);
int cxPhysical = dm.dmPelsWidth;
int cyPhysical = dm.dmPelsHeight;
// 缩放比例计算 实际上使用任何一个即可
double horzScale = ((double)cxPhysical / (double)cxLogical);
double vertScale = ((double)cyPhysical / (double)cyLogical);
// printf("cxPhysical = %d px.cyPhysical = %d px.\n", cxPhysical, cyPhysical);
// printf("cxLogical = %d px.cyLogical = %d px.\n", cxLogical, cyLogical);
// printf("horzScale = %.2f ,vertScale = %.2f \n", horzScale, vertScale );
return horzScale;
}
POINT GetMousePosition(int x = 1,int n = 1, int l = 0) { //x相对窗口位置, n转化为黑窗口格子坐标 , l转化为全角
double Percentage = GetScreenPercentage();
HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE);
// HWND h=GetForegroundWindow();
HWND h=GetConsoleWindow();
CONSOLE_FONT_INFO consoleCurrentFont;
POINT p;
if(x) {
GetCursorPos(&p);
ScreenToClient(h,&p);
} else {
GetCursorPos(&p);
}
if(n) {
GetCurrentConsoleFont(hOutput,FALSE,&consoleCurrentFont);
p.x/=consoleCurrentFont.dwFontSize.X/Percentage;
p.y/=consoleCurrentFont.dwFontSize.Y/Percentage;
if (l) {
p.x>>=1;
}
}
return p;
}
int CheckMouse(int left, int top, int right, int buttom, int mode = 0) {
if (mode) {
left <<= 1;
right <<= 1;
}
POINT p = GetMousePosition();
if (p.x <= right && p.x >= left && p.y <= buttom && p.y >= top) {
return 1;
}
return 0;
}
void HidePos() {
CONSOLE_CURSOR_INFO cursor_info = {1, 0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void ShowPos() {
CONSOLE_CURSOR_INFO cursor_info = {26, 1};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void SetColor(const short ForG = 7, const short BackG = 0) {
WORD wColor = ((BackG & 0x0F) << 4) + (ForG & 0x0F);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),wColor);
}
void Edge(int left, int top, int right, int buttom, int mode = 1) {
if (!mode) {
left >>= 1;
right >>= 1;
}
Gotoxy((left + 1) << 1, top);
for (int i = left + 2; i <= right; ++i) {
printf("▁");
}
Gotoxy(left << 1, top + 1);
for (int i = top + 2; i <= buttom; ++i) {
printf("▕");
Gotoxy(-2,1,1);
}
Gotoxy(right << 1, top + 1);
for (int i = top + 2; i <= buttom; ++i) {
printf("▏");
Gotoxy(-2,1,1);
}
Gotoxy((left + 1) << 1, buttom);
for (int i = left + 2; i <= right; ++i) {
printf("▔");
}
}
void FixedSize() {
SetWindowLongPtrA(
GetConsoleWindow(),
GWL_STYLE,
GetWindowLongPtrA(GetConsoleWindow(),
GWL_STYLE)
& ~WS_SIZEBOX
& ~WS_MAXIMIZEBOX
);
}
void SetFont(int size = 36, int num = 0) {
CONSOLE_FONT_INFOEX cfi;
cfi.cbSize = sizeof cfi;
cfi.nFont = 0;
cfi.dwFontSize.X = 0;
cfi.dwFontSize.Y = size;
cfi.FontFamily = FF_DONTCARE;
cfi.FontWeight = FW_NORMAL;
switch(num) {
case 0:
wcscpy(cfi.FaceName, L"NSimSun");
break;//新宋体
case 1:
wcscpy(cfi.FaceName, L"Lucida Console");
break;//一款个性独特的英文字体
case 2:
wcscpy(cfi.FaceName, L"Consolas");
break;//等宽字体(Dev默认字体)
case 3:
wcscpy(cfi.FaceName, L"Raster");
break;//点阵字体
}
SetCurrentConsoleFontEx(
GetStdHandle(STD_OUTPUT_HANDLE),
FALSE, &cfi
);
}
#define QUICK_EDIT 0x01
#define INSERT 0x02
void CloseConsoleMode(UINT uTag) {
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
GetConsoleMode(hStdin, &mode);
if(uTag & QUICK_EDIT)
mode &= ~ENABLE_QUICK_EDIT_MODE; //移除快速编辑模式
if(uTag & INSERT)
mode &= ~ENABLE_INSERT_MODE; //移除插入模式
SetConsoleMode(hStdin, mode);
}
void OpenConsoleMode(UINT uTag) {
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
GetConsoleMode(hStdin, &mode);
if(uTag & QUICK_EDIT)
mode |= ENABLE_QUICK_EDIT_MODE; //设置快速编辑模式
if(uTag & INSERT)
mode |= ENABLE_INSERT_MODE; //设置插入模式
SetConsoleMode(hStdin, mode);
}
void SetSize(int col, int row) {
char cmd[64];
sprintf(cmd, "mode con cols=%d lines=%d", col, row);
system(cmd);
}
int Click() {
if (GetKeyState(1) & 0x8000) {
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
return 1;
}
return 0;
}
int ClickR() {
if (GetKeyState(4) & 0x8000) {
mouse_event(MOUSEEVENTF_MIDDLEUP,0,0,0,0);
return 1;
}
return 0;
}
int Rule() {
SetColor(7);
system("cls");
printf("此游戏和传统扫雷类似, 可使用鼠标点击, 左键为挖开, 中键为标记\n");
printf("在结算阶段感觉太慢时, 可以按任意键加快\n");
Gotoxy(0,18);
SetColor(7);
printf("返回");
int b = 0;
while (1) {
Sleep(5);
if (CheckMouse(0,18,3,18)) {
if (b == 0) {
Gotoxy(0,18);
SetColor(0,15);
printf("返回");
b = 1;
}
if (Click()) {
return 0;
}
} else if (b == 1 && !CheckMouse(0,18,3,18)) {
Gotoxy(0,18);
SetColor(7);
printf("返回");
b = 0;
}
}
}
int Exit() {
SetColor();
system("cls");
Edge(27,6,57,13,0);
Gotoxy(18,8,2);
SetColor(13);
printf("确定要退出吗?");
Gotoxy(17,10,2);
SetColor(12);
printf("是/YES");
Gotoxy(22,10,2);
SetColor(9);
printf("否/NO");
int b1=0,b2=0;
while (1) {
Sleep(5);
if (CheckMouse(34,10,39,10)) {
if (b1 == 0) {
Gotoxy(17,10,2);
SetColor(0,15);
printf("是/YES");
b1 = 1;
}
if (Click()) {
SetColor();
system("cls");
exit(0);
}
} else {
if (b1 == 1) {
Gotoxy(17,10,2);
SetColor(12);
printf("是/YES");
b1 = 0;
}
}
if (CheckMouse(44,10,48,10)) {
if (b2 == 0) {
Gotoxy(22,10,2);
SetColor(0,15);
printf("否/NO");
b2 = 1;
}
if (Click()) {
return 0;
}
} else {
if (b2 == 1) {
Gotoxy(22,10,2);
SetColor(9);
printf("否/NO");
b2 = 0;
}
}
}
}
int creater() {
SetColor();
system("cls");
printf("创作者: 洛谷用户 745288");
Gotoxy(0,18);
SetColor(7);
printf("返回");
int b = 0;
while (1) {
Sleep(5);
if (CheckMouse(0,18,3,18)) {
if (b == 0) {
Gotoxy(0,18);
SetColor(0,15);
printf("返回");
b = 1;
}
if (Click()) {
return 0;
}
} else if (b == 1 && !CheckMouse(0,18,3,18)) {
Gotoxy(0,18);
SetColor(7);
printf("返回");
b = 0;
}
}
}
int Menu() {//1 Rule 2 Exit 3 creater
SetColor(7);
system("cls");
SetColor(2);
Edge(27,5,57,13,0);
SetColor(15);
Gotoxy(19,7,2);
printf("开始游戏");
Gotoxy(20,8,2);
printf("规则");
Gotoxy(39,9);
printf("制作者");
Gotoxy(20,10,2);
printf("退出");
int last = -1;
while (1) {
Sleep(5);
POINT p = GetMousePosition();
SetColor(10);
if (p.x >= 36 && p.x <= 47 && p.y <= 10 && p.y >= 7) {
if (p.y != last) {
Gotoxy(36,p.y);
printf("→");
Gotoxy(46,p.y);
printf("←");
Gotoxy(36,last);
printf(" ");
Gotoxy(46,last);
printf(" ");
last = p.y;
}
if (Click()) {
if (p.y == 7) {//开始
return 0;
} else if (p.y == 8) {//规则
return 1;
} else if (p.y == 9) {//制作者
system("start https://www.luogu.com.cn/user/745288");
return 3;
} else if (p.y == 10) {//退出
return 2;
}
}
} else if (last != -1) {
Gotoxy(36,last);
printf(" ");
Gotoxy(46,last);
printf(" ");
last = -1;
}
}
}
int c[20][20], c1[20][20];//地雷/地雷数量 标记/挖开
int n = 10, m = 20, tot, Top, Left;
int Rand() {
mt19937 rnd(time(0));
for (int i = 0; i < m; ++i) {
int x = rnd()%n, y = rnd()%n;
while (c[x][y] != 0) {
x = rnd()%n, y = rnd()%n;
}
c[x][y] = -1;
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (c[i][j] == -1) {
continue;
}
int tot = 0;
for (int k = -1; k <= 1; ++k) {
for (int l = -1; l <= 1; ++l) {
if (i+k<0||i+k>=n||j+l<0||j+l>=n) continue;
if (k == l && l == 0) {
continue;
}
if (c[i+k][j+l] == -1) {
++tot;
}
}
}
c[i][j] = tot;
}
}
return 0;
}
int NewGame() {
memset(c, 0, sizeof(c));
memset(c1, 0, sizeof(c1));
tot = 0;
SetColor();
system("cls");
Edge(16,5,27,14);
Gotoxy(18,8,2);
printf("大小: %d",n);
Gotoxy(18,10,2);
printf("数量: %d",m);
Gotoxy(21,9,2);
for (int i = 0; i < 3; ++i) {
printf(" ̄");
}
Gotoxy(21,11,2);
for (int i = 0; i < 3; ++i) {
printf(" ̄");
}
Gotoxy(41,12);
SetColor(0,7);
printf("确定");
int b = 0;
int now = 0;
int size=n, num=m;
string Size, Num;
for (int i = 1; size / i; i *= 10) {
Size += size / i % 10;
}
for (int i = 1; num / i; i *= 10) {
Num += num / i % 10;
}
char cache;
while (1) {
Sleep(5);
if (CheckMouse(41,12,44,12)) {//确定键
if (b == 0) {
Gotoxy(41,12);
SetColor(0,15);
printf("确定");
b = 1;
}
if (Click()) {
HidePos();
if (size > 0 && num > 0 && num < size * size && size <= 20) {
//输入成功
n = size;
m = num;
Rand();
return 0;
} else if (size == num && num == 0) {
Rand();
return 0;
} else {
Gotoxy(19,7,2);
SetColor(12);
printf("输入不合法!");
Sleep(1000);
Gotoxy(19,7,2);
SetColor(12);
printf(" ");
}
}
} else {
if (b == 1) {
Gotoxy(41,12);
SetColor(0,7);
printf("确定");
b = 0;
}
}
if (CheckMouse(42,8,47,8)) {//点击输入大小位置
if (Click()) {
now = 1;
ShowPos();
}
} else if (CheckMouse(42,10,47,10)) {//点击输入数量位置
if (Click()) {
now = 2;
ShowPos();
}
} else {
if (Click()) {
now = 0;
HidePos();
}
}
if (now == 1) {//移动光标
COORD coord = GetPos();
if (coord.X > 47 || coord.X < 42 || coord.Y != 8) Gotoxy(42+Size.size(),8);
} else if (now == 2) {
COORD coord = GetPos();
if (coord.X > 47 || coord.X < 42 || coord.Y != 10) Gotoxy(42+Num.size(),10);
}
if (kbhit()) {//输入
cache = getch();
if (!isdigit(cache) && cache != 8) {
} else if (now == 1) {
SetColor();
if (cache == 8) {
if (Size.size()) {
Size.pop_back();
size /= 10;
printf("\b \b");
}
} else {
Size += cache;
size = size * 10 + cache - 48;
putchar(cache);
}
} else if (now == 2) {
SetColor();
if (cache == 8) {
if (Num.size()) {
Num.pop_back();
num /= 10;
printf("\b \b");
}
} else {
Num += cache;
num = num * 10 + cache - 48;
putchar(cache);
}
}
}
}
return 0;
}
long Lclock, Rclock;
int Game() {//0 胜利 1 失败
POINT p = GetMousePosition();
int x = -1, y = -1, px = p.x / 2, py = p.y;
while (1) {
if (kbhit()) {
getch();
}
if (tot == n * n - m) {
int wait = 1;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (kbhit()) {
getch();
wait = 0;
} else if (Click()) {
wait = 0;
}
if (i == px - Left && j == py - Top) {
continue;
}
if (c[i][j] == -1) {
Gotoxy(i + Left, j + Top, 2);
if (wait) Sleep(250);
if (c1[i][j] == 2) {
SetColor(13);
} else {
SetColor(12);
}
printf("●");
}
}
}
Gotoxy(0,6);
printf("请按任意键继续...");
while (1) {
Sleep(5);
if (kbhit()) {
getch();
break;
} else if (Click()) {
break;
}
}
return 0;
}
Sleep(5);
p = GetMousePosition();
px = p.x / 2;
py = p.y;
if (x != px || y != py) {
if (x < Left + n && x >= Left && y >= Top && y < Top + n) {
Gotoxy(x, y, 2);
SetColor(3);
if (c1[x - Left][y - Top] == 0) {
printf("■");
} else if (c1[x - Left][y - Top] == 1) {
printf("%d",c[x - Left][y - Top]);
} else if (c1[x - Left][y - Top] == 2) {
SetColor(5);
printf("■");
}
}
if (px < Left + n && px >= Left && py >= Top && py < Top + n) {
Gotoxy(px, py, 2);
SetColor(11);
if (c1[px - Left][py - Top] == 0) {
printf("■");
} else if (c1[px - Left][py - Top] == 1) {
printf("%d",c[px - Left][py - Top]);
} else if (c1[px - Left][py - Top] == 2) {
SetColor(13);
printf("■");
}
}
x = px, y = py;
}
if (Click()) {
if (px < Left || px >= Left + n || py >= Top + n || py < Top) {
} else if (c1[px - Left][py - Top] != 0) {
SetColor(12);
Gotoxy(0,2);
printf("左键错误: \n无法挖开已标记的方块");
Lclock = clock();
} else if (c[px - Left][py - Top] == -1) {
Gotoxy(px, py, 2);
SetColor(12);
printf("死");
int wait = 1;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (kbhit()) {
getch();
wait = 0;
} else if (Click()) {
wait = 0;
}
if (i == px - Left && j == py - Top) {
continue;
}
if (c[i][j] == -1) {
Gotoxy(i + Left, j + Top, 2);
if (wait) Sleep(250);
if (c1[i][j] == 2) {
SetColor(13);
} else {
SetColor(12);
}
printf("●");
}
}
}
Gotoxy(0,6);
printf("请按任意键继续...");
while (1) {
Sleep(5);
if (kbhit()) {
getch();
break;
} else if (Click()) {
break;
}
}
return 1;
} else if (c[px - Left][py - Top] == 0) {
SetColor(3);
for (int i = -1; i <= 1; ++i) {
for (int j = -1; j <= 1; ++j) {
if (px + i < Left || px + i >= Left + n || py + j >= Top + n || py + j < Top) continue;
if ((i == j && i == 0) || c1[px + i - Left][py + j - Top] == 1) continue;
c1[px + i - Left][py + j - Top] = 1;
Gotoxy(px + i, py + j, 2);
printf("%d", c[px + i - Left][py + j - Top]);
++tot;
}
}
SetColor(11);
c1[px - Left][py - Top] = 1;
Gotoxy(px, py, 2);
printf("%d", c[px - Left][py - Top]);
++tot;
} else {
c1[px - Left][py - Top] = 1;
Gotoxy(px, py, 2);
SetColor(11);
printf("%d", c[px - Left][py - Top]);
++tot;
}
}
if (ClickR()) {
if (px < Left || px >= Left + n || py >= Top + n || py < Top) {
} else if (c1[px - Left][py - Top] == 1) {
SetColor(12);
Gotoxy(0,0);
printf("中键错误: \n无法标记已挖开的方块");
Rclock = clock();
} else if (c1[px - Left][py - Top] == 0) {
c1[px - Left][py - Top] = 2;
Gotoxy(px, py, 2);
SetColor(13);
printf("■");
} else if (c1[px - Left][py - Top] == 2) {
c1[px - Left][py - Top] = 0;
Gotoxy(px, py, 2);
SetColor(11);
printf("■");
}
}
if (clock() - Rclock > 1000) {
SetColor();
Gotoxy(0,0);
printf(" ");
Fill(0,0,10,1);
}
if (clock() - Lclock > 1000) {
SetColor();
Fill(0,2,10,3);
}
}
}
int mainfunc() {
int flag;
while (1) {
flag = Menu();
if (flag == 0) {
NewGame();
break;
} else if (flag == 1) {
Rule();
} else if (flag == 2) {
Exit();
} else if (flag == 3) {
creater();
}
}
SetColor(3);
system("cls");
Left = 21 - (n >> 1);
Top = 10 - (n >> 1);
for (int i = 0; i < n; ++i) {
Gotoxy(21 - (n >> 1),10 - (n >> 1) + i,2);
for (int j = 0; j < n; ++j) {
printf("■");
}
}
int result = Game();
SetColor();
system("cls");
Edge(27,5,57,13,0);
Gotoxy(19,8,2);
SetColor(13);
printf("要继续吗?");
Gotoxy(17,10,2);
SetColor(11);
printf("是/YES");
Gotoxy(22,10,2);
SetColor(12);
printf("否/NO");
Gotoxy(35,7);
if (result) {
SetColor(12);
printf("很遗憾, 你输了");
} else {
SetColor(10);
printf("恭喜! 你赢了! ");
}
int b1=0,b2=0;
while (1) {
Sleep(5);
if (CheckMouse(34,10,39,10)) {
if (b1 == 0) {
Gotoxy(17,10,2);
SetColor(0,15);
printf("是/YES");
b1 = 1;
}
if (Click()) {
return 0;
}
} else {
if (b1 == 1) {
Gotoxy(17,10,2);
SetColor(11);
printf("是/YES");
b1 = 0;
}
}
if (CheckMouse(44,10,48,10)) {
if (b2 == 0) {
Gotoxy(22,10,2);
SetColor(0,15);
printf("否/NO");
b2 = 1;
}
if (Click()) {
SetColor();
system("cls");
exit(0);
}
} else {
if (b2 == 1) {
Gotoxy(22,10,2);
SetColor(12);
printf("否/NO");
b2 = 0;
}
}
}
return 0;
}
int StartSet() {
CloseConsoleMode(QUICK_EDIT);
SetSize(88,20);
SetFont();
FixedSize();
HidePos();
return 0;
}
int main() {
StartSet();
int i = 1;
char c[] = "扫雷-第1局";
SetConsoleTitle(c);
while (1) {
mainfunc();
sprintf(c, "扫雷-第%d局",++i);
SetConsoleTitle(c);
}
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...