象棋来了(象棋的c代码,比较基础)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>

// 棋子类型枚举
typedef enum {
    GENERAL,    // 将/帅
    ADVISOR,    // 士/仕
    ELEPHANT,   // 象/相
    HORSE,      // 马/傌
    CHARIOT,    // 车/俥
    CANNON,     // 炮/炮
    SOLDIER     // 卒/兵
} PieceType;

// 棋子颜色枚举
typedef enum {
    RED,    // 红方
    BLACK   // 黑方
} PieceColor;

// 棋子结构体
typedef struct {
    PieceType type;
    PieceColor color; 
    int x;          // 横坐标(0-9)
    int y;          // 纵坐标(0-8)
    bool alive;     //是否存活
} ChessPiece;

// 棋盘结构体
typedef struct {
    ChessPiece pieces[32]; //棋子结构体数组用于装棋子的信息
    ChessPiece* board[10][9];  // 棋子结构体指针二维数组 用于装载棋子所在棋盘的位置
    int isRedTurn;//当前回合
    int isGameOver;//游戏是否结束
    int moveCount;//移动计数
} ChessBoard;

// 初始化棋子
void init_piece(ChessPiece* piece, PieceType type, PieceColor color, int x, int y) {
    piece->type = type;
    piece->color = color;
    piece->x = x;
    piece->y = y;
    piece->alive = 1;
}

// 初始化棋盘
void init_board(ChessBoard* board) {
    memset(board->board, 0, sizeof(board->board));
    board->isRedTurn = 1;
    board->isGameOver = 1;
    board->moveCount = 0;
    
    // 红方棋子(索引0-15)
    init_piece(&board->pieces[0], CHARIOT, RED, 9, 0);
    init_piece(&board->pieces[1], HORSE, RED, 9, 1);
    init_piece(&board->pieces[2], ELEPHANT, RED, 9, 2);
    init_piece(&board->pieces[3], ADVISOR, RED, 9, 3);
    init_piece(&board->pieces[4], GENERAL, RED, 9, 4);
    init_piece(&board->pieces[5], ADVISOR, RED, 9, 5);
    init_piece(&board->pieces[6], ELEPHANT, RED, 9, 6);
    init_piece(&board->pieces[7], HORSE, RED, 9, 7);
    init_piece(&board->pieces[8], CHARIOT, RED, 9, 8);
    init_piece(&board->pieces[9], CANNON, RED, 7, 1);
    init_piece(&board->pieces[10], CANNON, RED, 7, 7);
    init_piece(&board->pieces[11], SOLDIER, RED, 6, 0);
    init_piece(&board->pieces[12], SOLDIER, RED, 6, 2);
    init_piece(&board->pieces[13], SOLDIER, RED, 6, 4);
    init_piece(&board->pieces[14], SOLDIER, RED, 6, 6);
    init_piece(&board->pieces[15], SOLDIER, RED, 6, 8);
    
    // 黑方棋子(索引16-31)
    init_piece(&board->pieces[16], CHARIOT, BLACK, 0, 0);
    init_piece(&board->pieces[17], HORSE, BLACK, 0, 1);
    init_piece(&board->pieces[18], ELEPHANT, BLACK, 0, 2);
    init_piece(&board->pieces[19], ADVISOR, BLACK, 0, 3);
    init_piece(&board->pieces[20], GENERAL, BLACK, 0, 4);
    init_piece(&board->pieces[21], ADVISOR, BLACK, 0, 5);
    init_piece(&board->pieces[22], ELEPHANT, BLACK, 0, 6);
    init_piece(&board->pieces[23], HORSE, BLACK, 0, 7);
    init_piece(&board->pieces[24], CHARIOT, BLACK, 0, 8);
    init_piece(&board->pieces[25], CANNON, BLACK, 2, 1);
    init_piece(&board->pieces[26], CANNON, BLACK, 2, 7);
    init_piece(&board->pieces[27], SOLDIER, BLACK, 3, 0);
    init_piece(&board->pieces[28], SOLDIER, BLACK, 3, 2);
    init_piece(&board->pieces[29], SOLDIER, BLACK, 3, 4);
    init_piece(&board->pieces[30], SOLDIER, BLACK, 3, 6);
    init_piece(&board->pieces[31], SOLDIER, BLACK, 3, 8);
    
    // 将棋子放置到棋盘上
    for (int i = 0; i < 32; i++) {
        ChessPiece* piece = &board->pieces[i];
        board->board[piece->x][piece->y] = piece;
    }
}

// 获取棋子名称(中文)
 char* get_piece_name(ChessPiece* piece) {
    if (piece == NULL || !piece->alive) return 0 ;
    
     char* names[2][7] = {
        {"帅", "仕", "相", "马", "车", "炮", "兵"}, // 红方
        {"将", "士", "象", "马", "车", "炮", "卒"}  // 黑方
    };
    
    return names[piece->color][piece->type];
}

// 绘制标准象棋棋盘
void draw_board(ChessBoard* board) {
    printf("\n");
    printf("  0  1  2  3  4  5  6  7  8"); 
    printf("\n");
    for (int x = 0; x < 10; x++) 
    {
        printf("%d ",x);
        for (int y = 0; y< 9; y++) 
        {
            ChessPiece* piece = board->board[x][y];
            if (piece != NULL && piece->alive) 
            {
                if (piece->color == RED) {
                    printf("\033[47;31m%s\033[0m ", get_piece_name(piece));
                } else {
                    printf("\033[47;30m%s\033[0m ", get_piece_name(piece));
                }
            } 
            else printf(" + ");
        }
        printf("\n");
        // 楚河汉界标记
        if (x == 4)
        {
            printf("     楚  河");
            printf("        汉  界");
            printf("\n");
        }
      }
        
    printf("回合: %s方  步数: %d\n", board->isRedTurn ? "红" : "黑", board->moveCount);
}


// 检查坐标是否有效
int is_valid_position(int x, int y) {
    return x >= 0 && x < 10 && y >= 0 && y < 9;
}


// 车移动规则验证
int is_valid_chariot_move(ChessBoard* board, int fromX, int fromY, int toX, int toY) {
    if (fromX != toX && fromY != toY) return 0;
    
    int step, i;
    //判断原坐标与目标中间有没有其他棋子
    if (fromX == toX) {
        step = (fromY < toY) ? 1 : -1;
        for (i = fromY + step; i != toY; i += step) {
            if (board->board[fromX][i] != NULL && board->board[fromX][i]->alive) {
                return 0;
            }
        }
    } else {
        step = (fromX < toX) ? 1 : -1;
        for (i = fromX + step; i != toX; i += step) {
            if (board->board[i][fromY] != NULL && board->board[i][fromY]->alive) {
                return 0;
            }
        }
    }
    return 1;
}

// 炮移动规则验证
int is_valid_cannon_move(ChessBoard* board, int fromX, int fromY, int toX, int toY) {
    if (fromX != toX && fromY != toY) return 0;
    
    int step, i,count=0;
    //判断原坐标与目标中间有没有其他棋子
    if (fromX == toX) {
        step = (fromY < toY) ? 1 : -1;
        for (i = fromY + step; i != toY; i += step) {
            if (board->board[fromX][i] != NULL && board->board[fromX][i]->alive) {
               count++;
            }
        }
    } else {
        step = (fromX < toX) ? 1 : -1;
        for (i = fromX + step; i != toX; i += step) {
            if (board->board[i][fromY] != NULL && board->board[i][fromY]->alive) {
                count++;
            }
        }
    }
    ChessPiece *fromPiece=board->board[fromX][fromY];
    ChessPiece *toPiece = board->board[toX][toY];
    if(count==0)
    {
        if(toPiece==NULL)return 1;
    }
    if(count==1)
    {
        if(toPiece->color!=fromPiece->color) return 1;
    }
    return 0;
}

// 马移动规则验证
int is_valid_horse_move(ChessBoard* board, int fromX, int fromY, int toX, int toY) {
    int dx = abs(toX - fromX);
    int dy = abs(toY - fromY);
    
    if (!((dx == 2 && dy == 1) || (dx == 1 && dy == 2))) return 0;
    
    // 检查马脚
    // 上下方向有没有棋子
    if (dx == 2) {
        int middleX = fromX + (toX > fromX ? 1 : -1);
        if (board->board[middleX][fromY] != NULL && board->board[middleX][fromY]->alive) {
            return 0;
        }
    }
    //左右方向有没有棋子
    else 
    {
        int middleY = fromY + (toY > fromY ? 1 : -1);
        if (board->board[fromX][middleY] != NULL && board->board[fromX][middleY]->alive) {
            return 0;
        }
    }
    return 1;
}

// 象移动规则验证
int is_valid_elephant_move(ChessBoard* board, int fromX, int fromY, int toX, int toY, bool isRed) {
    int dx = abs(toX - fromX);
    int dy = abs(toY - fromY);
    
    if (dx != 2 || dy != 2) return 0;
    
    // 检查象眼
    int middleX = (fromX + toX) / 2;
    int middleY = (fromY + toY) / 2;
    if (board->board[middleX][middleY] != NULL && board->board[middleX][middleY]->alive) {
        return 0;
    }
    
    // 象不能过河
    if (isRed && toX < 5) return 0;
    if (!isRed && toX > 4) return 0;
    
    return 1;
}

// 士移动规则验证
int is_valid_advisor_move(int fromX, int fromY, int toX, int toY, bool isRed) {
    int dx = abs(toX - fromX);
    int dy = abs(toY - fromY);
    
    
    // 士只能在九宫格内移动
    if (toY < 3 || toY > 5) return 0;

    if (dx != 1 || dy != 1) return 0;

    if (isRed) {
        return toX >= 7 && toX <= 9;
    } else {
        return toX >= 0 && toX <= 2;
    }
}

// 将帅移动规则验证
int is_valid_general_move(int fromX, int fromY, int toX, int toY, bool isRed) {
    int dx = abs(toX - fromX);
    int dy = abs(toY - fromY);
    
    // 将帅只能在九宫格内移动
    if (toY < 3 || toY > 5) return 0;
    if (isRed) {
        if (toX < 7 || toX > 9) return 0;
    } else {
        if (toX < 0 || toX> 2) return 0;
    }
    
    // 将帅只能走一步
    if ((dx == 1 && dy == 0) || (dx == 0 && dy == 1)) {
        return 1;
    }
    
    return 0;
}


// 兵卒移动规则验证
int is_valid_soldier_move(int fromX, int fromY, int toX, int toY, bool isRed) {
    int dx = toX - fromX;
    int dy = toY - fromY;
    
    if (isRed) {
        // 红方兵向上移动
        if (dx == -1 && dy == 0) return 1; // 向前
        if (fromX < 5 && (dx == -1 || dx == 0)) return 1; // 过河后可以横向移动
    } else {
        // 黑方卒向下移动
        if (dx == 1 && dy == 0) return 1; // 向前
        if (fromX > 4 &&(dx == 1 || dx == 0 )) return 1; // 过河后可以横向移动
    }
    
    return 0;
}

// 检查移动是否合法
int is_valid_move(ChessBoard* board, int fromX, int fromY, int toX, int toY) {
    // 检查坐标是否有效
    if (!is_valid_position(fromX, fromY) || !is_valid_position(toX, toY)) {
        return 0;
    }
    
    ChessPiece* fromPiece = board->board[fromX][fromY];
    ChessPiece* toPiece = board->board[toX][toY];
    
    // 检查是否有棋子可移动
    if (fromPiece == NULL || !fromPiece->alive) {
        return 0;
    }
    
    // 检查是否轮到当前玩家
    if (fromPiece->color == RED && !board->isRedTurn) return 0;
    if (fromPiece->color == BLACK && board->isRedTurn) return 0;
    
    // 检查目标位置是否有己方棋子
    if (toPiece != NULL && toPiece->alive && toPiece->color == fromPiece->color) {
        return 0;
    }
    
    // 根据不同棋子类型检查移动规则
    switch (fromPiece->type) {
        case CHARIOT:
            return is_valid_chariot_move(board, fromX, fromY, toX, toY);
        case HORSE:
            return is_valid_horse_move(board, fromX, fromY, toX, toY);
        case CANNON:
            return is_valid_cannon_move(board, fromX, fromY, toX, toY);
        case ELEPHANT:
            return is_valid_elephant_move(board, fromX, fromY, toX, toY, fromPiece->color == RED);
        case ADVISOR:
            return is_valid_advisor_move(fromX, fromY, toX, toY, fromPiece->color == RED);
        case GENERAL:
            return is_valid_general_move(fromX, fromY, toX, toY, fromPiece->color == RED);
        case SOLDIER:
            return is_valid_soldier_move(fromX, fromY, toX, toY, fromPiece->color == RED);
        default:
            return 0;
    }
}

// 移动棋子
int move_piece(ChessBoard* board, int fromX, int fromY, int toX, int toY) {
    if (!is_valid_move(board, fromX, fromY, toX, toY)) 
    {
        printf("无效移动!\n");
        return 0;
    }
   
    ChessPiece* fromPiece = board->board[fromX][fromY];
    ChessPiece* toPiece = board->board[toX][toY];
    
    // 执行移动
    if (toPiece != NULL) 
    {
        toPiece->alive = 0;  // 吃掉对方棋子
        if(toPiece->type==GENERAL)
        {
            printf("%s方已死,游戏结束!\n",board->isRedTurn?"黑":"红");
            board->isGameOver=0;
        }
    }
    board->board[fromX][fromY] = NULL;
    board->board[toX][toY] = fromPiece;
    fromPiece->x = toX;
    fromPiece->y = toY;
    
    // 切换玩家
    board->isRedTurn = !board->isRedTurn;
    board->moveCount++;
    return 1;
}

int main() {
    ChessBoard board;
    init_board(&board);
    printf("********* 开始游戏!*********\n");
// 主游戏循环
   while (board.isGameOver) 
   {
        printf("********* 象棋游戏!*********\n");
        draw_board(&board);
           printf("输入格式: 起始行列 目标行列 (如: 51 52)\n");
        printf("%s方走棋 > ", board.isRedTurn ? "红" : "黑");
        int fromCol, fromRow, toCol, toRow;
        if (scanf("%1d%1d %1d%1d", &fromRow, &fromCol, &toRow, &toCol) != 4) {
            printf("输入格式错误!\n");
            continue;
        }
        
        if (!move_piece(&board, fromRow, fromCol, toRow, toCol)) {
            printf("按回车键继续...");
            while (getchar() != '\n'); // 清除输入缓冲区
            getchar();
        }
        system("clear");
    }
    // 游戏结束显示
    draw_board(&board);
    printf("游戏结束!%s方获胜!\n", board.isRedTurn ? "红" : "黑");
    return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值