程序的一个BUG

C语言 码拜 5年前 (2016-06-04) 528次浏览
运行的时候,堵电脑的棋的话,它会覆盖本人的棋,而且有些地方还下不了,求帮助,谢谢
// 工程实践——五子棋Dlg.cpp : 实现文件
//
#include “stdafx.h”
#include “工程实践——五子棋.h”
#include “工程实践——五子棋Dlg.h”
#include “afxdialogex.h”
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// C工程实践——五子棋Dlg 对话框
C工程实践——五子棋Dlg::C工程实践——五子棋Dlg(CWnd* pParent /*=NULL*/)
: CDialogEx(C工程实践——五子棋Dlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void C工程实践——五子棋Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(C工程实践——五子棋Dlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_LBUTTONUP()
END_MESSAGE_MAP()
// C工程实践——五子棋Dlg 消息处理程序
BOOL C工程实践——五子棋Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于…”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
//  执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO:  在此添加额外的初始化代码
MoveWindow(0, 0, 550, 573);
CenterWindow();
GetDlgItem(IDOK)->ShowWindow(SW_HIDE);
GetDlgItem(IDCANCEL)->ShowWindow(SW_HIDE);
return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}
void C工程实践——五子棋Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 假如向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。
void C工程实践——五子棋Dlg::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
{
CDialogEx::OnPaint();
}
CDC *pDC = GetDC();
Draw(0, 0, IDB_BOARD, pDC);
/*Draw(355, 355, IDB_BLACK, pDC);*/
//Initialize board
for (int i = 0; i < 15;i++)
for (int j = 0; j < 15; j++)
chess[i][j] = 0;
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR C工程实践——五子棋Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void C工程实践——五子棋Dlg::Draw(int x, int y, UINT bitmap, CDC *pDC)
{
//load bitmap
CBitmap m_bmp;
m_bmp.LoadBitmap(bitmap);
//Create canvas
CDC dc;
dc.CreateCompatibleDC(pDC);
CBitmap *pOldbmp = dc.SelectObject(&m_bmp);
//Create bm for getting imformation of picture
BITMAP bm;
m_bmp.GetObject(sizeof(BITMAP), &bm);
//Draw a board
if (IDB_BOARD == bitmap)
pDC->BitBlt(x, y, bm.bmWidth, bm.bmHeight, &dc, 0, 0, SRCCOPY);
else
{
//Draw chess pirces
int w = bm.bmWidth;
int h = bm.bmHeight;
TransparentBlt(pDC->m_hDC, x, y, w, h, dc.m_hDC, 0, 0, w, h, RGB(255, 255, 255));
}
//Recover brush
dc.SelectObject(pOldbmp);
}
void C工程实践——五子棋Dlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO:  在此添加消息处理程序代码和/或调用默认值
if (point.x > 0 && point.x<525 && point.y>0 && point.y < 525)
{
int i = point.x / 35;
int j = point.y / 35;
int x = i * 35 + 5;
int y = j * 35 + 5;
CDC *pDC = GetDC();
//put the black piece while there is no chess piece
if (0 == chess[i][j])
{
Draw(x, y, IDB_BLACK, pDC);
chess[i][j] = 1;
AI();
}
if (win(i, j))
{
MessageBox(TEXT(“恭喜你赢啦!”),TEXT(“提示”), MB_OK);
Invalidate(FALSE);
}
}
CDialogEx::OnLButtonUp(nFlags, point);
}
int C工程实践——五子棋Dlg::check(int i,int j,int m,int n)
{
int tempi, tempj, count = -1;
int alive1 = 0, alive2 = 0;
//first check
tempi = i;
tempj = j;
while (tempi > 0 && tempi<15 && tempj>0 && tempj < 15 && chess[tempi][tempj] == chess[i][j])
{
tempi += m;
tempj += n;
count++;
}
if (chess[tempi][tempj] == 0)
alive1 = 1;
//second check
tempi = i;
tempj = j;
while (tempi > 0 && tempi<15 && tempj>0 && tempj < 15 && chess[tempi][tempj] == chess[i][j])
{
tempi -= m;
tempj -= n;
count++;
}
if (chess[tempi][tempj] == 0)
alive2 = 1;
if (count >= 5)
return 5;
else if (alive1&&alive2)
return count;
else if ((alive1 || alive2) && count != 1)
return count + 4;
return 0;
}
bool C工程实践——五子棋Dlg::win(int i,int j)
{
if (check(i, j, 0, 1) == 5 || check(i, j, 1, 0) == 5
|| check(i, j, 1, 1) == 5 || check(i, j, 1, -1) == 5)
return true;
return false;
}
void C工程实践——五子棋Dlg::AI()
{
//score of whtie and black
int white_value, black_value;
//the best location of white and black
int whitei, whitej, blacki, blackj;
//Get the best location and score
white_value = value(whitei, whitej, -1);
black_value = value(blacki, blackj, 1);
//Start play chess
CDC *pDC = GetDC();
int x, y;
//if black is more favorable,AI defend
if (white_value < black_value)
{
x = 5 + blackj * 35;
y = 5 + blacki * 35;
Draw(x, y, IDB_WHITE, pDC);
chess[blacki][blackj] = -1;
if (win(blacki, blackj))
{
MessageBox(TEXT(“对不起,你输了。”), TEXT(“提示”), MB_OK);
Invalidate(FALSE);
}
}
//if white is more favorable,AI attack
else
{
x = 5 + whitej * 35;
y = 5 + whitei * 35;
Draw(x, y, IDB_WHITE, pDC);
chess[whitei][whitej] = -1;
if (win(whitei, whitej))
{
MessageBox(TEXT(“对不起,你输了。”), TEXT(“提示”), MB_OK);
Invalidate(FALSE);
}
}
}
int C工程实践——五子棋Dlg::value(int &best_i,int &best_j,int color)
{
int maxvalue = 0,value;
for (int i = 1; i < 14; i++)
for (int j = 1; j < 14; j++)
{
if (color == chess[i][j])
{
for (int m = i – 1; m <= i + 1; m++)
for (int n = j – 1; n <= j + 1; n++)
{
if (0 == chess[m][n])
{
value = getscore(m, n, color);
if (maxvalue < value)
{
maxvalue = value;
best_i = m;
best_j = n;
}
}
}
}
}
return maxvalue;
}
/*int C工程实践——五子棋Dlg::value(int &best_i, int &best_j, int color)
{
if (-1 == color)
{
best_i = 1;
best_j = 1;
return 0;
}
if (1 == color)
{
best_i = 2;
best_j = 2;
return 1;
}
return 0;
}*/
int C工程实践——五子棋Dlg::getscore(int i,int j,int color)
{
int d4 = 0, d3 = 0, d2 = 0;
int a5 = 0, a4 = 0, a3 = 0, a2 = 0;
int status[4], score;
chess[i][j] = color;
//left to right
status[0] = check(i, j, 0, 1);
//right to left
status[1] = check(i, j, 1, 0);
//left up to right down
status[2] = check(i, j, 1, 1);
//left down to right up
status[3] = check(i, j, 1, -1);
chess[i][j] = 0;
//statistics
for (int n = 0; n < 4; n++)
{
switch (status[n])
{
case 8:
d4++;
break;
case 7:
d3++;
break;
case 6:
d2++;
break;
case 5:
a5 = 1;
break;
case 4:
a4 = 1;
break;
case 3:
a3++;
break;
case 2:
a2++;
break;
}
}
if (a5)
score = 100000;
else if (a4)
score = 10000;
else if (d4 >= 2)
score = 10000;
else if (d4&&a3)
score = 10000;
else if (a3 >= 2)
score = 5000;
else if (a3&&a2 >= 2)
score = 5000;
else if (a3&&d3)
score = 1000;
else if (1 == d4)
score = 500;
else if (1 == a3)
score = 200;
else if (a2 >= 2)
score = 100;
else if (d3 >= 2)
score = 50;
else if (1 == a2)
score = 10;
else if (1 == d3)
score = 5;
return score;
}
解决方案

160

代码功能归根结底不是别人帮本人看或讲解或注释出来的;而是被本人静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生本人领悟和上厕所!
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明程序的一个BUG
喜欢 (0)
[1034331897@qq.com]
分享 (0)