You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为C++国际象棋游戏实现回退按钮功能?

国际象棋回退功能修复方案

我正在用C++完成国际象棋作业,需求是实现棋子在棋盘内任意移动,以及通过back命令恢复上一步的棋盘状态。但现在执行back命令后,棋盘内容会全部消失。

我尝试用数组保存状态,但现有代码里的SaveBoard和Back函数逻辑完全错误,没正确完成棋盘状态的复制与恢复。之前还试过添加SetConsoleMode相关代码,但问题依然存在。以下是我的完整代码:

#include <iostream>
#include <Windows.h>
#include <io.h>
#include <fcntl.h>
#include <string>
using namespace std;

wstring  board[8][8] = {
    L"\033[31m♜ \033[0m", L"\033[31m♞ \033[0m", L"\033[31m♝ \033[0m", L"\033[31m♚ \033[0m", L"\033[31m♛ \033[0m", L"\033[31m♝ \033[0m", L"\033[31m♞ \033[0m", L"\033[31m♜ \033[0m",
    L"\033[31m♙ \033[0m", L"\033[31m♙ \033[0m", L"\033[31m♙ \033[0m", L"\033[31m♙ \033[0m", L"\033[31m♙ \033[0m", L"\033[31m♙ \033[0m", L"\033[31m♙ \033[0m", L"\033[31m♙ \033[0m",
    L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ",
    L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ",
    L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ",
    L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ",
    L"♙ ", L"♙ ", L"♙ ", L"♙ ", L"♙ ", L"♙ ", L"♙ ", L"♙ ",
    L"♖ ", L"♘ ", L"♗ ", L"♔ ", L"♕ ", L"♗ ", L"♘ ", L"♖ "
};
wstring* backboard = &board[8][8];
void SaveBoard() {
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            backboard = &board[8][8];
        }
    }
}
void Back() {
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
             board[8][8] = *backboard;
        }
    }
}
// board printing
void printBoard() {
    wcout << L"   A B C D E F G H" << endl;
    for (int i = 0; i < 8; i++) {
        wcout << 8 - i << L" |";
        for (int j = 0; j < 8; j++) {
            wcout << board[i][j];
        }
        wcout << L"| " << 8 - i << endl;
    }
    wcout << L"   A B C D E F G H" << endl;
}


// Moving 
bool movePiece(string from, string to) {
    
    int fromX = from[0] - 'A';    
    int fromY = 8 - (from[1] - '0'); 
    int toX = to[0] - 'A';
    int toY = 8 - (to[1] - '0');

    
    if (fromX < 0 || fromX >= 8 || fromY < 0 || fromY >= 8 || toX < 0 || toX >= 8 || toY < 0 || toY >= 8) {
        wcout << L"Wrong coordinates!" << endl;
        return false;
    }

    wstring piece = board[fromY][fromX];

    SaveBoard();

    board[toY][toX] = piece;
    board[fromY][fromX] = L"  ";

    return true;
}


int main() {
    _setmode(_fileno(stdout), _O_U16TEXT); // Setting for Unicode symbols
    SetConsoleCP(1251);     // u don`t need this since i translated everything
    SetConsoleOutputCP(1251);
    SetConsoleMode;
    ENABLE_VIRTUAL_TERMINAL_PROCESSING;
    string from, to;

    while (true) {
        printBoard();

        wcout << L"Move piece or use back/exit: ";
        cin >> from;

        if (from == "exit") break;
        if (from == "back") {
            Back();
            wcout << L"Returned." << endl;
            continue;
        
        }
        else {
            wcout << L"Not Returned. Try again." << endl;
        }
        cin >> to;

        if (!movePiece(from, to)) {
            wcout << L"Move didn`t work. Try again." << endl;
        }
    }

    return 0;
}

核心问题分析

  1. 备份棋盘定义错误:wstring* backboard = &board[8][8]; 中board[8][8]超出了8x8数组的索引范围(合法索引为0-7),指向无效内存,无法保存棋盘状态。
  2. SaveBoard函数逻辑无效:只是反复让backboard指向越界地址,完全没有复制棋盘内容。
  3. Back函数逻辑错误:仅操作越界的board[8][8],没有遍历棋盘恢复内容,且*backboard本身是无效值,导致棋盘清空。
  4. SetConsoleMode调用错误:原代码只是写了函数名和常量,没有正确调用函数,无法启用虚拟终端处理。
  5. 输入逻辑混乱:错误的else分支会跳过输入目标坐标的步骤,导致后续流程出错。

修复后的完整代码

#include <iostream>
#include <Windows.h>
#include <io.h>
#include <fcntl.h>
#include <string>
using namespace std;

wstring board[8][8] = {
    L"\033[31m♜ \033[0m", L"\033[31m♞ \033[0m", L"\033[31m♝ \033[0m", L"\033[31m♚ \033[0m", L"\033[31m♛ \033[0m", L"\033[31m♝ \033[0m", L"\033[31m♞ \033[0m", L"\033[31m♜ \033[0m",
    L"\033[31m♙ \033[0m", L"\033[31m♙ \033[0m", L"\033[31m♙ \033[0m", L"\033[31m♙ \033[0m", L"\033[31m♙ \033[0m", L"\033[31m♙ \033[0m", L"\033[31m♙ \033[0m", L"\033[31m♙ \033[0m",
    L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ",
    L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ",
    L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ",
    L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ", L"  ",
    L"♙ ", L"♙ ", L"♙ ", L"♙ ", L"♙ ", L"♙ ", L"♙ ", L"♙ ",
    L"♖ ", L"♘ ", L"♗ ", L"♔ ", L"♕ ", L"♗ ", L"♘ ", L"♖ "
};
// 定义和主棋盘同规格的备份数组
wstring backboard[8][8];

void SaveBoard() {
    // 逐格复制棋盘内容到备份
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            backboard[i][j] = board[i][j];
        }
    }
}

void Back() {
    // 逐格从备份恢复到主棋盘
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            board[i][j] = backboard[i][j];
        }
    }
}

// 打印棋盘
void printBoard() {
    wcout << L"   A B C D E F G H" << endl;
    for (int i = 0; i < 8; i++) {
        wcout << 8 - i << L" |";
        for (int j = 0; j < 8; j++) {
            wcout << board[i][j];
        }
        wcout << L"| " << 8 - i << endl;
    }
    wcout << L"   A B C D E F G H" << endl;
}

// 移动棋子
bool movePiece(string from, string to) {
    int fromX = from[0] - 'A';    
    int fromY = 8 - (from[1] - '0'); 
    int toX = to[0] - 'A';
    int toY = 8 - (to[1] - '0');

    if (fromX < 0 || fromX >= 8 || fromY < 0 || fromY >= 8 || toX < 0 || toX >= 8 || toY < 0 || toY >= 8) {
        wcout << L"坐标错误!" << endl;
        return false;
    }

    // 移动前先保存当前状态
    SaveBoard();

    board[toY][toX] = board[fromY][fromX];
    board[fromY][fromX] = L"  ";

    return true;
}

int main() {
    _setmode(_fileno(stdout), _O_U16TEXT); // 启用Unicode输出
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    
    // 正确启用虚拟终端处理,支持ANSI颜色
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD mode = 0;
    GetConsoleMode(hOut, &mode);
    SetConsoleMode(hOut, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);

    string from, to;

    while (true) {
        printBoard();

        wcout << L"输入移动指令(格式如A1 A2),或输入back回退、exit退出:";
        cin >> from;

        if (from == "exit") break;
        if (from == "back") {
            Back();
            wcout << L"已回退到上一步状态。" << endl;
            continue;
        }
        
        // 获取目标坐标
        cin >> to;

        if (!movePiece(from, to)) {
            wcout << L"移动失败,请重试。" << endl;
        }
    }

    return 0;
}

内容的提问来源于stack exchange,提问作者Сергій Дегтярьов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 17:49:59