袅袅系秋风 发表于 2019-3-13 20:35

【c++】五子棋源码

之前发过这个帖子,不过当时是用来申请账号的,不过因为申请用户名是qq号所以没有申请成功,在那个区里没人看,现在开放注册了就在这里再发一遍吧,就当记录下自己的足迹

本人是一名学生,正好最近在做课程设计,使用c语言配合easyx图形库(想下载图形库的话百度搜索easyx就能找到了)编写了一个五子棋的小游戏


去年做课程设计,使用c语言配合easyx图形库(想下载的话百度搜索就能找到了)编写了一个五子棋的小游戏,由于是第一次发帖,做的有什
么不对的地方希望大家提下建议,源码我会放在链接内,有需要的可以下载
废话不说了,先上几张效果图

游戏进入界面

游戏的双人模式

单人模式(也就是人机,这里算是比较核心的了,因为比较懒,所以机器人的算法写的不太聪明{:1_905:},只判断了棋子个数,像相同的棋子个数不同的优先级,就没有判断,)

自己做的游戏大概流程图(有点难看,凑合着看吧:lol )


代码的话我就不讲解了,里面都有注释的,如果函数不知道是什么意思,可以百度查一下,都能搜到的
最后补充一下 ,我是用的vc++6.0编写的,如果用vs的话,字符串前好像要加“L”当做宽字符。

举个栗子:
vc++6.0中可以这样写:
MessageBox(h, "请游戏结束后重试", "提示信息", MB_OK);//弹出提示框


但在vs中需要这样写:
MessageBox(h, L"请游戏结束后重试", L"提示信息", MB_OK);//弹出提示框





下面上代码
#include<graphics.h>
#include<Windows.h>
#include<conio.h>
#include<stdio.h>


#definecolumn 19
#definerow 19
//函数声明
int judgement(int x, int y);
void drawchessboard();
void XiaQi();
int caculateValue(int r, int c, int who);
int MaxOfQuan(int r, int c);
void AIReboot();
int caculateValue(int r,int c,int who);
int MaxOfQuan(int r,int c);


//全局变量
IMAGE black, white, background, renren, surrender, renji,mainpicture;//图片全局变量
HWND h;//之后用来接受当前绘图窗口句柄
int turn = 0;//控制下棋 0都不能下1黑棋下2白棋下
int map = { 0 };//存储棋盘信息0没有棋子1黑棋2白棋
int chooseType = 0;//1为人人 2为人机
int gif = 0;//控制菜单处的贴图

struct quanzhi
{
      int hang, lie, yuoxie, zouxie;//存储四个方向相邻棋子数\ /   
};
quanzhi quan;//记录最优位置

void AIReboot()//机器人下棋
{
      memset(quan, 0, sizeof(quan));//数组置零
      int i, j,tmp,max1=0,a1=0,b1=0;
      for (i = 0; i < row; i++)//遍历棋盘
      {
                for (j = 0; j < column; j++)
                {
                        if (map != 0)
                              continue;
                        caculateValue(i,j,1);//计算敌方最优位置防御
                        tmp = MaxOfQuan(i, j);
                        if (max1 <tmp )
                        {
                              max1 = tmp;
                              a1 = i;
                              b1 = j;
                        }
                }
      }

      memset(quan, 0, sizeof(quan));
      int max2=0,a2=0,b2=0;
      for (i = 0; i < row; i++)
      {
                for (j = 0; j < column; j++)
                {
                        if (map != 0)
                              continue;
                        caculateValue(i,j,2);//计算己方最优位置进攻
                        tmp = MaxOfQuan(i, j);
                        if (max2 <tmp )
                        {
                              max2 = tmp;
                              a2 = i;
                              b2 = j;
                        }
                }
      }
      if(max2!=0&&max2>=max1)//攻击当己方与敌方最多相连棋子相同时 己方的优先级更大
      {
                putimage(b2*40, a2*40, &white);
                map=2;
                if (judgement(b2, a2) != 2)
                turn = 1;
      }
      else//防御
      {
                putimage(b1*40, a1*40, &white);
                map=2;
                if (judgement(b1, a1) != 2)
                turn = 1;

      }
      
      
                                       
}

int caculateValue(int r,int c,int who)//计算权值
{

      //计算行
      int sum = 0,i;
      for (i = 1; i < 5; i++)
      {
                if (c - i >= 0 && map == who)
                        sum++;
                if(map!=who)
                        break;
      }
      for (i = 1; i < 5; i++)
      {
                if (c + i < 19 && map == who)
                        sum++;
                if(map!=who)
                        break;
      }
      quan.hang = sum;


      //列
      sum = 0;
      for (i = 1; i < 5; i++)
      {
                if (r - i >= 0 && map == who)
                        sum++;
                if(map!=who)
                        break;
      }
      for (i = 1; i < 5; i++)
      {
                if (r + i < 19 && map == who)
                        sum++;
                if(map!=who)
                        break;
      }
      quan.lie = sum;


      //左斜
      sum = 0;
      for (i = 1; i < 5; i++)
      {
                if (r + i < 19 && c - i >= 0 && map == who)
                        sum++;
                if(map!=who)
                        break;
      }
      for (i = 1; i < 5; i++)
      {
                if (r - i >= 0 && c + i < 19 && map == who)
                        sum++;
                if(map!=who)
                        break;
               
      }
      quan.zouxie = sum;


      //右斜
      sum = 0;
      for (i = 1; i < 5; i++)
      {
                if (r - i >= 0 && c - i >= 0 && map == who)
                        sum++;
                if(map!=who)
                        break;
      }
      for (i = 1; i < 5; i++)
      {
                if (r + i < 19 && c + i < 19 && map == who)
                        sum++;
                if(map!=who)
                        break;
      }
      quan.yuoxie = sum;
      return 0;
}

int MaxOfQuan(int r,int c)
{
      int max = max(quan.hang, max(quan.lie, max(quan.yuoxie, quan.zouxie)));
      
      return max;
      
}

void drawchessboard()//绘制棋盘
{
      int i, j;
      cleardevice();//清屏
      putimage(0, 0, &background);//贴背景图、菜单图
      putimage(780, 100, 200, 55, &renren, 298, 85);
      putimage(780, 200, 200, 55, &renji, 298, 85);
      putimage(780, 300, 200, 55, &surrender, 298, 85);

      setlinecolor(BLACK);//设置线的颜色为黑色
      for (i = 1, j = 1; j < 20; i += 2, j++)//绘制19x19棋盘
      {
                line(20, 20 * i, 40 * column - 20, 20 * i);
                line(20 * i, 20, 20 * i, 40 * row - 20);
      }
}
void XiaQi()
{
      MOUSEMSG m;//鼠标
      while (1)
      {
                m = GetMouseMsg();//获取鼠标信息
                switch (m.uMsg)
                {
                case WM_LBUTTONDOWN://鼠标左键按下
                        if (m.x >= 780 && m.x <= 980 && m.y >= 100 && m.y <= 155)//点击开始人人,游戏开始,黑棋先下
                        {
                              if (turn == 0)//开始游戏
                              {
                                        turn = 1;//黑棋先手
                                       
                                        chooseType = 1;
                                        drawchessboard();
                                        memset(map, 0, sizeof(map));
                                        MessageBox(h, "游戏开始请下棋", "提示信息", MB_OK);//弹出提示框
                                        outtextxy(800, 50, "当前模式:双人模式");
                                        outtextxy(800,455,"当前执子:");
                                        putimage(900,440,&black);
                                        break;
                              }
                              else
                                        MessageBox(h, "请游戏结束后重试", "提示信息", MB_OK);//弹出提示框
                        }
                        else if (m.x >= 780 && m.x <= 980 && m.y >= 200 && m.y <= 255)//人机模式
                        {
                              if (turn == 0)//开始游戏
                              {
                                        turn = 1;
                                        chooseType = 2;
                                        drawchessboard();
                                        memset(map, 0, sizeof(map));
                                        MessageBox(h, "游戏开始请下棋", "提示信息", MB_OK);//弹出提示框
                                        outtextxy(800, 50, "当前模式:单人模式");
                                        outtextxy(800,455,"你所执子:");
                                        putimage(900,440,&black);
                                        break;
                              }
                              else
                                        MessageBox(h, "请游戏结束后重试", "提示信息", MB_OK);//弹出提示框
                        }
                        else if (m.x >= 780 && m.x <= 980 && m.y >= 300 && m.y <= 355)//认输当前轮到谁谁输
                        {
                              if (turn == 1)
                              {
                                        MessageBox(h, "黑方认输 白方胜!!!", "提示信息", MB_OK);//弹出提示框
                                        turn = 0;
                                        chooseType = 0;
                              }
                              else if (turn == 2)
                              {
                                        MessageBox(h, "白方认输 黑方胜!!!", "提示信息", MB_OK);//弹出提示框
                                        turn = 0;
                                        chooseType = 0;
                              }
                              else
                                        MessageBox(h, "游戏未开始 不能认输!!!", "提示信息", MB_OK);//弹出提示框
                        }
                        else if(turn==0)
                              MessageBox(h, "请开始游戏!!!", "提示信息", MB_OK);
                        if (chooseType == 1)//人人大战
                        {
                              if (turn == 1)//黑棋下子
                              {
                                        putimage(900,440,&white);
                                        int x = m.x, y = m.y;//计算鼠标点击处最近的棋盘空格
                                        int true_x = x / 40 * 40 + 20, true_y = y / 40 * 40 + 20;
                                        if (true_x>760 || true_y>760)
                                        {
                                                MessageBox(h, "这里不是棋盘!!!", "提示信息", MB_OK);//弹出提示框
                                        }
                                        else
                                        {
                                                int locate_x = (true_x - 20) / 40, locate_y = (true_y - 20) / 40;//计算map数组的下标
                                                if (map == 0)
                                                {
                                                      putimage(true_x - 20, true_y - 20, &black);
                                                      map = 1;
                                                      if(judgement(locate_x,locate_y)!=1)
                                                      turn = 2;
                                                }
                                                else
                                                      MessageBox(h, "这里已经有棋子了,不能下!!!", "提示信息", MB_OK);//弹出提示框
                                        }
                              }
                              else if (turn == 2)//白棋下子
                              {
                                        putimage(900,440,&black);
                                        int x = m.x, y = m.y;
                                        int true_x = x / 40 * 40 + 20, true_y = y / 40 * 40 + 20;
                                        if (true_x>760 || true_y>760)
                                                MessageBox(h, "这里不是棋盘!!!", "提示信息", MB_OK);//弹出提示框
                                        else
                                        {

                                                int locate_x = (true_x - 20) / 40, locate_y = (true_y - 20) / 40;
                                                if (map == 0)
                                                {
                                                      putimage(true_x - 20, true_y - 20, &white);
                                                      map = 2;
                                                      if (judgement(locate_x, locate_y) != 2)
                                                                turn = 1;      
                                                }
                                                else
                                                      MessageBox(h, "这里已经有棋子了,不能下!!!", "提示信息", MB_OK);//弹出提示框
                                        }
                              }
                        }
                        else if (chooseType == 2)//人机模式
                        {
                              if(turn==0)
                                        continue;
                              else
                              {
                                        int x = m.x, y = m.y;
                                        int true_x = x / 40 * 40 + 20, true_y = y / 40 * 40 + 20;
                                        if (true_x>760 || true_y>760)
                                        {
                                                MessageBox(h, "这里不是棋盘!!!", "提示信息", MB_OK);//弹出提示框
                                                continue;
                                        }
                                        else
                                        {
                                                int locate_x = (true_x - 20) / 40, locate_y = (true_y - 20) / 40;
                                                if (map == 0)
                                                {
                                                      putimage(true_x - 20, true_y - 20, &black);
                                                      map = 1;
                                                      if (judgement(locate_x, locate_y) != 1)
                                                                turn = 2;
                                                      else
                                                                continue;
                                                }
                                                else
                                                {
                                                      MessageBox(h, "这里已经有棋子了,不能下!!!", "提示信息", MB_OK);//弹出提示框
                                                      continue;
                                                }
                                        }
                                        AIReboot();//机器人
                              }
                        }
                case WM_MOUSEMOVE:
                        if (m.x >= 780 && m.x <= 980 && m.y >= 100 && m.y <= 155 && gif == 0)
                        {
                              fillrectangle(780, 100, 980, 155);
                              outtextxy(830, 110, "双人模式");
                              gif = 1;
                        }
                        
                        else if (m.x >= 780 && m.x <= 980 && m.y >= 200 && m.y <= 255 && gif == 0)
                        {
                              fillrectangle(780, 200, 980, 255);
                              outtextxy(830, 210, "单人模式");
                              gif = 2;
                        }
                        else if (m.x >= 780 && m.x <= 980 && m.y >= 300 && m.y <= 355 && gif == 0)
                        {
                              fillrectangle(780, 300, 980, 355);
                              outtextxy(840, 310, "   认输");
                              gif = 3;
                        }
                        else if ((m.x < 780 || m.x > 980) || ((m.x>=780&&m.x<=980)&&((m.y<100)||(m.y>155&&m.y<200)||(m.y>255&&m.y<300)||m.y>355))&& gif != 0)      
                        {
                              putimage(780, 100, 200, 55, &renren, 298, 85);
                              putimage(780, 200, 200, 55, &renji, 298, 85);
                              putimage(780, 300, 200, 55, &surrender, 298, 85);
                              gif = 0;
                        }
                }
      }
}
int judgement(int x,int y)//判断是否胜利
{
      //行
      int r1 = x - 4, r2 = x + 4,i, j, rsum = 0;
      if (r1<0)r1 = 0;
      if (r2>18) r2 = 18;
      if (turn == 1) //黑棋
      {
                for (i = r1; i <= r2; i++)
                {
                        if (map == 1)
                        {
                              rsum++;
                              if (rsum == 5)
                              {
                                        outtextxy(800,510,"获胜者:");
                                        putimage(900,500,&black);
                                        MessageBox(h, "游戏结束 黑方胜!!!", "提示信息", MB_OK);//弹出提示框
                                        //outtextxy(750,525,"游戏结束 黑方行满5子胜!!!");
                                        turn = 0;
                                        chooseType = 0;
                                        return 1;//连续五个黑子,黑方胜返回1
                              }
                        }
                        else
                              rsum = 0;
                }
      }
      else if (turn == 2) {//白棋
                for (i = r1; i <= r2; i++) {
                        if (map == 2) {
                              rsum++;
                              if (rsum == 5) {
                                        outtextxy(800,510,"获胜者:");
                                        putimage(900,500,&white);
                                        MessageBox(h, "游戏结束 白方行满5子白方胜!!!", "提示信息", MB_OK);//弹出提示框
                                        turn = 0;
                                        chooseType = 0;
                                        return 2;//连续五个白子,白方胜返回2
                              }
                        }
                        else
                              rsum = 0;
                }
      }

      //列
      int c1 = y - 4, c2 = y + 4,csum = 0;
      if (c1<0)
                c1 = 0;
      if (c2>18)
                c2 = 18;
      if (turn == 1) {//黑棋
                for (i = c1; i <= c2; i++) {
                        if (map == 1) {
                              csum++;
                              if (csum == 5) {
                                        outtextxy(800,510,"获胜者:");
                                        putimage(900,500,&black);
                                        MessageBox(h, "游戏结束 黑方列满5子黑方胜!!!", "提示信息", MB_OK);//弹出提示框
                                        turn = 0;
                                        chooseType = 0;
                                        return 1;//连续五个黑子,黑方胜返回1
                              }
                        }
                        else
                              csum = 0;
                }
      }
      else if (turn == 2) {//白棋
                for (i = c1; i <= c2; i++) {
                        if (map == 2) {
                              csum++;
                              if (csum == 5) {
                                        outtextxy(800,510,"获胜者:");
                                        putimage(900,500,&white);
                                        MessageBox(h, "游戏结束 白方列满5子白方胜!!!", "提示信息", MB_OK);//弹出提示框
                                        turn = 0;
                                        chooseType = 0;
                                        return 2;//连续五个白子,白方胜返回1
                              }
                        }
                        else
                              csum = 0;
                }
      }

      //判断\ 方向
      int a1 = y - 4, a2 = x - 4, b1 = y + 4, b2 = x + 4,asum = 0;//a1行   a2列
      if (a1<0) a1 = 0;
      if (a2<0) a2 = 0;
      if (b1>18) b1 = 18;
      if (b2>18) b2 = 18;
      if (turn == 1) {//黑棋
                for (i = a1, j = a2; i <= b1&&j <= b2; i++, j++) {
                        if (map == 1) {
                              asum++;
                              if (asum == 5) {
                                        outtextxy(800,510,"获胜者:");
                                        putimage(900,500,&black);
                                        MessageBox(h, "游戏结束 黑方右斜满5子黑方胜!!!", "提示信息", MB_OK);//弹出提示框
                                        turn = 0;
                                        chooseType = 0;
                                        return 1;//连续五个黑子,黑方胜返回1
                              }
                        }
                        else
                              asum = 0;
                }
      }
      else if (turn == 2) {//白棋
                for (i = a1, j = a2; i <= b1&&j <= b2; i++, j++) {
                        if (map == 2) {
                              asum++;
                              if (asum == 5) {
                                        outtextxy(800,510,"获胜者:");
                                        putimage(900,500,&white);
                                        MessageBox(h, "游戏结束 白方右斜满5子白方胜!!!", "提示信息", MB_OK);//弹出提示框
                                        turn = 0;
                                        chooseType = 0;
                                        return 2;//连续五个白子,白方胜返回2
                              }
                        }
                        else
                              asum = 0;
                }
      }


      //判断/ 方向
      int m1 = y + 4, m2 = x - 4, n1 = y - 4, n2 = x + 4,msum = 0;//a1行   a2列
      if (m1>18) a1 = 18;
      if (m2<0) m2 = 0;
      if (n1<0) n1 = 0;
      if (n2>18) n2 = 18;
      if (turn == 1) {//黑棋
                for (i = m1, j = m2; i >= n1&&j <= n2; i--, j++) {
                        if (map == 1) {
                              msum++;
                              if (msum == 5) {
                                        outtextxy(800,510,"获胜者:");
                                        putimage(900,500,&black);
                                        MessageBox(h, "游戏结束 黑方左斜满5子黑方胜!!!", "提示信息", MB_OK);//弹出提示框
                                        turn = 0;
                                        chooseType = 0;
                                        return 1;//连续五个黑子,黑方胜返回1
                              }
                        }
                        else
                              msum = 0;
                }
      }
      else if (turn == 2) {//白棋
                for (i = m1, j = m2; i >= n1&&j <= n2; i--, j++) {
                        if (map == 2) {
                              msum++;
                              if (msum == 5) {
                                        outtextxy(800,510,"获胜者:");
                                        putimage(900,500,&white);
                                        MessageBox(h, "游戏结束 白方左斜满5子白方胜!!!", "提示信息", MB_OK);//弹出提示框
                                        turn = 0;
                                        chooseType = 0;
                                        return 2;//连续五个白子,白方胜返回2
                              }
                        }
                        else
                              msum = 0;
                }
      }
      return 0;
}
int main()
{
      loadimage(&mainpicture, ("2.jpg"));
      loadimage(&background, ("1.jpg"));
      
      loadimage(&renren, ("人人.png"));
      loadimage(&renji, ("人机.png"));
      loadimage(&surrender, ("认输.png"));
      loadimage(&black, "black.png");
      loadimage(&white, "white.png");
      initgraph(1030, 750);
      h = GetHWnd();//获取绘图窗口句柄
      //SetWindowLong(h , GWL_STYLE , GetWindowLong(h,GWL_STYLE)-WS_CAPTION);//去掉标题栏
      //SetWindowPos(h , HWND_TOP , 0 , 0 , GetSystemMetrics(SM_CXSCREEN) , GetSystemMetrics(SM_CXSCREEN) , SWP_SHOWWINDOW);//窗口全屏
      settextcolor(BLACK);
      setbkmode(TRANSPARENT);
      setfillcolor(RGB(255,0,0));
      putimage(-20,0,&mainpicture);
      //drawchessboard();
      XiaQi();
      _getch();
      closegraph();
      return 0;
}源码链接在这
链接: https://pan.baidu.com/s/1uJM1deIpMj4M1V3szzAhWw 提取码: 8bzk 复制这段内容后打开百度网盘手机App,操作更方便哦
链接: https://pan.baidu.com/s/1uJM1deIpMj4M1V3szzAhWw 提取码: 8bzk 复制这段内容后打开百度网盘手机App,操作更方便哦
页: [1]
查看完整版本: 【c++】五子棋源码