一化北溟 2023-06-11 13:00 采纳率: 100%
浏览 36
已结题

问怎么改代码让游戏开始后可以把棋子下到角落的那格里,不按照规则走


#include <graphics.h>    
#include <strstream>
#include <ctime>
#pragma comment(lib, "Winmm.lib")
#define T(c) ((c == 'B') ? 'W' : 'B')
using namespace std;



const int difficult = 6;    // 难度
const int move[8][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1},
                        {-1, -1}, {1, -1}, {1, 1}, {-1, 1} };
// 八个方向扩展
char map[8][8];                // 棋盘
IMAGE img[5];                // 保存图片
int black, white;            // 双方的棋子数
int X, Y;                    // 白棋的下子点


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

void load(void)        // 加载素材
{
    // 加载图片
    loadimage(&img[0], "C:\\图片\\空位.bmp");
    loadimage(&img[1], "C:\\图片\\黑子.bmp");
    loadimage(&img[2], "C:\\图片\\白子.bmp");
    loadimage(&img[3], "C:\\图片\\黑子1.bmp");
    loadimage(&img[4], "C:\\图片\\白子1.bmp");

    // 加载音乐
    mciSendString("open C:\\音乐\\背景音乐.wma", NULL, 0, NULL);
    mciSendString("open C:\\音乐\\和局.wma", NULL, 0, NULL);
    mciSendString("open C:\\音乐\\胜利.wma", NULL, 0, NULL);
    mciSendString("open C:\\音乐\\失败.wma", NULL, 0, NULL);
    mciSendString("open C:\\音乐\\下子.wma", NULL, 0, NULL);

    // 初始化棋盘
    initgraph(340, 340);
    IMAGE qipan;
    loadimage(&qipan, "C:\\图片\\棋盘.bmp");
    putimage(0, 0, &qipan);
    setorigin(26, 26);
    SetWindowText(GetHWnd(), "黑白棋AI版");
}

void print(void)    // 画棋盘
{
    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]);
                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 + ::move[i][0];
        y1 = y + ::move[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 -= ::move[i][0];
                    y1 -= ::move[i][1];
                    x2 = x + ::move[i][0];
                    y2 = y +:: move[i][1];
                    while (((x <= x2 && x2 <= x1) || (x1 <= x2 && x2 <= x)) && ((y <= y2 && y2 <= y1) || (y1 <= y2 && y2 <= y)))
                    {
                        map[x2][y2] = a;
                        x2 += ::move[i][0];
                        y2 += ::move[i][1];
                    }
                }
                break;
            }
            x1 += ::move[i][0];
            y1 += ::move[i][1];
        }
    }
    map[x][y] = a;
}

int judge(int x, int y, char a)    // 判断当前是否可以落下,同draw函数
{
    if (map[x][y])                        // 如果当前不是空的返回0值
        return 0;
    char b = T(a);
    int i, x1, y1;
    int n = 0, sign;
    for (i = 0; i < 8; i++)
    {
        sign = 0;
        x1 = x + ::move[i][0];
        y1 = y + ::move[i][1];
        while (0 <= x1 && x1 < 8 && 0 <= y1 && y1 < 8 && map[x1][y1])
        {
            if (map[x1][y1] == b)
                sign++;
            else
            {
                n += sign;
                break;
            }
            x1 += ::move[i][0];
            y1 += ::move[i][1];
        }
    }
    return n;        // 返回可吃棋数
}

bool baidu(char c)    // 判断是否有棋可吃
{
    int x, y;
    for (x = 0; x < 8; x++)
        for (y = 0; y < 8; y++)
            if (judge(x, y, c))
                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 (!baidu(c))
    {
        if (baidu(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 C:\\音乐\\背景音乐.wma from 0 repeat", NULL, 0, NULL);
    do
    {
        if (baidu('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 C:\\音乐\\下子.wma from 0", NULL, 0, NULL);
                print();
                putimage(37 * y, 37 * x, &img[3]);            // 标识下子点
            }
            else
                goto A;
            if (quit('W'))                                    // 计算机是否失败
                break;
        }
        if (baidu('W'))                                        // 如果计算机有下子位置
        {
            clock_t start;
            start = clock();
            D('W', 1);                                        // 搜索解法
            while (clock() - start < CLOCKS_PER_SEC);
            draw(X, Y, 'W');
            print();
            mciSendString("play C:\\音乐\\下子.wma from 0", NULL, 0, NULL);
            putimage(37 * Y, 37 * X, &img[4]);    // 标识下子点
            if (quit('B'))                                    // 玩家是否失败
                break;
        }
    } while (baidu('B') || baidu('W'));

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

// 主函数
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    load();
    do
    {
        play();
    } while (ask());

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

img

  • 写回答

3条回答 默认 最新

  • CF2301_77400554X 2023-06-11 13:30
    关注

    参考引用chatgpt部分结果:
    要实现在游戏开始后可以把棋子下到角落的那格里,并且不按照规则走,你可以按照以下步骤修改代码:

    1、在函数draw()中,将下子的逻辑修改为直接将棋子放在角落格子里。将以下代码:

    
    map[x][y] = a;
    
    
    

    修改为:

    
    if ((x == 0 && y == 0) || (x == 0 && y == 7) || (x == 7 && y == 0) || (x == 7 && y == 7))
        map[x][y] = a;
    
    

    这样修改后,无论棋子下在哪个位置,都会被放在角落格子里。

    2、在函数judge()中,也需要修改判断逻辑,使得角落格子可以被判定为可下子的位置。将以下代码:

    
    if (map[x][y])                        // 如果当前不是空的返回0值
        return 0;
    
    

    修改为:

    
    if (map[x][y] || (x == 0 && y == 0) || (x == 0 && y == 7) || (x == 7 && y == 0) || (x == 7 && y == 7))
        return 0;
    
    

    这样修改后,角落格子也会被认为是可下子的位置。

    通过以上修改,游戏开始后可以将棋子下到角落格子里,并且不受规则限制。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 6月19日
  • 已采纳回答 6月11日
  • 创建了问题 6月11日

悬赏问题

  • ¥15 CCF-CSP 2023 第三题 解压缩(50%)
  • ¥30 comfyui openpose报错
  • ¥20 Wpf Datarid单元格闪烁效果的实现
  • ¥15 图像分割、图像边缘提取
  • ¥15 sqlserver执行存储过程报错
  • ¥100 nuxt、uniapp、ruoyi-vue 相关发布问题
  • ¥15 浮窗和全屏应用同时存在,全屏应用输入法无法弹出
  • ¥100 matlab2009 32位一直初始化
  • ¥15 Expected type 'str | PathLike[str]…… bytes' instead
  • ¥15 三极管电路求解,已知电阻电压和三级关放大倍数