基于c语言的象棋游戏

一、主要目标:

1.1:鼠标控制。

1.2:各棋子按照象棋规则移动

1.3:判断双方胜负

注:本设计使用vs-2017运行。需要下载graphics.h库。

二、基本流程

2.1 棋牌展示

 直接输出棋盘背景图片,包含方格线、“楚河”、“汉界”等,代码如下:

    loadimage(&img, "C:/Users/ASUS/Desktop/shess/5.jpg");
    putimage(0, 0, &img);//输出棋盘

该地址下放如图所示2.1所示图片充当背景。

                                                        图2.1 棋盘背景图片

 

2.3.2 棋子展示

    按照象棋棋子的摆法,在指定坐标出画出棋子(先画圆圈,再写字,每个棋子都如此)。

2.3.3 各棋子子移动

俥,马,象,士,炮,将,兵分别写移动规则(根据起始坐标和目的坐标判断是否可以移动)。

2.3.4 判断胜负

棋盘信息没改变一次就扫描一次棋盘,如果一方的将被覆盖(被对方所吃),则输出另一方获胜。游戏结束。

完整代码:

#include<stdio.h>
#include<graphics.h>
#include<math.h>
void execute(int a, int b, int c, int d);
bool jiang(int a, int b, int  c, int d);
bool pao(int a, int b, int c, int d);
bool ma(int a, int b, int c, int d);
IMAGE img;
#define distance  35//窗口线与棋盘边界线的距离
#define   longth  65//棋盘方格的长
#define   high   61//棋盘方格的宽
struct movecoordinate
{
    long x;
    long y;
};
struct  Chesscoordinate//棋子综合信息
{
    int x;
    int y;
    DWORD type;  //颜色
    bool river;//是否过河
    int id;
};
enum pieces
{
    SPACE = -1,
    車, 馬, 象, 士, 将, 炮, 卒,
    车, 马, 相, 仕, 帥, 砲, 兵,
    BEGIN, END,

};
enum pieces redchess[] = { 車,馬,象,士,将,炮,卒, };
enum pieces blackchess[] = { 车,马,相,仕,帥,砲,兵, };
enum pieces state = BEGIN;
struct move {  //鼠标选中的棋子
    int beginx;
    int beginy;
    int endx;
    int endy;
    int state;
}moving = { -1,-1,-1,-1,BEGIN };
const char* chessname[] = { "車","馬","象","士","将","炮","卒","车","马","相","仕","帥","砲","兵", };
struct Chesscoordinate  map[9][10];//坐标
struct Chesscoordinate  AImap[9][10];//坐标
movecoordinate begin = { -1,-1 }, end = { -1,-1 };
int  xx(int a)//数组下标转换成坐标
{
    a = distance + longth * a;
    return a;
}
int  yy(int a)
{
    a = distance + high * a;
    return a;
}
void begining()
{
    loadimage(&img, "C:/Users/ASUS/Desktop/shess/66.jpg");
    initgraph(img.getwidth(), img.getheight(), 1);
    putimage(0, 0, &img);//输出开始界面;

}
void  qiban()
{
    loadimage(&img, "C:/Users/ASUS/Desktop/shess/5.jpg");
    initgraph(img.getwidth(), img.getheight(), 1);
    putimage(0, 0, &img);//输出棋盘
}
void  coord()//棋子信息赋值
{
    loadimage(&img, "C:/Users/ASUS/Desktop/shess/5.jpg");
    putimage(0, 0, &img);//输出棋盘

    for (int i = 0; i <= 8; i++)
    {

        for (int j = 0; j <= 9; j++)//遍历二维数组
        {
            enum pieces chessid = SPACE;//先把全部位置的id赋值为SAPCE
            DWORD  chesstype;//定义颜色中间变量
            if (j <= 4)
            {
                chesstype = BLACK;//黑方
                if (j == 0)
                {
                    if (i <= 4)
                    {
                        chessid = blackchess[i];//
                    }
                    else
                    {
                        chessid = blackchess[8 - i];
                    }

                }
                if (j == 2 && (i == 1 || i == 7))
                {
                    chessid = blackchess[5];

                }

                if (j == 3 && (i == 0 || i == 2 || i == 4 || i == 4 || i == 6 || i == 8))
                {
                    chessid = blackchess[6];
                }

            }
            else
            {
                chesstype = RED;//红方
                if (j == 6 && (i == 0 || i == 2 || i == 4 || i == 6 || i == 8))
                {
                    chessid = redchess[6];
                }
                if (j == 7 && (i == 1 || i == 7))
                {
                    chessid = redchess[5];

                }

                if (j == 9)
                {

                    if (i <= 4)
                    {
                        chessid = redchess[i];
                    }
                    else
                    {
                        chessid = redchess[8 - i];
                    }
                }

            }//依次赋值
            map[i][j].id = chessid;
            map[i][j].river = false;
            map[i][j].type = chesstype;
            map[i][j].x = distance + longth * i;
            map[i][j].y = distance + high * j;

        }
    }
    for (int i = 0; i <= 8; i++)
    {
        for (int j = 0; j <= 9; j++)
        {
            if (map[i][j].id == SPACE)
            {
                map[i][j].type = YELLOW;
            }
        }
    }

}
void getbackground() //画棋子
{
    int x_start, y_start;
    x_start = distance;
    y_start = distance;

    settextstyle(30, 0, "黑体");//棋子大小颜色
    setbkmode(0);
    for (int i = 0; i <= 8; i++)
    {

        for (int j = 0; j <= 9; j++)
        {

            if (map[i][j].id != SPACE)//在棋盘上输出
            {
                setfillcolor(RGB(253, 216, 161));
                //    setlinestyle(BLACK);
                settextcolor(map[i][j].type);
                fillcircle(map[i][j].x, map[i][j].y, 24);
                fillcircle(map[i][j].x, map[i][j].y, 18);
                outtextxy(map[i][j].x - 13, map[i][j].y - 13, chessname[map[i][j].id]);

            }
        }
    }

}
void movechess(int a, int b, int c, int d)//移动棋子,改变其坐标
{

    map[c][d].id = map[a][b].id;
    map[c][d].river = map[a][b].river;
    map[c][d].type = map[a][b].type;
    map[c][d].x = xx(c);
    map[c][d].y = yy(d);
    map[a][b].id = SPACE;
    map[a][b].type = YELLOW;


}

void MouseControl()//获取鼠标点击信息并完响应
{
    //getbackground();
    if (MouseHit())
    {

        float beginrow, beginrol, endrow, endrol;//第一次按下时的坐标
        int intbeginrow, intbeginrol, intendrow, intendrol;//第二次按下时的坐标
        MOUSEMSG msg = GetMouseMsg();
        if (msg.uMsg == WM_LBUTTONDOWN)
        {
            //获取鼠标点击的数组的下标
        //    printf("(%d,%d)", msg.x, msg.y);
            beginrow = (float)(msg.x - distance) / longth;
            beginrol = (float)(msg.y - distance) / high;
            intbeginrow = round(beginrow);
            intbeginrol = round(beginrol);
            if (moving.state == BEGIN)
            {
                moving.state = END;
                moving.beginx = intbeginrow;
                moving.beginy = intbeginrol;
                //    printf("(%d,%d)  \n", moving.beginx, moving.beginy);
            }
            else if (moving.state == END)
            {

                moving.state = BEGIN;
                moving.endx = intbeginrow;
                moving.endy = intbeginrol;

                execute(moving.beginx, moving.beginy, moving.endx, moving.endy);


            }


        }

    }

}


int  win()
{
    int redgeneral = 0;
    int blackgeneral = 0;
    for (int i = 0; i <= 8; i++)
    {
        for (int j = 0; j <= 9; j++)
        {
            if (map[i][j].id == blackchess[4])
            {
                blackgeneral++;
            }
            else if (map[i][j].id == redchess[4])
            {
                redgeneral++;
            }
            else
            {
                blackgeneral = blackgeneral;
                redgeneral = redgeneral;
            }
        }
    }

    //printf("%d %d\n", blackgeneral, redgeneral);

    if (blackgeneral == 0)
    {
        return 0;

    }
    else if (redgeneral == 0)
    {

        return 1;
    }
    else
    {
        return 2;
    }


}
bool jiang(int a, int b, int  c, int d)//判断是否只移动了一格(将军、兵的规则)
{

    float h;
    h = sqrt(abs(d - b)*abs(d - b) + abs(c - a)*abs(c - a));
    if (b < 4 && c > 2 && c < 6 && d < 3)
    {
        if (h == 1 && map[c][d].type != map[a][b].type)
            return true;
        else
            return false;
    }
    if (b > 4 && c > 2 && c < 6 && d >6)
    {
        if (h == 1 && map[c][d].type != map[a][b].type)
            return true;
        else
            return false;
    }
    else
    {
        return false;
    }

}
bool bing(int a, int b, int c, int d)
{
    float h;
    h = sqrt(abs(d - b)*abs(d - b) + abs(c - a)*abs(c - a));
    if (map[a][b].type == BLACK)
    {
        if (map[a][b].river == false)
        {
            if (d == b + 1 && h == 1 && map[c][d].type != map[a][b].type)
            {
                return true;

            }
            else
            {
                return false;
            }
        }
        else
        {
            if (d >= b && h == 1 && map[c][d].type != map[a][b].type)
            {
                return true;

            }
            else
            {
                return false;
            }
        }
    }
    else if (map[a][b].type == RED)
    {
        if (map[a][b].river == false)
        {
            if (d == b - 1 && h == 1 && map[c][d].type != map[a][b].type)
            {
                return true;

            }
            else
            {
                return false;
            }
        }
        else
        {
            if (d <= b && h == 1 && map[c][d].type != map[a][b].type)
            {
                return true;

            }
            else
            {
                return false;
            }
        }
    }
    else
    {
        return false;
    }
}
bool pao(int a, int b, int c, int d)//炮的移动
{
    if (c == a && d != b)
    {
        int time = 0;
        int max = d > b ? d : b;
        int min = b < d ? b : d;
        for (int i = min; i <= max; i++)
        {
            if (map[c][i].id != SPACE)
            {
                time++;
            }

        }
        //    printf("%d\n", time);
        if (map[c][d].id == SPACE)
        {
            if (time == 1)
                return  true;
            else
                return false;
        }
        if (map[c][d].id != SPACE)
        {

            if (time != 3)
            {
                return false;
            }
            else
            {
                if (map[c][d].type == map[a][b].type)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }


        }

    }
    else if (d == b && c != a)
    {
        int time = 0;
        int max = a > c ? a : c;
        int min = c < a ? c : a;
        for (int i = min; i <= max; i++)
        {
            if (map[i][d].id != SPACE)
            {
                time++;
            }
        }
        //    printf("%d\n", time);
        if (map[c][d].id == SPACE)
        {
            if (time == 1)
                return  true;
            else
                return false;
        }
        if (map[c][d].id != SPACE)
        {

            if (time != 3)
            {
                return false;
            }
            else
            {
                if (map[c][d].type == map[a][b].type)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }


        }
    }
    else
    {
        return false;
    }
}
bool che(int a, int b, int c, int d)
{

    if (c == a && d != b)//是否为直线
    {

        int time = 0;
        int max = d > b ? d : b;
        int min = b < d ? b : d;
        for (int i = min; i <= max; i++)//遍历路径
        {


            if (map[c][i].id != SPACE)
            {
                time++;
            }


        }
        //    printf("%d", time);
        if (time == 1)//车移动不吃棋子
        {
            return true;

        }
        if (time == 2)//车移动并且吃目的坐标的棋子
        {
            if (map[c][d].type == map[a][b].type)//如果是目的坐标是自己的棋子,则返回false
            {
                return false;
            }
            if (map[c][d].type == YELLOW)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        else
        {
            return false;
        }
    }
    else    if (d == b && c != a)
    {
        int time = 0;
        int max = c > a ? c : a;
        int min = a < c ? a : c;
        for (int i = min; i <= max; i++)//遍历路径
        {
            if (map[i][d].id != SPACE)
            {
                time++;
            }

        }
        //    printf("%d", time);
        if (time == 1)//车是否车跳棋
        {
            return true;
        }
        else if (time == 2)
        {
            if (map[c][d].type == map[a][b].type)
            {
                return false;
            }
            if (map[c][d].type == YELLOW)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        else
        {
            return false;
        }
    }
    else
    {
        return 0;
    }
}
bool ma(int a, int b, int c, int d)
{
    float h;
    h = sqrt(abs(d - b)*abs(d - b) + abs(c - a)*abs(c - a));
    //    printf("%f", h);
    if (h <= 2 || h >= 2.5)//根号8=2.8.根号5=2.2
    {
        //    printf("太远了!\n");
        return  false;
    }
    else
    {
        int xx, yy, max, min;//关键点的坐标和中间值
        max = abs(d - b) > abs(c - a) ? abs(d - b) : abs(c - a);
        min = abs(c - a) < abs(d - b) ? abs(c - a) : abs(d - b);
        //printf("max\min:(%d,%d)", max, min);
        if (max == abs(d - b))
        {
            yy = b + (d - b) / 2;
            xx = a;
        }
        else
        {
            xx = a + (c - a) / 2;
            yy = b;
        }
        //    printf("xx\yy:(%d,%d)\n", xx, yy);
        if (map[xx][yy].id == SPACE)
        {
            if (map[c][d].type != map[a][b].type)
            {
                //    printf("目的坐标(%d,%d)\n", c, d);
                //    printf("那是你自己的棋子!\n");
                return true;
            }
            else
            {
                //    printf("那是你的棋子!\n");
                return false;
            }

        }
        else
        {
            //    printf("关键位置有棋子!\n");
            return false;
        }
    }
}
bool xiang(int a, int b, int c, int d)
{

    float h;
    h = sqrt(abs(d - b)*abs(d - b) + abs(c - a)*abs(c - a));
    if (b <= 4)
    {
        if (d > 4)
        {
            return false;
        }
        else
        {
            if (h<2.4 || h>2.9)
            {
                return false;
            }
            else
            {
                int xx = (a + c) / 2;
                int yy = (b + d) / 2;
                if (map[xx][yy].id == SPACE)
                {
                    if (map[c][d].type == map[a][b].type)
                    {
                        return false;
                    }
                    else
                    {
                        return true;

                    }
                }
                else
                {
                    return false;
                }
            }
        }

    }
    else
    {
        if (d < 5)
        {
            return false;
        }
        else
        {
            if (h<2.4 || h>2.9)
            {
                return false;
            }
            else
            {
                int xx = (a + c) / 2;
                int yy = (b + d) / 2;
                if (map[xx][yy].id == SPACE)
                {
                    if (map[c][d].type == map[a][b].type)
                    {
                        return false;
                    }
                    else
                    {
                        return true;

                    }
                }
                else
                {
                    return false;
                }
            }
        }
    }


}
bool shi(int a, int b, int c, int d)
{
    float h = sqrt(abs(d - b)*abs(d - b) + abs(c - a)*abs(c - a));
    //  printf("%f", h)

    if (b < 5)
    {
        if (c >= 3 && c <= 5 && d <= 2)
        {

            if (1.2 < h &&h < 1.5)
            {
                if (map[c][d].type != map[a][b].type)
                    return true;
                else
                    return false;

            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }
    else if (b > 5)
    {
        if (c >= 3 && c <= 5 && d >= 7)
        {

            if (1.2 < h &&h < 1.5)
            {
                if (map[c][d].type != map[a][b].type)
                    return true;
                else
                    return false;

            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }
    else
        return false;
}
void execute(int a, int b, int c, int d)//行棋
{
    if (map[a][b].id == blackchess[4])//黑方将
    {
        if (jiang(a, b, c, d))
        {

            movechess(a, b, c, d);

        }
        else
        {
            printf("你不能这样做\n");
        }

    }
    else if (map[a][b].id == redchess[4])//红方将
    {

        if (jiang(a, b, c, d))
        {
            movechess(a, b, c, d);
        }
        else
        {
            printf("你不能这样做!\n");
        }
    }

    else if (map[a][b].id == blackchess[6])//黑方兵
    {
        if (map[a][b].river == false)
        {
            if (bing(a, b, c, d))
            {
                movechess(a, b, c, d);

                if (d > 4)
                {
                    map[c][d].river = true;
                }
            }
            else
            {
                printf("你不可以这样做!\n");
            }
        }
        else
        {
            if (bing(a, b, c, d) && d >= b)
            {
                movechess(a, b, c, d);

            }
            else
            {
                printf("你不可以这样做\n");
            }
        }
    }
    else if (map[a][b].id == redchess[6])//红方兵
    {
        if (map[a][b].river == false)
        {
            if (bing(a, b, c, d))
            {
                movechess(a, b, c, d);

                if (d < 5)
                {
                    map[c][d].river = true;
                }
            }
            else
            {
                printf("你不可以这样做!\n");
            }
        }
        else
        {
            if (bing(a, b, c, d) && d <= b)
            {
                movechess(a, b, c, d);

            }
            else
            {
                printf("你不可以这样做!\n");
            }
        }
    }
    else if (map[a][b].id == blackchess[5] || map[a][b].id == redchess[5])
    {
        if (pao(a, b, c, d))
        {
            movechess(a, b, c, d);

        }
        else
        {
            printf("你不能这样做!\n");
        }

    }
    else if (map[a][b].id == blackchess[0] || map[a][b].id == redchess[0])
    {
        if (che(a, b, c, d))
        {
            movechess(a, b, c, d);

        }
        else
        {
            printf("你不可以这样做!\n");
        }
    }
    else if (map[a][b].id == blackchess[1] || map[a][b].id == redchess[1])
    {


        if (ma(a, b, c, d))
        {
            movechess(a, b, c, d);


        }
        else
        {
            printf("你不能这样做!\n");
        }

    }
    else if (map[a][b].id == blackchess[2] || map[a][b].id == redchess[2])
    {
        if (xiang(a, b, c, d))
        {
            movechess(a, b, c, d);

        }
        else
            printf("你不能这样做!\n");

    }
    else if (map[a][b].id == blackchess[3])
    {
        if (shi(a, b, c, d))
        {
            movechess(a, b, c, d);

        }
        else
            printf("你不能这样做!");
    }
    else if (map[a][b].id == redchess[3])
    {
        if (shi(a, b, c, d))
        {
            movechess(a, b, c, d);

        }
        else
            printf("你不能这样做!");
    }
}
int main()
{
    begining();
    while (1)
    {
        coord();//输出棋盘
        win();
        BeginBatchDraw();
        while (win() == 2)
        {
            win();
            putimage(0, 0, &img);
            getbackground();//输出棋子
            MouseControl();//鼠标更改数据
            FlushBatchDraw();

        }

        putimage(0, 0, &img);
        getbackground();//输出棋子
        MouseControl();//鼠标更改数据
        FlushBatchDraw();
        if (win() == 0)
        {
            printf("红方胜!\n");
        }
        else if (win() == 1)
        {
            printf("黑方胜!\n");

        }
    }
    getchar();

    return 0;
}

注意:由于棋子是根据所选棋盘图片的大小、在指定位置画棋子。棋盘的不一样会导致棋子位置不正确。读者可直接将该棋盘复制,将图片修改成和我一样的比例,如图2.2.

               

                                    图2.2 棋盘背景图片大小

读者也可以自己选择背景图片,根据图片大小,更改该代码宏定义处的distance、longth、high的值,保证棋子落在正确的位置上。另外包含人机部分的代码已上传到我的另一篇博客,请需要的自提。

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值