写了个人机对战的五子棋程序,根据极大极小值方法,主程序如下,需要整个源码的可发邮件给我:
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;
}