文档库 最新最全的文档下载
当前位置:文档库 › Windows编程五子棋小游戏

Windows编程五子棋小游戏

《Windows编程》大作业

题目:基于MFC的五子棋游戏实现

姓名:陈禹同

学号:1405130040

班级:软工1405

专业:软件工程

院系:数学与计算机

指导教师:刘文涛

MFC程序五子棋实验报告

一.实验内容:

通过学习MFC应用程序开发,应用MFC控件等方面知识,编译一个简单的五子棋人人对战游戏。

二.实验过程:

(1)算法设计原理

五子棋的游戏规则对我们大家来说都很很清楚的。只要某一方的棋子在一条直线上,棋子数先达到五或以上,则该方为胜者。根据游戏规则,算法设计分以下几个方面:

A.棋盘设计:

棋盘的设计主要是控件知识的应用。在棋盘的设计中所定义的控件主要有下面几种:

IDC_BUTTON_START(开始按钮)

IDC_BUTTON_END(结束按钮)

IDC_BUTTON_CHOICE(选择按钮)

IDC_RADIO1(黑棋先按钮)

IDC_RADIO2(白棋先按钮)

IDC_STATIC_BITMAP11到IDC_STATIC_BITMAP1012(棋盘位图120个)

IDC_BUTTON11到IDC_BUTTON1012(棋盘按钮120个)

IDC_TEST_DIOLOG(对话框控件)

IDC_STATIC(分组框两个)

棋盘设计是用一个对话框实现,再加上控件的使用,就形成一个简单的棋盘。

B.棋子设计

棋子的设计是小组人员自己用作图工具做出来的,黑白棋的实际如下图所示,其中最后一个图片是加载棋盘的位图,棋盘就是有多个位图合并出来的。

三个位图分别定义为:BITMAP1,BITMAP2,BITMAP3,如下图

C.开始函数

开始函数就是为开始按钮添加消息映射函数,开始函数需要实现的功能是,通过单击按钮,能够把所有构成棋盘的位图加载一遍,即相当于初始化棋盘,并且,如果棋盘上有棋子的位图的话,把棋子的位图清除,即相当于“清屏”其函数定义为:DeleteObject();开始函数的定义为:OnButtonStart() 。

D.结束函数

结束函数是为结束按钮添加的消息映射函数,其所要实现的功能是,单击结束按钮,弹出一个消息窗口,弹出消息,提示下一步要做什么。这里提示返回开始按钮,结束函数定义为:OnButtonEnd()。

E.下棋子函数

下棋子函数实现的时候,要考虑到两点,一点是单击开始按钮后,是否进行了选择,二是选择黑棋先还是白棋先。当点击棋盘上按钮时,如果没有进行选择,就弹出消息对话框,输出“请选择开局棋色”,如果进行了选择,就执行所对应的函数,白棋先的对应函数是LoadBitmap(IDB_BITMAP2);

黑棋先的对应函数是:LoadBitmap(IDB_BITMAP3);

下棋子函数定义为OnButton11()~OnButton1012();

F.选择先下棋色函数

该函数所要实现的功能是点击选择按钮,来选择开局先下棋子的棋色,其中,单击选择后,默认为白棋先下,如果想要改变的话,可以单击选择上面的复选框按钮,进行改变,白棋先下所对应的消息映射函数是:

CheckRadioButton(IDC_RADIO1,IDC_RADIO2,IDC_RADIO2);

黑棋先下所对应的消息映射函数是:

CheckRadioButton(IDC_RADIO1,IDC_RADIO2,IDC_RADIO1);

选择函数的定义为:OnButtonChoice();

G.判断输赢函数

五子棋胜利的条件是一方的五个棋子连成一条直线,包括纵,横,左斜,右斜四种,可以用二维数组来保存每个位置棋子的值,分别用0,1,2来表示无棋,黑棋,白棋,每当下一个棋子后,用值保存其颜色,当白棋或者黑棋有一者符合上述四种情况之一时,就可以判断出哪方胜利.

判断输赢函数定义为:IsOver(int x,int y,int z)

(2)编码以及函数实现

CTable::CTable()

{

// 初始化玩家姓名

TCHAR str[10];

CFiveApp *pApp = (CFiveApp *)AfxGetApp();

::GetPrivateProfileString( _T("Options"), _T("Name"), _T("Renjiu"), str, 15, pApp->m_szIni );

m_strMe = str;

// 初始化图像列表

m_iml.Create( 24, 24, ILC_COLOR24 | ILC_MASK, 0, 2 );

// 载入黑、白棋子掩码位图

CBitmap bmpBlack, bmpWhite;

bmpBlack.LoadBitmap( IDB_BMP_BLACK );

m_iml.Add( &bmpBlack, 0xff00ff );

bmpWhite.LoadBitmap( IDB_BMP_WHITE );

m_iml.Add( &bmpWhite, 0xff00ff );

// 初始化游戏模式

m_pGame = NULL;

}

//////////////////////////////////////////////////////////////////////////

// 析构函数,释放m_pGame指针

//////////////////////////////////////////////////////////////////////////

CTable::~CTable()

{

// 写入玩家姓名

CFiveApp *pApp = (CFiveApp *)AfxGetApp();

::WritePrivateProfileString( _T("Options"), _T("Name"), m_strMe,

pApp->m_szIni );

// 写入战绩统计

TCHAR str[10];

wsprintf( str, _T("%d"), pApp->m_nWin );

::WritePrivateProfileString( _T("Stats"), _T("Win"), str, pApp->m_szIni );

wsprintf( str, _T("%d"), pApp->m_nDraw );

::WritePrivateProfileString( _T("Stats"), _T("Draw"), str, pApp->m_szIni );

wsprintf( str, _T("%d"), pApp->m_nLost );

::WritePrivateProfileString( _T("Stats"), _T("Lost"), str, pApp->m_szIni );

if ( NULL != m_pGame )

delete m_pGame;

}

//////////////////////////////////////////////////////////////////////////

// 在指定棋盘坐标处绘制指定颜色的棋子

//////////////////////////////////////////////////////////////////////////

void CTable::Draw( int x, int y, int color )

{

POINT pt;

pt.x = 12 + 25 * x;

pt.y = 84 + 25 * y;

CDC *pDC = GetDC();

CPen pen;

pen.CreatePen( PS_SOLID, 1, 0xff );

pDC->SelectObject( &pen );

pDC->SetROP2( R2_NOTXORPEN );

m_iml.Draw( pDC, color, pt, ILD_TRANSPARENT );

STEP step;

// 利用R2_NOTXORPEN擦除先前画出的矩形

if ( !m_pGame->m_StepList.empty() )

{

// 获取最后一个点

step = *( m_pGame->m_StepList.begin() );

pDC->MoveTo( 11 + 25 * step.x, 83 + 25 * step.y );

pDC->LineTo( 36 + 25 * step.x, 83 + 25 * step.y );

pDC->LineTo( 36 + 25 * step.x, 108 + 25 * step.y );

pDC->LineTo( 11 + 25 * step.x, 108 + 25 * step.y );

pDC->LineTo( 11 + 25 * step.x, 83 + 25 * step.y );

}

// 更新最后落子坐标数据,画新的矩形

step.color = color;

step.x = x;

step.y = y;

m_pGame->m_StepList.push_front( step );

pDC->MoveTo( 11 + 25 * step.x, 83 + 25 * step.y );

pDC->LineTo( 36 + 25 * step.x, 83 + 25 * step.y );

pDC->LineTo( 36 + 25 * step.x, 108 + 25 * step.y );

pDC->LineTo( 11 + 25 * step.x, 108 + 25 * step.y );

pDC->LineTo( 11 + 25 * step.x, 83 + 25 * step.y );

ReleaseDC( pDC );

}

//////////////////////////////////////////////////////////////////////////

// 清空棋盘

//////////////////////////////////////////////////////////////////////////

void CTable::Clear( BOOL bWait )

{

int x, y;

for ( y = 0; y < 15; y++ )

{

for ( x = 0; x < 15; x++ )

{

m_data[x][y] = -1;

}

}

// 设置等待标志

m_bWait = bWait;

Invalidate();

// 删除游戏

if ( m_pGame != NULL )

{

delete m_pGame;

m_pGame = NULL;

}

}

//////////////////////////////////////////////////////////////////////////

// 设置玩家颜色

//////////////////////////////////////////////////////////////////////////

void CTable::SetColor( int color )

{

m_color = color;

}

//////////////////////////////////////////////////////////////////////////

// 获取玩家颜色

//////////////////////////////////////////////////////////////////////////

int CTable::GetColor() const

{

return m_color;

}

//////////////////////////////////////////////////////////////////////////

// 设置等待标志,返回先前的等待标志

//////////////////////////////////////////////////////////////////////////

BOOL CTable::SetWait( BOOL bWait )

{

m_bOldWait = m_bWait;

m_bWait = bWait;

return m_bOldWait;

}

//////////////////////////////////////////////////////////////////////////

// 设置棋盘数据,并绘制棋子

//////////////////////////////////////////////////////////////////////////

void CTable::SetData( int x, int y, int color )

{

m_data[x][y] = color;

Draw( x, y, color );

}

//////////////////////////////////////////////////////////////////////////

// 判断指定颜色是否胜利

//////////////////////////////////////////////////////////////////////////

BOOL CTable::Win( int color ) const

{

int x, y;

// 判断横向

for ( y = 0; y < 15; y++ )

{

for ( x = 0; x < 11; x++ )

{

if ( color == m_data[x][y] && color == m_data[x + 1][y] &&

color == m_data[x + 2][y] && color == m_data[x + 3][y] &&

color == m_data[x + 4][y] )

{

return TRUE;

}

}

}

// 判断纵向

for ( y = 0; y < 11; y++ )

{

for ( x = 0; x < 15; x++ )

{

if ( color == m_data[x][y] && color == m_data[x][y + 1] &&

color == m_data[x][y + 2] && color == m_data[x][y + 3] &&

color == m_data[x][y + 4] )

{

return TRUE;

}

}

}

// 判断“\”方向

for ( y = 0; y < 11; y++ )

{

for ( x = 0; x < 11; x++ )

{

if ( color == m_data[x][y] && color == m_data[x + 1][y + 1] &&

color == m_data[x + 2][y + 2] && color == m_data[x + 3][y + 3] &&

color == m_data[x + 4][y + 4] )

{

return TRUE;

}

}

}

// 判断“/”方向

for ( y = 0; y < 11; y++ )

{

for ( x = 4; x < 15; x++ )

{

if ( color == m_data[x][y] && color == m_data[x - 1][y + 1] &&

color == m_data[x - 2][y + 2] && color == m_data[x - 3][y + 3] &&

color == m_data[x - 4][y + 4] )

{

return TRUE;

}

}

}

// 不满足胜利条件

return FALSE;

}

(3)调试运行以及实验结果分析

下面是程序运行结果的主窗口,如图,包括棋盘,选择游戏-单人游戏按钮。点击开始按钮,所有位图加载一遍,准备开始棋局。

下图是点击开始按钮之后,游戏中黑白子依次下棋。

下图是一个简单的棋局结果截图,如图,当黑棋或白棋有五个子两在一起时,会判断出哪方获胜,这也就实现了判断哪方获胜功能,至于纵轴方向以及左斜或者右斜获胜如何实现,可以看具体的函数编码。

四.实验总结:

这次MFC程序的的实验操作,使我们更加熟练地掌握并运用本学期所学的windows程序设计的基础内容,在实验过程中,我们通过参考教材,应用课堂老师所讲的知识和我们所学习的c++的知识相结合,并经过讨论,实现了这个

简单的五子棋应用程序,对我说,这也算是我学习windows程序半年来所做的一些小成果吧,虽然我做出了这个小程序,但并不代表我已经完全掌握了程序设计的知识,要想更深的理解并熟练应用或者从事windows程序设计工作,我就不能满足现在所学的知识,我还要自己自己去主动学习更多的知识。知实验过程中,老师也向我们提出了指导性的建议,因此,在这里还要感谢老师,同时,我还应该多多向老师学习,在以后的学习中希望能够学到更多的东西。当然,实验中还有不足之处,但是我会在以后的学习中进行改进,争取更完美。

相关文档
相关文档 最新文档