c语言黑白棋ai游戏源码

简介: c语言黑白棋ai游戏源码
#include <graphics.h> // EasyX_2011惊蛰版
#include <strstream>
#include <ctime>
#pragma comment(lib, "Winmm.lib")
#define T(c) ((c == 'B') ? 'W' : 'B')
using namespace std;
// 来自公众号:c语言与cpp编程
/*******************************定义全局变量*****************************/
const int difficult = 6;  // 难度
const int move[8][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1},
            {-1, -1}, {1, -1}, {1, 1}, {-1, 1}};
              // 八个方向扩展
char map[8][8];       // 棋盘
IMAGE img[5];       // 保存图片
int black, white;     // 双方的棋子数
int X, Y;         // 白棋的下子点
/**********************************函数声明*****************************/
void load(void);        // 加载素材
void print(void);       // 画棋盘
void draw(int, int, char);    // 下当前子
int judge(int, int, char);    // 判断当前是否可以落下
bool baidu(char);       // 判断是否有棋可吃
bool quit(char);        // 判断是否有棋存活
bool ask(void);         // 弹出对话框
int D(char, int);       // 动态规划
void play(void);        // 游戏过程
/**********************************定义函数*****************************/
void load(void)   // 加载素材
{
  // 加载图片
  loadimage(&img[0], "图片\\空位.bmp");
  loadimage(&img[1], "图片\\黑子.bmp");
  loadimage(&img[2], "图片\\白子.bmp");
  loadimage(&img[3], "图片\\黑子1.bmp");
  loadimage(&img[4], "图片\\白子1.bmp");
  // 加载音乐
  mciSendString("open 音乐\\背景音乐.wma", NULL, 0, NULL);
  mciSendString("open 音乐\\和局.wma", NULL, 0, NULL);
  mciSendString("open 音乐\\胜利.wma", NULL, 0, NULL);
  mciSendString("open 音乐\\失败.wma", NULL, 0, NULL);
  mciSendString("open 音乐\\下子.wma", NULL, 0, NULL);
  // 初始化棋盘
  initgraph(340, 340);
  IMAGE qipan;
  loadimage(&qipan, "图片\\棋盘.bmp");
  putimage(0, 0, &qipan);
  setorigin(26, 26);
  SetWindowText(GetHWnd(), "黑白棋AI版");
}
void print(void)  // 画棋盘
{
  int x, y;
  black = white = 0;
  for(x = 0; x < 8; x++)
    for(y = 0; y < 8; y++)
      switch(map[x][y])
      {
        case 0:
            putimage(37 * y, 37 * x, &img[0]);
          break;
        case 'B':
            putimage(37 * y, 37 * x, &img[1]);
          black++;
          break;
        case 'W':
            putimage(37 * y, 37 * x, &img[2]);
          white++;
          break;
      }
}
void draw(int x, int y, char a) // 下当前子
{
  char b = T(a);                  // 敌方子
  int i, x1, y1, x2, y2;
  bool sign;      
  for (i = 0; i < 8; i++)
  {
    sign = false;
    x1 = x + move[i][0];
    y1 = y + move[i][1];
    while (0 <= x1 && x1 < 8 && 0 <= y1 && y1 < 8 && map[x1][y1])
    {
      if(map[x1][y1] == b)
        sign = true;
      else
      {
        if(sign)
        {
          x1 -= move[i][0];
          y1 -= move[i][1];
          x2 = x + move[i][0];
          y2 = y + move[i][1];
          while (((x <= x2 && x2 <= x1) || (x1 <= x2 && x2 <= x)) && ((y <= y2 && y2 <= y1) || (y1 <= y2 && y2 <= y)))
          {
            map[x2][y2] = a;
            x2 += move[i][0];
            y2 += move[i][1];
          }
        }
        break;
      }
      x1 += move[i][0];
      y1 += move[i][1];
    }
  }
  map[x][y] = a;
}
int judge(int x, int y, char a) // 判断当前是否可以落下,同draw函数
{
  if(map[x][y])           // 如果当前不是空的返回0值
    return 0;
  char b = T(a);
  int i, x1, y1;
  int n = 0, sign;
  for (i = 0; i < 8; i++)
  {
    sign = 0;
    x1 = x + move[i][0];
    y1 = y + move[i][1];
    while (0 <= x1 && x1 < 8 && 0 <= y1 && y1 < 8 && map[x1][y1])
    {
      if(map[x1][y1] == b)
        sign++;
      else
      {
        n += sign;
        break;
      }
      x1 += move[i][0];
      y1 += move[i][1];
    }
  }
  return n;   // 返回可吃棋数
}
bool baidu(char c)  // 判断是否有棋可吃
{
  int x, y;
  for(x = 0; x < 8; x++)
    for(y = 0; y < 8; y++)
      if(judge(x, y, c))
        return true;
  return false;
}
bool quit(char c) // 判断是否有棋存活
{
  int x, y;
  bool b = false, w = false;
  for(x = 0; x < 8; x++)
    for(y = 0; y < 8; y++)
    {
      if(map[x][y] == c)
        return false;
    }
  return true;
}
bool ask(void)  // 弹出对话框
{
  HWND wnd = GetHWnd();
  int key;
  char str[50];
  ostrstream strout(str, 50);
  strout <<"黑:" <<black <<"  白:" <<white <<endl;
  if (black == white)
    strout <<"世界和平";
  else if(black > white)
    strout <<"恭喜你赢了!";
  else
    strout <<"小样,还想赢我。";
  strout <<"\n再来一局吗?" <<ends;
  if(black == white)
    key = MessageBox(wnd, str, "和局", MB_YESNO | MB_ICONQUESTION);
  else if(black > white)
    key = MessageBox(wnd, str, "黑胜", MB_YESNO | MB_ICONQUESTION);
  else
    key = MessageBox(wnd, str, "白胜", MB_YESNO | MB_ICONQUESTION);
  if(key == IDYES)
    return true;
  else
    return false;
}
int D(char c, int step)
{
  // 判断是否结束递归
  if (step > difficult) // 约束步数之内
    return 0;
  if (!baidu(c))
  {
    if (baidu(T(c)))
      return -D(T(c), step);
    else
      return 0;
  }
  int i, j, max = 0, temp, x, y;
  bool ans = false;
  // 建立临时数组
  char **t = new char *[8];
  for (i = 0; i < 8; i++)
    t[i] = new char [8];
  for (i = 0; i < 8; i++)
    for (j = 0; j < 8; j++)
      t[i][j] = map[i][j];
  // 搜索解法
  for (i = 0; i < 8; i++)
    for (j = 0; j < 8; j++)
      if (temp = judge(i, j, c))
      {
        draw(i, j, c);
        temp -= D(T(c), step + 1);
        if (temp > max || !ans)
        {
          max = temp;
          x = i;
          y = j;
          ans = true;
        }
        for (int k = 0; k < 8; k++)
          for (int l = 0; l < 8; l++)
            map[k][l] = t[k][l];
      }
  // 撤销空间
  for (i = 0; i < 8; i++)
    delete [] t[i];
  delete [] t;
  // 如果是第一步则标识白棋下子点
  if (step == 1)
  {
    X = x;
    Y = y;
  }
  return max; // 返会最优解
}
void play(void)     // 游戏过程
{
  MOUSEMSG m;
  int x, y;
  // 初始化棋子
  for(x = 0; x < 8; x++)
    for(y = 0; y < 8; y++)
      map[x][y] = 0;
  map[3][4] = map[4][3] = 'B';
  map[3][3] = map[4][4] = 'W';
  // 开始游戏
  print();
  mciSendString("play 音乐\\背景音乐.wma from 0 repeat", NULL, 0, NULL);
  do
  {
    if (baidu('B'))                   // 如果玩家有下子位置              
    {
      A:
      while(true)
      {
        m = GetMouseMsg();              // 获取鼠标消息
        if(m.uMsg == WM_LBUTTONDOWN && m.x - 26 < 37 * 8 && m.y - 26 < 37 * 8)
                              // 如果左键点击
          break;
      }
      x = (m.y - 26) / 37;
      y = (m.x - 26) / 37;
      if(judge(x, y, 'B'))              // 如果当前位置有效
      {
        draw(x, y, 'B');              // 下子
        mciSendString("play 音乐\\下子.wma from 0", NULL, 0, NULL);
        print();
        putimage(37 * y, 37 * x, &img[3]);      // 标识下子点
      }
      else
        goto A;
      if (quit('W'))                  // 计算机是否失败
        break;
    }
    if (baidu('W'))                   // 如果计算机有下子位置
    {
      clock_t start;
      start = clock();
      D('W', 1);                    // 搜索解法
      while (clock() - start < CLOCKS_PER_SEC);
      draw(X, Y, 'W');
      print();
      mciSendString("play 音乐\\下子.wma from 0", NULL, 0, NULL);
      putimage(37 * Y, 37 * X, &img[4]);  // 标识下子点
      if (quit('B'))                  // 玩家是否失败
        break;
    }
  }while (baidu('B') || baidu ('W'));
  // 播放庆祝音乐
  mciSendString("stop 音乐\\背景音乐.wma", NULL, 0, NULL);
  if (black > white)
    mciSendString("play 音乐\\胜利.wma from 0", NULL, 0, NULL);
  else if (black < white)
    mciSendString("play 音乐\\失败.wma from 0", NULL, 0, NULL);
  else
    mciSendString("play 音乐\\和局.wma from 0", NULL, 0, NULL);
}
// 主函数
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  load();
  do
  {
    play();
  } while(ask());
  // 关闭音乐
  mciSendString("close 音乐\\背景音乐.wma", NULL, 0, NULL);
  mciSendString("close 音乐\\和局.wma", NULL, 0, NULL);
  mciSendString("close 音乐\\胜利.wma", NULL, 0, NULL);
  mciSendString("close 音乐\\失败.wma", NULL, 0, NULL);
  mciSendString("close 音乐\\下子.wma", NULL, 0, NULL);
  closegraph();
  return 0;
}
/***********************************THE END************************************/
相关文章
|
存储 人工智能 运维
【01】做一个精美的打飞机小游戏,浅尝阿里云通义灵码python小游戏开发AI编程-之飞机大战小游戏上手实践-优雅草央千澈-用ai开发小游戏尝试-分享源代码和游戏包
【01】做一个精美的打飞机小游戏,浅尝阿里云通义灵码python小游戏开发AI编程-之飞机大战小游戏上手实践-优雅草央千澈-用ai开发小游戏尝试-分享源代码和游戏包
817 48
【01】做一个精美的打飞机小游戏,浅尝阿里云通义灵码python小游戏开发AI编程-之飞机大战小游戏上手实践-优雅草央千澈-用ai开发小游戏尝试-分享源代码和游戏包
|
11月前
|
人工智能 数据安全/隐私保护 异构计算
桌面版exe安装和Python命令行安装2种方法详细讲解图片去水印AI源码私有化部署Lama-Cleaner安装使用方法-优雅草卓伊凡
桌面版exe安装和Python命令行安装2种方法详细讲解图片去水印AI源码私有化部署Lama-Cleaner安装使用方法-优雅草卓伊凡
1578 8
桌面版exe安装和Python命令行安装2种方法详细讲解图片去水印AI源码私有化部署Lama-Cleaner安装使用方法-优雅草卓伊凡
|
人工智能 自然语言处理 前端开发
DeepSite:基于DeepSeek的开源AI前端开发神器,一键生成游戏/网页代码
DeepSite是基于DeepSeek-V3模型的在线开发工具,无需配置环境即可通过自然语言描述快速生成游戏、网页和应用代码,并支持实时预览效果,显著降低开发门槛。
2132 93
DeepSite:基于DeepSeek的开源AI前端开发神器,一键生成游戏/网页代码
|
11月前
|
人工智能 算法 数据库
给AI装上一个'超级大脑':信息检索如何改变RAG系统的游戏规则
从传统检索方法到现代向量检索,通过一个购物助手的故事,直观展示了不同检索技术的原理与应用。学会这些技巧,让你的AI不再是「记忆只有金鱼长度」的大模型!
437 24
|
11月前
|
机器学习/深度学习 人工智能 算法
当AI提示词遇见精密算法:TimeGuessr如何用数学魔法打造文化游戏新体验
TimeGuessr融合AI与历史文化,首创时间与空间双维度评分体系,结合分段惩罚、Haversine距离计算与加权算法,辅以连击、速度与完美奖励机制,实现公平且富挑战性的游戏体验。
|
人工智能 自然语言处理 搜索推荐
从输入指令到代码落地:Cline AI 源码浅析
文章揭示了Cline如何将简单的自然语言指令转化为具体的编程任务,并执行相应的代码修改或生成操作。
1295 18
从输入指令到代码落地:Cline AI 源码浅析
|
12月前
|
人工智能 JSON 程序员
别再和AI玩文字游戏:JSON提示工程让AI乖乖按表填空
厌倦了和AI玩猜谜游戏吗?JSON提示工程来拯救你!用咖啡订单的方式和AI对话,让每次交互都精准到位,告别模糊不清的回复,迎接可预测的AI输出时代。
505 9
|
机器学习/深度学习 人工智能 数据可视化
基于YOLOv8的AI虫子种类识别项目|完整源码数据集+PyQt5界面+完整训练流程+开箱即用!
本项目基于YOLOv8与PyQt5开发,实现虫子种类识别,支持图片、视频、摄像头等多种输入方式,具备完整训练与部署流程,开箱即用,附带数据集与源码,适合快速搭建高精度昆虫识别系统。
基于YOLOv8的AI虫子种类识别项目|完整源码数据集+PyQt5界面+完整训练流程+开箱即用!