井字棋游戏 代码分析

井字棋游戏

 

开发工具:Visual C++.NET 2003

程序员:黄江斌

程序功能:井字棋小游戏,人机对战版

时间:2005828

 

界面如下图:

 

程序分析:

 

CtictactoeView::CtictactoeView()//程序中关键变量赋初值

{

       // TODO: 在此处添加构造代码

       int i , j;

       for( i = 0 ; i < 3 ; i++ )

              for( j = 0 ; j < 3 ; j++ )

                     myGraph[i][j] = 0;

       currX = -1;

       currY = -1;

       whosTurn = 1;

       whosFirst = 1;

}

 

void CtictactoeView::OnDraw(CDC* pDC)//程序界面、游戏状态的显示

{

       CtictactoeDoc* pDoc = GetDocument();

       ASSERT_VALID(pDoc);

       if (!pDoc)

              return;

 

       // TODO: 在此处为本机数据添加绘制代码

       CBitmap bitmap[9];

       CBitmap *pOldBitmap;

       CDC MemDC;   

       int i , j;

       int myTop = 5;

       int myLeft;

       int mySize = 100;

 

       MemDC.CreateCompatibleDC( pDC );

 

       for( i = 0 ; i < 3 ; i++ )

       {

              myTop = 5 + 105 * i;

              myLeft = 5;

              for( j = 0 ; j < 3 ; j++ )

              {

                     myLeft = 5 + 105 * j;

                     if( myGraph[i][j] == 0 )

                     {

                            bitmap[ 3 * i + j ].LoadBitmap( IDB_BACKGROUND );

                     }

                     else if( myGraph[i][j] == 1 )

                     {

                            bitmap[ 3 * i + j ].LoadBitmap( IDB_CROSS );

                     }

                     else if( myGraph[i][j] == 2 )

                     {

                            bitmap[ 3 * i + j ].LoadBitmap( IDB_ROUND );

                     }

                     else

                     {

                            bitmap[3 * i + j ].LoadBitmap( IDB_CHOOSE );

                     }

                     pOldBitmap = MemDC.SelectObject( &bitmap[ 3 * i + j ] );

                     pDC->BitBlt( myLeft , myTop , mySize , mySize , &MemDC , 0 , 0 , SRCCOPY );

                     MemDC.SelectObject( pOldBitmap );

              }

       }

}

 

void CtictactoeView::OnMouseMove(UINT nFlags, CPoint point)//跟踪鼠标位置

{

       // TODO: 在此添加消息处理程序代码和/或调用默认值

       this->point = point;

 

       int x , y;

 

       x = -1;

       y = -1;

 

       if( point.x >= 5 && point.x <= 105 )

              x = 0;

       else if( point.x >= 110 && point.x <= 210 )

              x = 1;

       else if( point.x >= 215 && point.x <= 315 )

              x = 2;

       if( point.y >= 5 && point.y <= 105 )

              y = 0;

       else if( point.y >= 110 && point.y <= 210 )

              y = 1;

       else if( point.y >= 215 && point.y <= 315 )

              y = 2;

 

       CRect mRect;

 

       if( currX == x && currY == y )

              return;

 

       if( currX != -1 && currY != -1 && myGraph[currY][currX] == 3 )

       {

              myGraph[currY][currX] = 0;

              mRect = CRect( 5 + currX * 105 , 5 + currY * 105 , 105 + currX * 105 , 105 + currY * 105 );

              InvalidateRect( mRect );

              currX = -1;

              currY = -1;

       }

 

       if( x != -1 && y != -1 && myGraph[y][x] == 0 )

       {

              currX = x;

              currY = y;

              myGraph[y][x] = 3;

              mRect = CRect( 5 + x * 105 , 5 + y * 105 , 105 + x * 105 , 105 + y * 105 );

              InvalidateRect( mRect );           

       }

       CView::OnMouseMove(nFlags, point);

}

 

void CtictactoeView::OnMouseX( CCmdUI *pCmdUI )//在状态栏中显示鼠标位置

{

       CString cs;

       cs.Format( "X=%d", point.x );

       pCmdUI->SetText( cs );

}

void CtictactoeView::OnMouseY( CCmdUI *pCmdUI ) //在状态栏中显示鼠标位置

{

       CString cs;

       cs.Format( "Y=%d", point.y );

       pCmdUI->SetText( cs );

}

void CtictactoeView::OnWhosFirst( CCmdUI *pCmdUI )//在状态栏中显示电脑先走还是人先走

{

       if( whosFirst == 2 )

              pCmdUI->SetText( "电脑先" );

       else

              pCmdUI->SetText( "用户先" );

}

void CtictactoeView::OnLButtonDown(UINT nFlags, CPoint point)//人走棋的输入部分

{

       // TODO: 在此添加消息处理程序代码和/或调用默认值

       if( currX == -1 || currY == -1 )

       {

       }

       else

       {

              myGraph[currY][currX] = whosTurn;

              CRect mRect;

              mRect = CRect( 5 + currX * 105 , 5 + currY * 105 , 105 + currX * 105 , 105 + currY * 105 );

              InvalidateRect( mRect );

              if( whosTurn == 1 )

                     whosTurn = 2;

              else

                     whosTurn = 1;

              currX = -1;

              currY = -1;

             

              int ret = judgment();

 

              if( ret == 0 )

                     computerPlay();

              else

                     winner( ret );

       }

       CView::OnLButtonDown(nFlags, point);

}

 

void CtictactoeView::computerPlay(void) //电脑走棋的人工智能部分

{

       long score[3][3];

       long maxScore;

       int x,y;

       int i,j,k;

       int me = 2;

       int another = 1;

       for( i = 0 ; i < 3 ; i++ )

              for( j = 0 ; j < 3 ; j++ )

              {

                     score[i][j] = 0;

                     if( myGraph[i][j] != 0 )

                            continue;

 

                     if( ( i + j ) % 2 == 0 )

                            score[i][j] += 10;

                     else

                            score[i][j] += 1;

 

                     if( i == 1 && j == 1 )

                            score[i][j] += 90;

 

                     for( k = 0 ; k < 3 ; k++ )

                            if( k != j )

                            {

                                   if( myGraph[i][k] == me )

                                   {

                                          if( myGraph[i][3-j-k] == me )

                                                 score[i][j] += 100000;

                                          else if( myGraph[i][3-j-k] == 0 )

                                                 score[i][j] += 1000;

                                          break;

                                   }

                                   else if( myGraph[i][k] == another )

                                   {

                                          if( myGraph[i][3-j-k] == another )

                                                 score[i][j] += 10000;

                                          else if( myGraph[i][3-j-k] == 0 )

                                                 score[i][j] += 750;

                                          break;

                                   }

                            }

                     for( k = 0 ; k < 3 ; k++ )

                            if( k != i )

                            {

                                   if( myGraph[k][j] == me )

                                   {

                                          if( myGraph[3-i-k][j] == me )

                                                 score[i][j] += 1000000;

                                          else if( myGraph[3-i-k][j] == 0 )

                                                 score[i][j] += 1000;

                                          break;

                                   }

                                   else if( myGraph[k][j] == another )

                                   {

                                          if( myGraph[3-i-k][j] == another )

                                                 score[i][j] += 10000;

                                          else if( myGraph[3-i-k][j] == 0 )

                                                 score[i][j] += 750;

                                          break;

                                   }

                            }

                            if( i == j )

                            {

                                   for( k = 0 ; k < 3 ; k++ )

                                          if( k != i )

                                          {

                                                 if( myGraph[k][k] == me )

                                                 {

                                                        if( myGraph[3-i-k][3-i-k] == me )

                                                               score[i][j] += 1000000;

                                                        else if( myGraph[3-i-k][3-i-k] == 0 )

                                                               score[i][j] += 1000;

                                                        break;

                                                 }

                                                 else if( myGraph[k][k] == another )

                                                 {

                                                        if( myGraph[3-i-k][3-i-k] == another )

                                                               score[i][j] += 10000;

                                                        else if( myGraph[3-i-k][3-i-k] == 0 )

                                                               score[i][j] += 750;

                                                        break;

                                                 }

                                          }

                            }

                            if( ( i + j ) == 2 )

                            {

                                   for( k = 0 ; k < 3 ; k++ )

                                          if( k != i && 2 - k != j )

                                          {

                                                 if( myGraph[k][2-k] == me )

                                                 {

                                                        if( myGraph[3-i-k][i+k-1] == me )

                                                               score[i][j] += 1000000;

                                                        else if( myGraph[3-i-k][i+k-1] == 0 )

                                                               score[i][j] += 1000;

                                                        break;

                                                 }

                                                 else if( myGraph[k][2-k] == another )

                                                 {

                                                        if( myGraph[3-i-k][i+k-1] == another )

                                                               score[i][j] += 10000;

                                                        else if( myGraph[3-i-k][i+k-1] == 0 )

                                                               score[i][j] += 750;

                                                        break;

                                                 }

                                          }

                            }

              }

       maxScore = 0;

       for( i = 0 ; i < 3 ; i++ )

              for( j = 0 ; j < 3 ; j++ )

                     if( score[i][j] > maxScore )

                     {

                            maxScore = score[i][j];

                            x = i;

                            y = j;

                     }

 

       CRect mRect;

       mRect = CRect( 5 + y * 105 , 5 + x * 105 , 105 + y * 105 , 105 + x * 105 );

       InvalidateRect( mRect );    

 

       myGraph[x][y] = whosTurn;

       if( whosTurn == 1 )

              whosTurn = 2;

       else

              whosTurn = 1;

 

       int ret = judgment();

 

       if( ret != 0 )

              winner( ret );

}

 

int  CtictactoeView::judgment()//判断是否已经结束游戏,判决谁赢得比赛

{

       int who;

       int i,j;

       bool flag;

       for( who = 1 ; who <= 2 ; who++ )

       {

              //检查玩家who在行上是否成胜状态

              for( i = 0 ; i < 3 ; i++ )

              {

                     flag = true;

                     for( j = 0 ; j < 3 && flag ;j++ )

                            if( myGraph[i][j] != who )

                                   flag = false;

                     //如果有成胜状态,就可以返回了

                     if( flag )

                            return who;

              }

              for( j = 0 ; j < 3 ; j++ )

              {

                     flag = true;

                     for( i = 0 ; i < 3 && flag ; i++ )

                            if( myGraph[i][j] != who )

                                   flag = false;

 

                     if( flag )

                            return who;

              }

              //检查斜列1有无成胜状态

              flag = true;

              for( i = 0 ; i < 3 && flag ; i++ )

                     if( myGraph[i][i] != who )

                            flag = false;

              if( flag )

                     return who;

              //检查斜列2有无成胜状态

              flag = true;

              for( i = 0 ; i < 3 && flag ; i++ )

                     if( myGraph[i][3-i-1] != who )

                            flag = false;

              if( flag )

                     return who;

       }

       flag = true;

       for( i = 0 ; i < 3 && flag ; i++ )

              for( j = 0 ; j < 3 && flag ; j++ )

                     if( myGraph[i][j] == 0 )

                            flag = false;

       if( flag )

              return 3;

       else

              return 0;

       return 0;

}

 

 

void CtictactoeView::winner( int who )//显示谁赢得比赛

{

       switch( who )

       {

       case 1:

              ::AfxMessageBox( "祝贺你胜利啦!" );

              break;

       case 2:

              ::AfxMessageBox( "电脑胜利,你要加油噢!" );

              break;

       case 3:

              ::AfxMessageBox( "平局!" );

       }

 

       initGame();

}

 

 

void CtictactoeView::initGame(void)//一局游戏的初始化

{

       int i , j;

       for( i = 0 ; i < 3 ; i++ )

              for( j = 0 ; j < 3 ; j++ )

                     myGraph[i][j] = 0;

       currX = -1;

       currY = -1;

       CRect mRect;

       mRect = CRect( 5 , 5 , 315 , 315 );

       InvalidateRect( mRect );    

       if( whosFirst == 1 )

       {

              whosFirst = 2;

              whosTurn = 2;

              computerPlay();

       }

       else

       {

              whosFirst = 1;

              whosTurn = 1;

       }

}

 

void CtictactoeView::OnNewgame()//开始新的游戏

{

       // TODO: 在此添加命令处理程序代码

       initGame();

}

你可能感兴趣的:(磨炼)