救救我的五子棋程序啊

sms88 2006-05-30 08:41:10
为何我一单击鼠标左键就会 系统没有反应 .我只能强制关电源重启了.

我的程序是参考<<MFC windows程序设计>> 中的第三章 改编出来的

//TicTac.h

#define EX 1
#define OH 2

class com
{
public:
com(int i=0, int j=0)
{
m=i;
n=j;
};

int m;
int n;
}; //为了保存的棋子的坐标

class CMyApp : public CWinApp
{
public:
virtual BOOL InitInstance ();
};

class CMainWindow : public CWnd
{
protected:
CRect m_rcSquares[20][20]; // Grid coordinates
int m_nGameGrid[20][20]; // Grid contents
int m_nNextChar; // Next character (EX or OH)

com GetRectID (CPoint & point);
void DrawBoard (CDC* pDC);
void DrawX (CDC* pDC, com & nPos);
void DrawO (CDC* pDC, com & nPos);
void ResetGame ();
void CheckForGameOver ();
int IsWinner ();
BOOL IsDraw ();

public:
CMainWindow ();

protected:
virtual void PostNcDestroy ();

afx_msg void OnPaint ();
afx_msg void OnLButtonDown (UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk (UINT nFlags, CPoint point);
afx_msg void OnRButtonDown (UINT nFlags, CPoint point);

DECLARE_MESSAGE_MAP ()
};
...全文
246 11 打赏 收藏 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
sms88 2006-05-30
  • 打赏
  • 举报
回复
不知道这里是不是有问题
//初始化棋子的坐标位置
for(int i=0;i<20;i++)
for(int j=0;j<20;j++)
m_rcSquares[i][j]=CRect( i*50 , j*50 , (j+1)*50 , (i+1)*50 ) ;

我是想20*20个,每个50宽.50高
lisypro 2006-05-30
  • 打赏
  • 举报
回复
你很急么
给把程序发到我的邮件罢lisypro@sohu.com
我帮你调一下
thisisll 2006-05-30
  • 打赏
  • 举报
回复
http://www.chinaai.org/Soft_Show.asp?SoftID=39
PC游戏编程(人机博弈)

着本书很好
最后还专门写了五子棋的例子
sms88 2006-05-30
  • 打赏
  • 举报
回复
2个循环我都改好了,没有了死循环
可是不知道为什么还是不能得到自己想要的五子棋
WecanHuang 2006-05-30
  • 打赏
  • 举报
回复
帮顶
thisisll 2006-05-30
  • 打赏
  • 举报
回复
你的J在循环体内
没有变化啊
用这个循环是什么意思?
billy145533 2006-05-30
  • 打赏
  • 举报
回复
应该是进入死循环了
检查这个函数IsWinner ()
while(j<20)
{
if(j+5>=20)
break;
if( m_nGameGrid[i][j]==EX && m_nGameGrid[i][j+1]==EX &&
m_nGameGrid[i][j+2]==EX && m_nGameGrid[i][j+3]==EX &&
m_nGameGrid[i][j+4]==EX )
return retrust=EX;
if( m_nGameGrid[i][j]==OH && m_nGameGrid[i][j+1]==OH &&
m_nGameGrid[i][j+2]==OH && m_nGameGrid[i][j+3]==OH &&
m_nGameGrid[i][j+4]==OH )
return retrust=OH;
}

如果j只满足while条件,那么就会死循环.
sms88 2006-05-30
  • 打赏
  • 举报
回复
void CMainWindow::CheckForGameOver ()
{
int nWinner;

//
// If the grid contains three consecutive Xs or Os, declare a winner
// and start a new game.
//
if (nWinner = IsWinner ()) {
CString string = (nWinner == EX) ?
_T ("X wins!") : _T ("O wins!");
MessageBox (string, _T ("Game Over"), MB_ICONEXCLAMATION | MB_OK);
ResetGame ();
}

//
// If the grid is full, declare a draw and start a new game.
//
else if (IsDraw ()) {
MessageBox (_T ("It's a draw!"), _T ("Game Over"),
MB_ICONEXCLAMATION | MB_OK);
ResetGame ();
}
}

int CMainWindow::IsWinner ()
{
int retrust=0;
int i=0;
int j=0;
int m,n;
//水平位置是否有5个棋子连在一起
while(i<20)
{
while(j<20)
{
if(j+5>=20)
break;
if( m_nGameGrid[i][j]==EX && m_nGameGrid[i][j+1]==EX &&
m_nGameGrid[i][j+2]==EX && m_nGameGrid[i][j+3]==EX &&
m_nGameGrid[i][j+4]==EX )
return retrust=EX;
if( m_nGameGrid[i][j]==OH && m_nGameGrid[i][j+1]==OH &&
m_nGameGrid[i][j+2]==OH && m_nGameGrid[i][j+3]==OH &&
m_nGameGrid[i][j+4]==OH )
return retrust=OH;
}
i++;
}
//垂直位置是否有5个棋子连在一起
i=j=0;
while(j<20)
{
while(i<20)
{
if(i+5>=20)
break;
if( m_nGameGrid[i][j]==EX && m_nGameGrid[i+1][j]==EX &&
m_nGameGrid[i+2][j]==EX && m_nGameGrid[i+3][j]==EX &&
m_nGameGrid[i+4][j]==EX )
return retrust=EX;
if( m_nGameGrid[i][j]==OH && m_nGameGrid[i+1][j]==OH &&
m_nGameGrid[i+2][j]==OH && m_nGameGrid[i+3][j]==OH &&
m_nGameGrid[i+4][j]==OH )
return retrust=OH;
}
j++;
}

//左上到右下斜线是否有5个棋子连在一起
i=j=0;
while(i<20)
{
while(j<20)
{
m=i;
n=j;
if(m+5>=20 ||n+5>=20)
break;
while(m<20 && n<20)
{
if( m_nGameGrid[m][n]==EX && m_nGameGrid[m+1][n+1]==EX &&
m_nGameGrid[m+2][n+2]==EX && m_nGameGrid[m+3][n+3]==EX &&
m_nGameGrid[m+4][n+4]==EX )
return retrust=EX;
if( m_nGameGrid[m][n]==OH && m_nGameGrid[m+1][n+1]==OH &&
m_nGameGrid[m+2][n+2]==OH && m_nGameGrid[m+3][n+3]==OH &&
m_nGameGrid[m+4][n+4]==OH )
return retrust=OH;
m++; n++;
}
j++;
}
i++;
}

//左下到右上斜线是否有5个棋子连在一起
i=19;
j=0;
while(i>=0)
{
while(j<20)
{
m=i;
n=j;
if(m-5<0 ||n+5>=20)
break;
while(m<20 && n<20)
{
if( m_nGameGrid[m][n]==EX && m_nGameGrid[m-1][n+1]==EX &&
m_nGameGrid[m-2][n+2]==EX && m_nGameGrid[m-3][n+3]==EX &&
m_nGameGrid[m-4][n+4]==EX )
return retrust=EX;
if( m_nGameGrid[m][n]==OH && m_nGameGrid[m-1][n+1]==OH &&
m_nGameGrid[m-2][n+2]==OH && m_nGameGrid[m-3][n+3]==OH &&
m_nGameGrid[m-4][n+4]==OH )
return retrust=OH;
m--; n++;
}
j++;
}
i--;
}
return retrust;
}

BOOL CMainWindow::IsDraw ()
{
BOOL retrust=TRUE;
for(int i=0;i<20;i++)
for(int j=0;j<20;j++)
{
if (m_nGameGrid[i][j] == 0)
retrust=FALSE;
}
return retrust;
}

void CMainWindow::ResetGame ()
{
m_nNextChar = EX;
::ZeroMemory (m_nGameGrid, 400 * sizeof (int));
Invalidate ();
}
sms88 2006-05-30
  • 打赏
  • 举报
回复
//TicTac.pp

#include <afxwin.h>
#include "TicTac.h"
CMyApp myApp;
/////////////////////////////////////////////////////////////////////////
// CMyApp member functions

BOOL CMyApp::InitInstance ()
{
m_pMainWnd = new CMainWindow;
m_pMainWnd->ShowWindow (m_nCmdShow);
m_pMainWnd->UpdateWindow ();
return TRUE;
}

/////////////////////////////////////////////////////////////////////////
// CMainWindow message map and member functions

BEGIN_MESSAGE_MAP (CMainWindow, CWnd)
ON_WM_PAINT ()
ON_WM_LBUTTONDOWN ()
ON_WM_LBUTTONDBLCLK ()
ON_WM_RBUTTONDOWN ()
END_MESSAGE_MAP ()



CMainWindow::CMainWindow ()
{
//初始化棋子的位置
for(int i=0;i<20;i++)
for(int j=0;j<20;j++)
m_rcSquares[i][j]=CRect( i*50 , j*50 , (j+1)*50 , (i+1)*50 ) ;

m_nNextChar = EX;
::ZeroMemory (m_nGameGrid, 400 * sizeof (int));

//
// Register a WNDCLASS.
//
CString strWndClass = AfxRegisterWndClass (
CS_DBLCLKS, // Class style
AfxGetApp ()->LoadStandardCursor (IDC_ARROW), // Class cursor
(HBRUSH) (COLOR_3DFACE + 1), // Background brush
AfxGetApp ()->LoadStandardIcon (IDI_WINLOGO) // Class icon
);

//
// Create a window.
//
CreateEx (0, strWndClass, _T ("Tic-Tac-Toe"),
WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL);

//
// Size the window.
//
CRect rect (0, 0, 1000, 1000);
CalcWindowRect (&rect);

SetWindowPos (NULL, 0, 0, rect.Width (), rect.Height (),
SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW);
}

void CMainWindow::PostNcDestroy ()
{
delete this;
}

void CMainWindow::OnPaint ()
{
CPaintDC dc (this);
DrawBoard (&dc);
}

void CMainWindow::OnLButtonDown (UINT nFlags, CPoint point)
{
//
// Do nothing if it's O's turn, if the click occurred outside the
// tic-tac-toe grid, or if a nonempty square was clicked.
//
if (m_nNextChar != EX)
return;

com nPos = GetRectID (point);
if ((nPos.m== -1) || (m_nGameGrid[nPos.m][nPos.n] != 0))
return;

//
// Add an X to the game grid and toggle m_nNextChar.
//
m_nGameGrid[nPos.m][nPos.n] = EX;
m_nNextChar = OH;

//
// Draw an X on the screen and see if either player has won.
//
CClientDC dc (this);
DrawX (&dc, nPos);
CheckForGameOver ();
}

void CMainWindow::OnRButtonDown (UINT nFlags, CPoint point)
{
//
// Do nothing if it's X's turn, if the click occurred outside the
// tic-tac-toe grid, or if a nonempty square was clicked.
//
if (m_nNextChar != OH)
return;

com nPos = GetRectID (point);
if ((nPos.m== -1) || (m_nGameGrid[nPos.m][nPos.n] != 0))
return;

//
// Add an O to the game grid and toggle m_nNextChar.
//
m_nGameGrid[nPos.m][nPos.n] = OH;
m_nNextChar = EX;

//
// Draw an O on the screen and see if either player has won.
//
CClientDC dc (this);
DrawO (&dc, nPos);
CheckForGameOver ();
}

void CMainWindow::OnLButtonDblClk (UINT nFlags, CPoint point)
{
//
// Reset the game if one of the thick black lines defining the game
// grid is double-clicked with the left mouse button.
//
ResetGame ();
}

com CMainWindow::GetRectID (CPoint& point)
{
//
// Hit-test each of the grid's nine squares and return a rectangle ID
// (0-8) if (point.x, point.y) lies inside a square.
//
for (int i=0; i<20; i++)
for(int j=0;j<20;j++)
{
if (m_rcSquares[i][j].PtInRect (point))
return (i,j);
}
return (-1,-1);
}

void CMainWindow::DrawBoard (CDC* pDC)
{
//
// Draw the lines that define the tic-tac-toe grid.
//
CPen pen (PS_SOLID, 1, RGB (0, 0, 0));
CPen* pOldPen = pDC->SelectObject (&pen);
for(int j = 50 ; j <= 1000 ; j += 100 )
{
pDC->MoveTo(j,0);
pDC->LineTo(j,1000);
}
for(int k = 50 ; k <= 1000 ; k += 100 )
{
pDC->MoveTo(0,k);
pDC->LineTo(1000,k);
}
//
// Draw the Xs and Os.
//
for(int i=0;i<20;i++)
for(int j=0;j<20;j++)
{

if (m_nGameGrid[i][j] == EX)
{
com A(i,j);
DrawX (pDC, A);
}
else if (m_nGameGrid[i][j] == OH)
{
com B(i,j);
DrawO (pDC, B);
}
}
pDC->SelectObject (pOldPen);
}

void CMainWindow::DrawX (CDC* pDC, com & nPos)
{
CPen pen (PS_SOLID, 16, RGB (0, 0, 255));
CPen* pOldPen = pDC->SelectObject (&pen);
pDC->SelectStockObject (NULL_BRUSH);

CRect rect = m_rcSquares[nPos.m][nPos.n];
// rect.DeflateRect (16, 16);
pDC->Ellipse (rect);

pDC->SelectObject (pOldPen);
}

void CMainWindow::DrawO (CDC* pDC, com & nPos)
{
CPen pen (PS_SOLID, 16, RGB (0, 0, 255));
CPen* pOldPen = pDC->SelectObject (&pen);
pDC->SelectStockObject (NULL_BRUSH);

CRect rect = m_rcSquares[nPos.m][nPos.n];
// rect.DeflateRect (16, 16);
pDC->Ellipse (rect);

pDC->SelectObject (pOldPen);
}
yangxingkuan 2006-05-30
  • 打赏
  • 举报
回复
头都看晕了,帮顶
thisisll 2006-05-30
  • 打赏
  • 举报
回复
你应该把棋子和坐标独立开
当得到一个CPoint的时候再去算他在棋盘中的位置

我给你推荐的书对你帮助肯定很大,建议你看看

16,550

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧