【实践小项目】如何用C语言实现下象棋

实现象棋的程序需要考虑到棋盘、棋子、走法规则等多个方面。下面是一个简单的C语言程序实现下象棋的示例:

#include <stdio.h>
#include <stdbool.h>

// 棋盘大小
#define BOARD_SIZE 10

// 棋子类型
#define CHESS_KING 1  // 将/帅
#define CHESS_ADVISOR 2  // 士
#define CHESS_ELEPHANT 3  // 象
#define CHESS_HORSE 4  // 马
#define CHESS_CHARIOT 5  // 车
#define CHESS_CANNON 6  // 炮
#define CHESS_SOLDIER 7  // 兵/卒

// 棋盘数组
int board[BOARD_SIZE][BOARD_SIZE] = {
    {5, 4, 3, 2, 1, 2, 3, 4, 5},
    {0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 6, 0, 0, 0, 0, 0, 6, 0},
    {7, 0, 7, 0, 7, 0, 7, 0, 7},
    {0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0},
    {7, 0, 7, 0, 7, 0, 7, 0, 7},
    {0, 6, 0, 0, 0, 0, 0, 6, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0},
    {5, 4, 3, 2, 1, 2, 3, 4, 5}
};

// 输出棋盘
void print_board() {
    for (int i = 0; i < BOARD_SIZE; i++) {
        for (int j = 0; j < BOARD_SIZE; j++) {
            printf("%d ", board[i][j]);
        }
        printf("\n");
    }
}

// 判断是否越界
bool is_out_of_bound(int x, int y) {
    return x < 0 || x >= BOARD_SIZE || y < 0 || y >= BOARD_SIZE;
}

// 判断是否是同一方棋子
bool is_same_side(int x1, int y1, int x2, int y2) {
    if (board[x1][y1] * board[x2][y2] > 0) {
        return true;
    }
    return false;
}

// 判断是否可以走棋
bool can_move(int x1, int y1, int x2, int y2) {
    if (is_out_of_bound(x1, y1) || is_out_of_bound(x2, y2)) {
        return false;
    }
    if (board[x1][y1] == 0 || is_same_side(x1, y1, x2, y2)) {
        return false;
    }
    // TODO: 添加

// 判断是否可以走棋
bool can_move(int x1, int y1, int x2, int y2) {
    if (is_out_of_bound(x1, y1) || is_out_of_bound(x2, y2)) {
        return false;
    }
    if (board[x1][y1] == 0 || is_same_side(x1, y1, x2, y2)) {
        return false;
    }
    int chess_type = abs(board[x1][y1]);
    switch (chess_type) {
        case CHESS_KING:
            if (x2 < 3 || x2 > 5 || y2 < 0 || y2 > 2 || abs(x1 - x2) + abs(y1 - y2) != 1) {
                return false;
            }
            break;
        case CHESS_ADVISOR:
            if (x2 < 3 || x2 > 5 || y2 < 0 || y2 > 2 || abs(x1 - x2) != 1 || abs(y1 - y2) != 1) {
                return false;
            }
            break;
        case CHESS_ELEPHANT:
            if (x2 < 0 || x2 > 8 || y2 < 0 || y2 > 8 || abs(x1 - x2) != 2 || abs(y1 - y2) != 2 || board[(x1 + x2) / 2][(y1 + y2) / 2] != 0) {
                return false;
            }
            break;
        case CHESS_HORSE:
            if ((abs(x1 - x2) == 1 && abs(y1 - y2) == 2 && board[x1][(y1 + y2) / 2] == 0) ||
                (abs(x1 - x2) == 2 && abs(y1 - y2) == 1 && board[(x1 + x2) / 2][y1] == 0)) {
                break;
            }
            return false;
        case CHESS_CHARIOT:
            if (x1 != x2 && y1 != y2) {
                return false;
            }
            if (x1 == x2) {
                int min_y = y1 < y2 ? y1 : y2;
                int max_y = y1 > y2 ? y1 : y2;
                for (int i = min_y + 1; i < max_y; i++) {
                    if (board[x1][i] != 0) {
                        return false;
                    }
                }
            } else {
                int min_x = x1 < x2 ? x1 : x2;
                int max_x = x1 > x2 ? x1 : x2;
                for (int i = min_x + 1; i < max_x; i++) {
                    if (board[i][y1] != 0) {
                        return false;
                    }
                }
            }
            break;
        case CHESS_CANNON:
            if (x1 != x2 && y1 != y2) {
                return false;
            }
            int count = 0;
            if (x1 == x2) {
                int min_y = y1 < y2 ? y1 : y2;
                int max_y = y1 > y2 ? y1 : y2;
                for (int i = min_y + 1; i < max_y; i++) {
                    if (board[x1][i] != 0) {
                        count

// 走棋
void move(int x1, int y1, int x2, int y2) {
    int chess = board[x1][y1];
    board[x2][y2] = chess;
    board[x1][y1] = 0;
}

// 悔棋
void undo_move(int x1, int y1, int x2, int y2, int chess) {
    board[x1][y1] = chess;
    board[x2][y2] = 0;
}

// 象棋搜索
int search(int depth, int alpha, int beta) {
    if (depth <= 0) {
        return evaluate();
    }
    int value;
    int count = generate_moves();
    for (int i = 0; i < count; i++) {
        int x1 = moves[i].x1;
        int y1 = moves[i].y1;
        int x2 = moves[i].x2;
        int y2 = moves[i].y2;
        int chess = board[x2][y2];
        move(x1, y1, x2, y2);
        if (is_checked(side)) {
            undo_move(x1, y1, x2, y2, chess);
            continue;
        }
        side = 1 - side;
        value = -search(depth - 1, -beta, -alpha);
        side = 1 - side;
        undo_move(x1, y1, x2, y2, chess);
        if (value >= beta) {
            return beta;
        }
        if (value > alpha) {
            alpha = value;
            if (depth == search_depth) {
                best_move = moves[i];
            }
        }
    }
    return alpha;
}

// 主函数
int main() {
    init_board();
    print_board();
    while (!game_over()) {
        if (side == 0) {
            // 电脑走棋
            search(search_depth, -1000000, 1000000);
            move(best_move.x1, best_move.y1, best_move.x2, best_move.y2);
            print_board();
        } else {
            // 玩家走棋
            printf("请输入要移动的棋子坐标和目标位置坐标(格式如 0 0 1 0):");
            int x1, y1, x2, y2;
            scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
            if (can_move(x1, y1, x2, y2)) {
                move(x1, y1, x2, y2);
                print_board();
            } else {
                printf("非法移动!\n");
            }
        }
    }
    printf("游戏结束!\n");
    return 0;
}

以上是一个基本的象棋程序框架,你可以根据需要进行修改和完善。注意,这只是一个简单的实现,可能存在许多不足之处,需要根据实际情况进行优化和改进。

猜你喜欢

转载自blog.csdn.net/m0_49107591/article/details/129634914
今日推荐