人机对战五子棋

写了个人机对战的五子棋程序,根据极大极小值方法,主程序如下,需要整个源码的可发邮件给我:

BOOL CFiveChessDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // 将/“关于.../”菜单项添加到系统菜单中。

 // IDM_ABOUTBOX 必须在系统命令范围内。
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }

 // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
 //  执行此操作
 SetIcon(m_hIcon, TRUE);   // 设置大图标
 SetIcon(m_hIcon, FALSE);  // 设置小图标

 // TODO: 在此添加额外的初始化代码
 m_startX = 25;
 m_startY = 30;
 m_chessLen = 21;
 m_chessHeight = 21;
 m_bFinished = true;
 CButton *button;
 button =(CButton *) GetDlgItem(IDC_RADIO_COMPUTER);
 button->SetCheck(1);
 int i,j;
 for(i=0;i<15;i++)
 {
  for(j=0;j<15;j++)
   m_chessMap[i][j] = 0;
 }

 EnableToolTips(TRUE);
 m_ToolTip.Create(this);
 m_ToolTip.Activate(TRUE);
 m_ToolTip.AddTool(this,"得分");
 return TRUE;  // 除非设置了控件的焦点,否则返回 TRUE
}

void CFiveChessDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CFiveChessDlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // 用于绘制的设备上下文

  SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

  // 使图标在工作矩形中居中
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  // 绘制图标
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  
  CDialog::OnPaint();
  PaintBMP(IDB_BITMAP_BOARD,0,0);
  int i,j;
  for(i=0;i<15;i++)
  {
   for(j=0;j<15;j++)
   {
    PutChess(m_chessMap[i][j],i,j);
   }
  }
 }
}

void CFiveChessDlg::PutChess(int type,int i,int j)
{
 if(type == m_black)
 {
  PaintBMP(IDB_BITMAP_BLACK,i*m_chessLen+m_startX -10,j*m_chessHeight+m_startY -10);
  m_chessNum++;
 }
 else if(type == m_white)
 {
  PaintBMP(IDB_BITMAP_WHITE,i*m_chessLen+m_startX -10,j*m_chessHeight+m_startY -10);
  m_chessNum++;
 }
}
//当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CFiveChessDlg::OnQueryDragIcon()
{
 return static_cast<HCURSOR>(m_hIcon);
}


void CFiveChessDlg::PaintBMP(unsigned int id,int x,int y)
{
 CClientDC dc(this);
 //dc.SetBkMode(TRANSPARENT);
 CRect rect;
 GetClientRect(&rect);
 CBitmap bitmap;
 BITMAP bm;
 BOOL result;
 result = bitmap.LoadBitmap(id);
 
 bitmap.GetObject(sizeof(BITMAP),&bm);
 CDC memdc;
 memdc.CreateCompatibleDC(&dc);
 memdc.SelectObject(&bitmap);
 dc.BitBlt(x,y,bm.bmWidth,bm.bmHeight,&memdc,0,0,SRCCOPY);
 memdc.DeleteDC();
 ReleaseDC(&memdc);
}

void CFiveChessDlg::OnBnClickedRadioComputer()
{
 CButton *button;
 button = (CButton *)GetDlgItem(IDC_RADIO_COMPUTER);
 if(button->GetCheck())
 {
  m_bComputerFirst = true;
 }
 else
  m_bComputerFirst = false;
}

void CFiveChessDlg::OnBnClickedRadioPlayer()
{
 CButton *button;
 button = (CButton *)GetDlgItem(IDC_RADIO_PLAYER);
 if(button->GetCheck())
  m_bComputerFirst = false;
 else
  m_bComputerFirst = true;
}

void CFiveChessDlg::OnBnClickedButtonNewgame()
{
 int i,j;
 m_chessNum = 0;
 m_bFinished = false;
 m_bBlackTurn = true;
 for(i=0;i<15;i++)
 {
  for(j=0;j<15;j++)
   m_chessMap[i][j] = 0;
 }
 PaintBMP(IDB_BITMAP_BOARD,0,0);
 if(m_bComputerFirst)
 {
  m_computerChess = m_black;
  m_playerChess = m_white;
  PutChess(m_computerChess,7,7);
  m_chessMap[7][7] = m_computerChess;
 }
 else
 {
  m_computerChess = m_white;
  m_playerChess = m_black;
 }
 m_bPlayerTurn = true;
}

void CFiveChessDlg::ComputerPlay(int *m,int *n)
{
 int i,j;
 int a,b;
 int maxScore=0,score=0,minScore=0;
 for(i=0;i<15;i++)
 {
  for(j=0;j<15;j++)
  {
   if(m_chessMap[i][j] != 0)
    continue;
   score = GiveScore(false,m_playerChess,i,j);
   if(score<minScore)
   {
    a = i;
    b = j;
    minScore = score;
   }
  }
 }
 

 for(i=0;i<15;i++)
 {
  for(j=0;j<15;j++)
  {
   if(m_chessMap[i][j] != 0)
    continue;
   score = GiveScore(true,m_computerChess,i,j);
   if(score>maxScore)
   {
    *m = i;
    *n = j;
    maxScore = score;
   }
  }
 }
 if(maxScore + minScore <= 0)
 {
  *m = a;
  *n = b;
 }
}
void CFiveChessDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
 if(m_bFinished)
  return ;
 if(!m_bPlayerTurn)
  return ;
 int i,j;
 int result;
 i = (point.x - m_startX + 10)/m_chessLen;
 j = (point.y - m_startY + 10)/m_chessHeight;
 if(m_chessMap[i][j] != 0)
  return ;
 if(i<0 || j<0 || i>=15 || j>=15)
  return ;
 PutChess(m_playerChess,i,j);
 m_bPlayerTurn = false;
 m_chessMap[i][j] = m_playerChess;
 result = JudgeWinner(m_playerChess,i,j);
 if(result != 0)
 {
  m_bFinished = true;
  MessageBox("你赢了");
  return ;
 }
 int m=0,n=0;
 ComputerPlay(&m,&n);
 TRACE("%d,%d/n",m,n);
 PutChess(m_computerChess,m,n);
 m_chessMap[m][n] = m_computerChess;
 result = JudgeWinner(m_computerChess,m,n);
 if(result != 0)
 {
  m_bFinished = false;
  MessageBox("你输了");
  return ;
 }
 m_bPlayerTurn = true;
}
/*void CFiveChessDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
 if(m_bFinished)
  return ;
 
 int i,j;
 int chess;
 int result;
 i = (point.x - m_startX + 10)/m_chessLen;
 j = (point.y - m_startY + 10)/m_chessHeight;
 if(m_chessMap[i][j] != 0)
  return ;
 if(i<0 || j<0 || i>=15 || j>=15)
  return ;
 if(m_bBlackTurn)
 {
  chess = m_black;
  m_bBlackTurn = false;
 }
 else
 {
  chess = m_white;
  m_bBlackTurn = true;
 }
 m_chessMap[i][j] = chess;
 PutChess(chess,i,j);
 result = JudgeWinner(chess,i,j);
 if(result == m_black)
 {
  MessageBox("黑棋赢");
  m_bFinished = true;
 }
 else if(result == m_white)
 {
  MessageBox("白棋赢");
  m_bFinished = true;
 }
 else if(m_chessNum == 15*15)
 {
  MessageBox("和棋");
  m_bFinished = true;
 }
}
*/
int CFiveChessDlg::JudgeWinner(int chess,int row,int col)
{
 int sameNum;
 int i,j;
 sameNum = 0;
 j = col;
 for(i=row;i>=row-4&&j>=0;i--)
 {
  if(m_chessMap[i][j] == chess)
   sameNum++;
  else
   break;
 }
 for(i=row+1;i<=row+4&&i<15;i++)
 {
  if(m_chessMap[i][j] == chess)
   sameNum++;
  else
   break;
 }
 if(sameNum >=5)
 {
  return chess;
 }
 sameNum = 0;

 i=row;
 for(j=col;j>=col-4&&j>=0;j--)
 {
  if(m_chessMap[i][j] == chess)
   sameNum++;
  else
   break;
 }
 for(j=col+1;j<=col+4&&j<15;j++)
 {
  if(m_chessMap[i][j] == chess)
   sameNum++;
  else
   break;
 }
 if(sameNum >= 5)
 {
  return chess;
 }
 sameNum = 0;
 for(i=row,j=col;i>=row-4&&j>=col-4&&i>=0&&j>=0;i--,j--)
 {
  if(m_chessMap[i][j] == chess)
   sameNum++;
  else
   break;
 }
 for(i=row+1,j=col+1;i<=row+4&&j<=col+4&&i<15&&j<15;i++,j++)
 {
  if(m_chessMap[i][j] == chess)
  {
   sameNum++;
  }
  else
   break;
 }
 if(sameNum >= 5)
 {
  return chess;
 }
 sameNum = 0;
 for(i=row,j=col;i<=row+4&&j>=col-4&&i<15&&j>=0;i++,j--)
 {
  if(m_chessMap[i][j] == chess)
   sameNum++;
  else
   break;
 }
 for(i=row-1,j=col+1;i>=row-4&&j<=col+4&&i>=0&&j<15;i--,j++)
 {
  if(m_chessMap[i][j] == chess)
   sameNum++;
  else
   break;
 }
 if(sameNum >= 5)
  return chess;
 return 0;
}


LRESULT CFiveChessDlg::WindowProc(UINT message,WPARAM wParam,LPARAM lParam)
{
 MSG msg;
 switch(message)
 {
 case WM_RBUTTONDOWN:
 case WM_RBUTTONUP:
 case  WM_MOUSEMOVE:
  msg.hwnd=m_hWnd;
  msg.message=message;
  msg.wParam=wParam;
  msg.lParam=lParam;
  m_ToolTip.RelayEvent(&msg);
  break;
 default:
  break;
 }
 return CDialog::WindowProc(message, wParam, lParam);
}
BOOL CFiveChessDlg::PreTranslateMessage(MSG* pMsg)
{
 // TODO: 在此添加专用代码和/或调用基类
 m_ToolTip.RelayEvent(pMsg);
 return CDialog::PreTranslateMessage(pMsg);
}


int CFiveChessDlg::GiveScore(bool max,int chess,int row,int col)
{
 int i,j,k;
 int stop;
 int score=0;
 int num;
 int five;
 if(m_chessMap[row][col] != 0)
  return 0;
 if(chess == m_black)
  stop = m_white;
 else
  stop = m_black;
 
 for(k=0;k<=4;k++)
 {
  num = 0;
  five = 1;
  j = col;
  for(i=row-1;i>=0&&i>=row-k;i--)
  {
   if(m_chessMap[i][j] == chess)
    num++;
   else if(m_chessMap[i][j] == stop)
   {
    break;
   }
   five++;
  }
  for(i=row+1;i<15&&i<=row+(4-k);i++)
  {
   if(m_chessMap[i][j] == chess)
   {
    num++;
   }
   else if(m_chessMap[i][j] == stop)
   {
    break;
   }
   five++;
  }
  if(five>=5)
  {
   if(max)
    score += NumToScoreMax(num);
   else
    score += NumToScoreMin(num);
  }
  num = 0;
  five = 1;
  i = row;
  for(j=col-1;j>=0&&j>=col-k;j--)
  {
   if(m_chessMap[i][j] == chess)
    num++;
   else if(m_chessMap[i][j] == stop)
   {
    break;
   }
   five++;
  }
  for(j=col+1;j<15&&j<=col+(4-k);j++)
  {
   if(m_chessMap[i][j] == chess)
    num++;
   else if(m_chessMap[i][j] == stop)
   {
    break;
   }
   five++;
  }
  if(five>=5)
  {
   if(max)
    score += NumToScoreMax(num);
   else
    score += NumToScoreMin(num);
  }
  num = 0;
  five = 1;
  for(i=row-1,j=col-1;i>=0&&j>=0&&i>=row-k&&j>=col-k;i--,j--)
  {
   if(m_chessMap[i][j] == chess)
    num++;
   else if(m_chessMap[i][j] == stop)
   {
    break;
   }
   five++;
  }
  for(i=row+1,j=col+1;i<15&&j<15&&i<=row+(4-k)&&j<=col+(4-k);i++,j++)
  {
   if(m_chessMap[i][j] == chess)
    num++;
   else if(m_chessMap[i][j] == stop)
   {
    break;
   }
   five++;
  }
  if(five>=5)
  {
   if(max)
    score += NumToScoreMax(num);
   else
    score += NumToScoreMin(num);
  }
  num = 0;
  five = 1;
  for(i=row-1,j=col+1;i>=0&&j<15&&i>=row-k;i--,j++)
  {
   if(m_chessMap[i][j] == chess)
    num++;
   else if(m_chessMap[i][j] == stop)
   {
    break;
   }
   five++;
  }
  for(i=row+1,j=col-1;i<15&&j>=0&&i<=row+(4-k);i++,j--)
  {
   if(m_chessMap[i][j] == chess)
    num++;
   else if(m_chessMap[i][j] == stop)
   {
    break;
   }
   five++;
  }
  if(five>=5)
  {
   if(max)
    score += NumToScoreMax(num);
   else
    score += NumToScoreMin(num);
  }
  five = 1;
  num = 0;
 }
 return score;


}

int CFiveChessDlg::NumToScoreMax(int num)
{
 switch(num)
 {
 case 1:
  return 5;
  break;
 case 2:
  return 50;
  break;
 case 3:
  return 100;
  break;
 case 4:
  return 10000;
  break;
 default:
  break;
 }
 return 0;
}

int CFiveChessDlg::NumToScoreMin(int num)
{
 switch(num)
 {
 case 1:
  return -5;
  break;
 case 2:
  return -50;
  break;
 case 3:
  return -500;
  break;
 case 4:
  return -5000;
  break;
 default:
  break;
 }
 return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
作品背景: “α狗”是“Alpha Go”,智能计算系统。“α”是第一个希腊字母,代表了开始,一个人工智能时代的开始,为了顺应科技潮流,我们设计并实现了βGo的五子棋人机对战 设计思路: (1)初始化:首先,建立盘面数组Table[15][15]、 棋型表Computer[15][15][4] Player[15][15][4]; (2)主循环控制模块:主要担当一个调度者的角色。 (3)玩家下子:在Table[15][15]数组的相应地方记录‘2’,以 表明该子是玩家下的。 (4)盘面分析填写棋型表:人工智能算法的根本依据! (5)电脑下子:现在要作的就是让电脑知道在哪一点下子了。其中最简单的计算方法,就是遍历棋型表Computer[15][15][4]和Player[15][15][4]找出其中数值最大的一点,在该点下子即可。 (6)胜败判定:务须多言,某方形成五子连即获胜; 五子棋MFC界面展示: 心得体会: 这次制作人机对战五子棋,从一横一竖的棋盘制作,到键盘鼠标控制棋子下落,最终达到MFC的界面优化。从简单的人人对战判断输赢,到最终实现人机对战,甚至运用极大极小算法设置计算机智力等级。一行行代码,一次次编译失败,一次次调试,我们收获了C的乐趣,体会了编程的魅力。 未来展望: 当然还有太多的需要改进和提升的地方了,我们暂时还没有实现悔棋和添加残局的功能,希望在以后的学习中能够实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值