以前写的一个命令行版扫雷,今天翻出来整理了下拿出来,写的有点乱= =
Codeblocks、VC6.0编译通过,只能在windows下运行,Linux不支持。不嫌蛋疼的可以用curses库来实现下Linux版本。。。
截图2张,比较简陋:
程序还是比较简单的,那这里就直接丢代码了:
/**
* 命令行版扫雷,方向键控制
* 作者:evangwt
*/
#include
#include
#include
#include
#include
#define bool int
#define true 1
#define false 0
#define ROW 9
#define COLUMN 9
#define TOTAL_MINE 10
// ASCII码
#define MINE 42
#define ESC 27
#define ENTER 13
#define SPACE 32
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
typedef struct cursorPos_st
{
int x;
int y;
} cursorPos_t;
typedef struct block_st
{
bool bCover;
int nMine;
} block_t;
cursorPos_t cursorPos[ROW][COLUMN]; // 光标位置数组
block_t mine[ROW][COLUMN]; // 扫雷地图数组
int nLeftBlock = ROW * COLUMN; // 剩余的格数
int index_x = 0, index_y = 0; // 光标在光标位置数组、地图数组中的下标
void setColor(unsigned short Color);
void welcome();
void init();
void count(); // 计算附近雷数
void get(); // 获取键盘输入
void gotoPos(int y, int x);
void move(int y, int x); // 移动当前光标位置
bool check(int y, int x); // 检测是否踩雷
void print(); // 输出扫雷界面
void over(char *str); // 游戏结束
int main()
{
setColor(160);
system("cls");
welcome();
init();
count();
print();
/*颜色测试
int i = 0;
for(i = 0; i < 256; ++i){
setColor(i);
system("cls");
print();
gotoPos(0, 0);
printf("%d", i);
Sleep(100);
getch();
}
*/
for (;;)
{
gotoPos(cursorPos[index_y][index_x].y, cursorPos[index_y][index_x].x);
get();
}
return 0;
}
void setColor(unsigned short Color)
{
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hCon, Color);
};
void init()
{
int i = 0, j = 0;
int nMine = TOTAL_MINE; // 初始化地雷总数
srand((unsigned int)time(NULL));
// 初始化地雷地图数组
for (i = 0; i < ROW; ++i)
{
for (j = 0; j < COLUMN; ++j)
{
mine[i][j].bCover = true;
mine[i][j].nMine = 0;
}
}
// 放置地雷
while (nMine)
{
//printf("%d\n", nMine);
i = rand() % ROW;
j = rand() % COLUMN;
if (mine[i][j].nMine == 0)
{
mine[i][j].nMine = -1; // -1为地雷
--nMine;
}
}
// 初始化光标位置数组
for (i = 0; i < ROW; ++i)
{
for (j = 0; j < COLUMN; ++j)
{
cursorPos[i][j].x = j * 6 + 3;
cursorPos[i][j].y = i * 2 + 1;
//printf("%d,%d;", cursorPos[i][j].x, cursorPos[i][j].y);
}
}
}
void count()
{
int i = 0, j = 0, m = 0, n = 0;
int nMine = 0; // 每个格子周围的雷数
for (i = 0; i < ROW; ++i)
{
for (j = 0; j < COLUMN; ++j)
{
if (mine[i][j].nMine == -1)
continue;
// 8方向
nMine = 0;
for (m = -1; m <= 1; ++m)
{
if (i + m < 0 || i + m >= ROW) // 行溢出
{
continue;
}
for (n = -1; n <= 1; ++n)
{
if (j + n < 0 || j + n >= COLUMN)// 列溢出
{
continue;
}
if (mine[i + m][j + n].nMine == -1)
{
++nMine;
}
}
}
mine[i][j].nMine = nMine;
}
}
}
void get() {
bool lose;
int key1 = getch();
if (key1 == 224) // 方向键两个字节,第一个字节ASCII 224
{
int key2 = getch();
switch (key2)
{
case UP:
move(index_y - 1, index_x);
break;
case DOWN:
move(index_y + 1, index_x);
break;
case LEFT:
move(index_y, index_x - 1);
break;
case RIGHT:
//printf("right\n");
move(index_y, index_x + 1);
break;
default:
break;
}
}
else
{
switch (key1)
{
case ENTER:
case SPACE:
lose = check(index_y, index_x);
system("cls");
print();
if (lose)
{
printf("| 诶哟我去,踩到一坨热翔! =。。= |\n");
printf("| 按\"r\"重玩,其他键继续。 |\n");
printf("[%c]-------------------------------------------------[%c]\n", MINE, MINE);
Sleep(1000);
char key3 = getch();
if (key3 == 'r' || key3 == 'R')
{
setColor(160);
init();
count();
print();
}
}
else if (nLeftBlock > TOTAL_MINE)
{
printf("| 哎哟,不错哦~ = v = |\n");
printf("[%c]-------------------------------------------------[%c]\n", MINE, MINE);
}
else
{
printf("| 哟,居然赢了! =。。= |\n");
printf("| 按\"r\"重玩,其他键继续。 |\n");
printf("[%c]-------------------------------------------------[%c]\n", MINE, MINE);
Sleep(1000);
char key3 = getch();
if (key3 == 'r' || key3 == 'R')
{
setColor(160);
init();
count();
print();
}
}
break;
case ESC:
system("cls");
over("\t\t\t\t\t白白~\n\n\n\n\n\n\n\n");
default:
break;
}
}
}
void gotoPos(int y, int x)
{
COORD c;
c.X = x;
c.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}
void move(int y, int x)
{
if ((x >= 0 && x < COLUMN) && (y >= 0 && y < ROW))
{
gotoPos(cursorPos[y][x].y, cursorPos[y][x].x);
index_x = x;
index_y = y;
}
}
bool check(int y, int x)
{
int i = 0, j = 0;
// 下标溢出
if (x < 0 || x >= COLUMN || y < 0 || y >= ROW)
{
return false;
}
// 翻开选中的格子
mine[y][x].bCover = false;
// 踩中地雷
if (mine[y][x].nMine == -1)
{
mine[y][x].nMine = 9;
return true;
}
// 展开连片空格
if (mine[y][x].nMine > 0 && mine[y][x].nMine < 9)
{
return false;
}
for (i = -1; i <= 1; ++i)
{
if (y + i < 0 || y + i >= ROW) // 行溢出
{
continue;
}
for (j = -1; j <= 1; ++j)
{
if (x + j < 0 || x + j >= COLUMN) // 列溢出
{
continue;
}
if (mine[y + i][x + j].bCover)
{
mine[y + i][x + j].bCover = false;
check(y + i, x + j);
}
}
}
return false;
}
void print()
{
system("cls");
char help0[] = "←↑↓→";
char help1[] = "移动光标";
char help2[] = "空格\\回车";
char help3[] = " 挖雷";
char help4[] = "Esc 退出";
gotoPos(4, 62);
printf("%s", help0);
gotoPos(6, 62);
printf("%s", help1);
gotoPos(9, 62);
printf("%s", help2);
gotoPos(11, 62);
printf("%s", help3);
gotoPos(14, 62);
printf("%s", help4);
gotoPos(0, 0);
int i = 0, j = 0, k = 0;
nLeftBlock = 0;
printf("[M]---");
for (k = 1; k < COLUMN - 1; ++k)
{
printf("+-----");
}
printf("+---[I]\n");
for (i = 0; i < ROW; ++i)
{
for (j = 0; j < COLUMN; ++j)
{
if (mine[i][j].bCover)
{
++nLeftBlock;
printf("| %c ", 1);
}
else if (mine[i][j].nMine == -1 || mine[i][j].nMine == 9)
{
printf("| %c ", MINE);
}
else if (mine[i][j].nMine == 0)
{
printf("| %c ", ' ');
}
else
{
printf("| %d ", mine[i][j].nMine);
}
}
printf("|\n");
if (i < ROW - 1)
{
for (k = 0; k < COLUMN; ++k)
{
printf("+-----");
}
printf("+\n");
}
}
printf("[N]---");
for (k = 1; k < COLUMN - 1; ++k)
{
printf("+-----");
}
printf("+---[E]\n");
}
void welcome() {
int i = 0;
char words0[] = "《屌丝扫雷》";
char words1[] = "之";
char words2[] = "命令行版本";
char words3[] = "版权所有 evangwt,谢谢 (=v = )";
for (i = 0; i <= 5; ++i)
{
system("cls");
gotoPos(i, (80 - strlen(words0)) / 2);
printf("%s", words0);
Sleep(50);
}
for (i = 78; i >= 39; --i)
{
gotoPos(7, i);
printf("%s", words1);
gotoPos(7, 78 - i);
printf("%s", words1);
Sleep(40);
}
for (i = 0; i <= (80 - strlen(words2)) / 2; ++i)
{
gotoPos(9, i);
printf("%s", words2);
Sleep(50);
}
for (i = 24; i >= 14; --i)
{
system("cls");
gotoPos(5, (80 - strlen(words0)) / 2);
printf("%s", words0);
gotoPos(7, 39);
printf("%s", words1);
gotoPos(9, (80 - strlen(words2)) / 2);
printf("%s", words2);
gotoPos(i, (80 - strlen(words3)) / 2);
printf("%s", words3);
Sleep(50);
}
char help0[] = "{←↑↓→ 移动光标,空格\\回车 翻牌,Esc 退出}";
char help1[] = "{其他暂停界面按任意键继续}";
gotoPos(18, (80 - strlen(help0)) / 2);
printf("%s", help0);
gotoPos(19, (80 - strlen(help1)) / 2);
printf("%s", help1);
getch();
}
void over(char *str) {
setColor(110);
system("cls");
gotoPos(10, 0);
int i = 0;
do
{
printf("%c", str[i]);
Sleep(100);
} while(str[i++]);
system("pause");
exit(0);
}