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************************************/
相关文章
|
2月前
|
机器学习/深度学习 人工智能 算法
C语言与AI
C语言与AI
94 0
|
11天前
|
机器学习/深度学习 人工智能 开发者
谷歌推世界首个AI游戏引擎,2000亿游戏产业恐颠覆!0代码生成游戏,老黄预言成真
【9月更文挑战第22天】谷歌近日推出的AI游戏引擎GameNGen,作为全球首款神经模型驱动的游戏引擎,引发了广泛关注。该引擎使用户无需编写代码即可生成游戏,并实现了与复杂环境的实时交互,显著提升了模拟质量。在单TPU上,GameNGen能以超20帧/秒的速度流畅模拟经典游戏《DOOM》。这项技术不仅简化了游戏开发流程,降低了成本,还为游戏设计带来了更多可能性。然而,它也可能改变游戏产业的商业模式和创意多样性。无论如何,GameNGen标志着游戏开发领域的一次重大革新。
22 2
|
2月前
|
人工智能 前端开发 Java
【实操】Spring Cloud Alibaba AI,阿里AI这不得玩一下(含前后端源码)
本文介绍了如何使用 **Spring Cloud Alibaba AI** 构建基于 Spring Boot 和 uni-app 的聊天机器人应用。主要内容包括:Spring Cloud Alibaba AI 的概念与功能,使用前的准备工作(如 JDK 17+、Spring Boot 3.0+ 及通义 API-KEY),详细实操步骤(涵盖前后端开发工具、组件选择、功能分析及关键代码示例)。最终展示了如何成功实现具备基本聊天功能的 AI 应用,帮助读者快速搭建智能聊天系统并探索更多高级功能。
584 2
【实操】Spring Cloud Alibaba AI,阿里AI这不得玩一下(含前后端源码)
|
2月前
|
存储 C语言
【C语言】C语言-宾馆客房管理系统(源码+论文)【独一无二】
【C语言】C语言-宾馆客房管理系统(源码+论文)【独一无二】
【C语言】C语言-宾馆客房管理系统(源码+论文)【独一无二】
|
2月前
|
算法 编译器 C语言
【C语言篇】猜数字游戏(赋源码)
rand函数会返回⼀个伪随机数,这个随机数的范围是在0~RAND_MAX之间,这个RAND_MAX的⼤⼩是依赖编译器上实现的,但是⼤部分编译器上是32767。
|
2月前
|
存储 数据可视化 数据安全/隐私保护
【C语言】C语言-成绩管理系统(管理员+教师+学生 源码)【独一无二】
【C语言】C语言-成绩管理系统(管理员+教师+学生 源码)【独一无二】
|
2月前
|
存储 数据可视化 C语言
【C语言】C语言-身份证管理系统(源码+注释)【独一无二】
【C语言】C语言-身份证管理系统(源码+注释)【独一无二】
|
2月前
|
存储 数据可视化 C语言
【C语言】C语言-学生籍贯信息记录系统(源码+论文)【独一无二】
【C语言】C语言-学生籍贯信息记录系统(源码+论文)【独一无二】
|
2月前
|
存储 C语言
【C语言】C语言-学生选修课程系统(源码)【独一无二】
【C语言】C语言-学生选修课程系统(源码)【独一无二】
|
2月前
|
存储 数据可视化 Serverless
【C语言】C语言-学籍管理系统(源码+文件存储)【独一无二】
【C语言】C语言-学籍管理系统(源码+文件存储)【独一无二】
下一篇
无影云桌面