命令行版扫雷,方向键控制

来源:互联网 发布:千万别在淘宝搜血滴子 编辑:程序博客网 时间:2024/05/02 00:51

以前写的一个命令行版扫雷,今天翻出来整理了下拿出来,写的有点乱=  =

Codeblocks、VC6.0编译通过,只能在windows下运行,Linux不支持。不嫌蛋疼的可以用curses库来实现下Linux版本。。。

截图2张,比较简陋:


程序还是比较简单的,那这里就直接丢代码了:

/** * 命令行版扫雷,方向键控制 * 作者:evangwt */#include <stdio.h>#include <stdlib.h>#include <conio.h>#include <time.h>#include <windows.h>#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           77typedef 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);}



原创粉丝点击