求!!c语言黑白棋提示功能怎么写,就是设置一个提示按钮,点一下系统帮你下下一步 原体代码如下

求!!c语言黑白棋提示功能怎么写,就是设置一个提示按钮,点一下系统帮你下下一步
原体代码如下


```c
#include     // EasyX 
#include 
#include 
#include 
#pragma comment(lib, "Winmm.lib")
#define T(c) ((c == 'B') ? 'W' : 'B')  //定义一个标识符来表示一个常量
using namespace std;

/*******************************定义全局变量*****************************/
const int difficult = 3;    // 难度
// 八个方向扩展
const int HImove[8][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1},
                        {-1, -1}, {1, -1}, {1, 1}, {-1, 1} };

char map[8][8];                // 棋盘
IMAGE img[6];                // 保存图片
int black, white;            // 双方的棋子数
int X, Y;                    // 白棋的下子点

/**********************************函数声明*****************************/
void load();                // 加载素材
void print();                // 画棋盘
void draw(int x, int y, char a);        // 下当前子
int judge(int x, int y, char a);        // 判断当前是否可以落下
bool check(char a);                // 判断是否有棋可吃
bool quit(char a);                // 判断是否有棋存活
bool ask();                // 弹出对话框
int D(char a, int);                // 动态规划
void play();                // 游戏过程

/**********************************定义函数*****************************/
void load()        // 加载素材
{
    // 加载图片
    loadimage(&img[0], "图片\\空位.bmp");
    loadimage(&img[1], "图片\\de.jpg");
    loadimage(&img[2], "图片\\la.jpg");
    loadimage(&img[3], "图片\\de1.jpg");
    loadimage(&img[4], "图片\\la1.jpg");
    loadimage(&img[5], "图片\\提示.jpg");
    // 加载音乐
    mciSendString("open 音乐\\背景音乐.mp3", NULL, 0, NULL);
    mciSendString("open 音乐\\和局.wma", NULL, 0, NULL);
    mciSendString("open 音乐\\胜利.wma", NULL, 0, NULL);
    mciSendString("open 音乐\\失败.wma", NULL, 0, NULL);
    mciSendString("open 音乐\\下子.wma", NULL, 0, NULL);
    // 初始化棋盘
    initgraph(380, 340);//初始化窗体

    IMAGE qipan;
    loadimage(&qipan, "图片\\背景.jpg");

    putimage(0, 0, &qipan);
    setorigin(26, 26);//图片插入原点
    SetWindowText(GetHWnd(), "德克萨斯与拉普兰德");
    
        
}

void print()    // 画棋盘
{
    int x, y;
    black = white = 0;
    for (x = 0; x < 8; x++)
        for (y = 0; y < 8; y++)
            switch (map[x][y])
            {
            case 0:
                putimage(37 * y, 37 * x, &img[0]);//因为图片的像素是37*37,所以宽度也是37的倍数
                break;
            case 'B':
                putimage(37 * y, 37 * x, &img[1]);
                black++;
                break;
            case 'W':
                putimage(37 * y, 37 * x, &img[2]);
                white++;
                break;
            }
}
// 下当前子
void draw(int x, int y, char a)
{
    char b = T(a);// 敌方子
    int i, x1, y1, x2, y2;
    bool sign;//用来控制是否是对方棋子标识 
    for (i = 0; i < 8; i++)
    {
        sign = false;
        x1 = x + HImove[i][0];
        y1 = y + HImove[i][1];
        while (0 <= x1 && x1 < 8 && 0 <= y1 && y1 < 8 && map[x1][y1])
        {
            if (map[x1][y1] == b)
                sign = true;
            else
            {
                if (sign)
                {
                    x1 -= HImove[i][0];
                    y1 -= HImove[i][1];
                    x2 = x + HImove[i][0];
                    y2 = y + HImove[i][1];
                    while (((x <= x2 && x2 <= x1) || (x1 <= x2 && x2 <= x)) && ((y <= y2 && y2 <= y1) || (y1 <= y2 && y2 <= y)))
                    {
                        map[x2][y2] = a;
                        x2 += HImove[i][0];
                        y2 += HImove[i][1];
                    }
                }
                break;
            }
            x1 += HImove[i][0];
            y1 += HImove[i][1];
        }
    }
    map[x][y] = a;
}
// 判断当前下子可吃敌方棋子数量
int judge(int x, int y, char a)
{
    if (map[x][y])// 如果当前不是空的返回0值
        return 0;
    char b = T(a);//对方棋子 
    int i, x1, y1;
    int sum; //单方向可吃棋子数量 
    int count=0; // 总可吃棋子数 
    for (i = 0; i < 8; i++)
    {
        sum = 0;//计算当前方向对方棋子的数量
        x1 = x + HImove[i][0];  
        y1 = y + HImove[i][1];  
        while (0 <= x1 && x1 < 8 && 0 <= y1 && y1 < 8 && map[x1][y1])
        {
            if (map[x1][y1] == b)
                sum++;
            else
            {
                count += sum;
                break;
            }
            x1 += HImove[i][0];
            y1 += HImove[i][1];
        }
    }
    return count;        // 返回可吃棋数
}

// 判断是否有棋可吃
bool check(char c)
{
    int x, y;
    for (x = 0; x < 8; x++)
        for (y = 0; y < 8; y++)
            if (judge(x, y, c)>0)
                return true;
    return false;
}

// 判断是否有棋存活
bool quit(char c)
{
    int x, y;
    bool b = false, w = false;
    for (x = 0; x < 8; x++)
        for (y = 0; y < 8; y++)
        {
            if (map[x][y] == c)
                return false;
        }
    return true;
}
// 弹出对话框
bool ask(void)
{
    HWND wnd = GetHWnd();
    int key;
    char str[50];
    ostrstream strout(str, 50);
    strout << "黑:" << black << "  白:" << white << endl;
    if (black == white)
        strout << "世界和平";
    else if (black > white)
        strout << "不堪一击。";
    else
        strout << "德克萨斯做的到吗!";
    strout << "\n再来一局吗?" << ends;
    if (black == white)
        key = MessageBox(wnd, str, "和局", MB_YESNO | MB_ICONQUESTION);
    else if (black > white)
        key = MessageBox(wnd, str, "黑胜", MB_YESNO | MB_ICONQUESTION);
    else
        key = MessageBox(wnd, str, "白胜", MB_YESNO | MB_ICONQUESTION);
    if (key == IDYES)
        return true;
    else
        return false;
}

int D(char c, int step)
{
    // 判断是否结束递归
    if (step > difficult)    // 约束步数之内
        return 0;
    if (!check(c))
    {
        if (check(T(c)))
            return -D(T(c), step);
        else
            return 0;
    }

    int i, j, max = 0, temp, x, y;
    bool ans = false;

    // 建立临时数组
    char** t = new char* [8];
    for (i = 0; i < 8; i++)
        t[i] = new char[8];
    for (i = 0; i < 8; i++)
        for (j = 0; j < 8; j++)
            t[i][j] = map[i][j];

    // 搜索解法
    for (i = 0; i < 8; i++)
        for (j = 0; j < 8; j++)
            if (temp = judge(i, j, c))
            {
                draw(i, j, c);
                temp -= D(T(c), step + 1);
                if (temp > max || !ans)
                {
                    max = temp;
                    x = i;
                    y = j;
                    ans = true;
                }
                for (int k = 0; k < 8; k++)
                    for (int l = 0; l < 8; l++)
                        map[k][l] = t[k][l];
            }

    // 撤销空间
    for (i = 0; i < 8; i++)
        delete[] t[i];
    delete[] t;

    // 如果是第一步则标识白棋下子点
    if (step == 1)
    {
        X = x;
        Y = y;
    }

    return max;    // 返会最优解
}

// 游戏过程
void play(void)
{
    MOUSEMSG m;
    int x, y;
    for (x = 0; x < 8; x++)
        for (y = 0; y < 8; y++)
            map[x][y] = 0;
    map[3][4] = map[4][3] = 'B';
    map[3][3] = map[4][4] = 'W';

    // 开始游戏
    print();

    mciSendString("play 音乐\\背景音乐.mp3 from 0 repeat", NULL, 0, NULL);
    do
    {
        if (check('B'))                                        // 如果玩家有下子位置                            
        {
        A:
            while (true)
            {
                m = GetMouseMsg();                            // 获取鼠标消息
                if (m.uMsg == WM_LBUTTONDOWN && m.x - 26 < 37 * 8 && m.y - 26 < 37 * 8)
                    // 如果左键点击
                    break;
            }
            x = (m.y - 26) / 37;
            y = (m.x - 26) / 37;
            if (judge(x, y, 'B'))                            // 如果当前位置有效
            {
                draw(x, y, 'B');                            // 下子
                mciSendString("play 音乐\\下子.wma from 0", NULL, 0, NULL);
                print();
                putimage(37 * y, 37 * x, &img[3]);            // 标识下子点
            }
            else
                goto A;
            if (quit('W'))                                    // 计算机是否失败
                break;
        }
        if (check('W'))                                        // 如果计算机有下子位置
        {
            clock_t start;
            start = clock();
            D('W', 1);                                        // 搜索解法
            while (clock() - start < CLOCKS_PER_SEC);
            draw(X, Y, 'W');
            print();
            mciSendString("play 音乐\\下子.wma from 0", NULL, 0, NULL);
            putimage(37 * Y, 37 * X, &img[4]);    // 标识下子点
            if (quit('B'))                                    // 玩家是否失败
                break;
        }
    } while (check('B') || check('W'));

    // 播放庆祝音乐
    mciSendString("stop 音乐\\背景音乐.mp3", NULL, 0, NULL);
    if (black > white)
        mciSendString("play 音乐\\胜利.wma from 0", NULL, 0, NULL);
    else if (black < white)
        mciSendString("play 音乐\\失败.wma from 0", NULL, 0, NULL);
    else
        mciSendString("play 音乐\\和局.wma from 0", NULL, 0, NULL);
}

// 主函数
int main()
{
    load();
    do
    {
        play();
    } while (ask());

    // 关闭音乐
    mciSendString("close 音乐\\背景音乐.mp3", NULL, 0, NULL);
    mciSendString("close 音乐\\和局.wma", NULL, 0, NULL);
    mciSendString("close 音乐\\胜利.wma", NULL, 0, NULL);
    mciSendString("close 音乐\\失败.wma", NULL, 0, NULL);
    mciSendString("close 音乐\\下子.wma", NULL, 0, NULL);
    _getch();
    closegraph();
    return 0;
}

```

为了实现这个功能,可以使用极大极小值算法(alpha-beta pruning算法)来评估棋盘上每一步的最优结果,根据评估结果来决定下一步最优的走法。极大极小值算法是一种类似于推理的搜索算法,大方向上是基于搜索树来寻找最优走法,帮助黑白棋系统判断当前哪一步最具有优势以及对局面最有利。

以下是一个完整的黑白棋游戏的C++代码,其中包含了提示功能的实现。这个程序使用EasyX图形库和Windows API,需要在Windows操作系统下运行。


#include <graphics.h>    // EasyX图形库 
#include <strstream>
#include <ctime>
#include <conio.h>
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib, "Winmm.lib")
#define T(c) ((c == 'B') ? 'W' : 'B')  //定义一个标识符来表示一个常量
using namespace std;
 
/*******************************定义全局变量*****************************/
const int difficult = 3;    // 难度
// 八个方向扩展
const int HImove[8][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1},
                        {-1, -1}, {1, -1}, {1, 1}, {-1, 1} };
 
char map[8][8];                // 棋盘
IMAGE img[6];                // 保存图片
int black, white;            // 双方的棋子数
int X, Y;                    // 白棋的下子点
 
/**********************************函数声明*****************************/
void load();                // 加载素材
void print();                // 画棋盘
void draw(int x, int y, char a);        // 下当前子
int judge(int x, int y, char a);        // 判断当前是否可以落下
bool check(char a);                // 判断是否有棋可吃
bool quit(char a);                // 判断是否有棋存活
bool ask();                // 弹出对话框
int D(char a, int);                // 动态规划
void play();                // 游戏过程
void tip();                    // 提示功能
 
/**********************************定义函数*****************************/
void load()        // 加载素材
{
    // 加载图片
    loadimage(&img[0], "images\\empty.jpg");
    loadimage(&img[1], "images\\black.jpg");
    loadimage(&img[2], "images\\white.jpg");
    loadimage(&img[3], "images\\black_1.jpg");
    loadimage(&img[4], "images\\white_1.jpg");
    loadimage(&img[5], "images\\tip.jpg");
    // 加载音乐
    mciSendString("open audios\\bgm.mp3", NULL, 0, NULL);
    mciSendString("open audios\\draw.mp3", NULL, 0, NULL);
    mciSendString("open audios\\drawn.mp3", NULL, 0, NULL);
    mciSendString("open audios\\equal.mp3", NULL, 0, NULL);
    mciSendString("open audios\\win.mp3", NULL, 0, NULL);
    mciSendString("open audios\\lose.mp3", NULL, 0, NULL);
    // 初始化棋盘
    initgraph(380, 340);
    IMAGE qipan;
    loadimage(&qipan, "images\\bg.jpg");
    putimage(0, 0, &qipan);
    setorigin(26, 26);
    SetWindowText(GetHWnd(), "黑白棋");