Game.cpp
资源名称:毕业论文--五子棋.zip [点击查看]
上传用户:fjjkzlh
上传日期:2010-04-06
资源大小:469k
文件大小:11k
源码类别:
棋牌游戏
开发平台:
Visual C++
- #include "StdAfx.h"
- #include "Table.h"
- #include "Game.h"
- #include "Messages.h"
- #include "Resource.h"
- //////////////////////////////////////////////////////////////////////////
- // CGame类的实现部分
- //////////////////////////////////////////////////////////////////////////
- CGame::~CGame()
- {
- }
- void CGame::Win( const STEP& stepSend )
- {
- }
- //////////////////////////////////////////////////////////////////////////
- // COneGame类的实现部分
- //////////////////////////////////////////////////////////////////////////
- COneGame::~COneGame()
- {
- }
- void COneGame::Init()
- {
- // 设置网络连接状态
- m_pTable->m_bConnected = FALSE;
- // 设置敌人姓名
- m_pTable->GetParent()->SetDlgItemText( IDC_ST_ENEMY, _T("计算机") );
- // 计算获胜组合情况
- int i, j, k, nCount = 0;
- for ( i = 0; i < 15; i++ )
- {
- for ( j = 0; j < 15; j++ )
- {
- for ( k = 0; k < 572; k++ )
- {
- m_Player[i][j][k] = false;
- m_Computer[i][j][k] = false;
- }
- }
- }
- for ( i = 0; i < 2; i++ )
- {
- for ( j = 0; j < 572; j++ )
- {
- m_Win[i][j] = 0;
- }
- }
- for ( i = 0; i < 15; i++ )
- {
- for ( j = 0; j < 11; j++ )
- {
- for ( k = 0; k < 5; k++ )
- {
- m_Player[j + k][i][nCount] = true;
- m_Computer[j + k][i][nCount] = true;
- }
- nCount++;
- }
- }
- for ( i = 0; i < 15; i++ )
- {
- for ( j = 0; j < 11; j++ )
- {
- for ( k = 0; k < 5; k++ )
- {
- m_Player[i][j + k][nCount] = true;
- m_Computer[i][j + k][nCount] = true;
- }
- nCount++;
- }
- }
- for ( i = 0; i < 11; i++ )
- {
- for ( j = 0; j < 11; j++ )
- {
- for ( k = 0; k < 5; k++ )
- {
- m_Player[j + k][i + k][nCount] = true;
- m_Computer[j + k][i + k][nCount] = true;
- }
- nCount++;
- }
- }
- for ( i = 0; i < 11; i++ )
- {
- for ( j = 14; j >= 4; j-- )
- {
- for ( k = 0; k < 5; k++ )
- {
- m_Player[j - k][i + k][nCount] = true;
- m_Computer[j - k][i + k][nCount] = true;
- }
- nCount++;
- }
- }
- if ( 1 == m_pTable->GetColor() )
- {
- // 如果玩家后走,则手动控制电脑占据天元
- m_pTable->SetData( 7, 7, 0 );
- PlaySound( MAKEINTRESOURCE( IDR_WAVE_PUT ), NULL, SND_RESOURCE | SND_SYNC );
- m_bStart = false;
- for ( i = 0; i < 572; i++ )
- {
- // 保存先前数据,做悔棋之用
- m_nOldWin[0][i] = m_Win[0][i];
- m_nOldWin[1][i] = m_Win[1][i];
- m_bOldPlayer[i] = m_Player[7][7][i];
- }
- for ( i = 0; i < 572; i++ )
- {
- // 修改计算机下子后,棋盘的变化状况
- if ( m_Computer[7][7][i] && m_Win[1][i] != -1 )
- {
- m_Win[1][i]++;
- }
- if ( m_Player[7][7][i] )
- {
- m_Player[7][7][i] = false;
- m_Win[0][i] = -1;
- }
- }
- }
- else
- {
- m_bStart = true;
- }
- }
- void COneGame::SendStep( const STEP& stepPut )
- {
- int bestx, besty, i, j, pi, pj, ptemp, ctemp, pscore = 10, cscore = -10000;
- int ctempTable[15][15], ptempTable[15][15];
- int m, n, temp1[20], temp2[20]; // 暂存第一步搜索的信息
- m_pTable->GetParent()->GetDlgItem( IDC_BTN_BACK )->EnableWindow( FALSE );
- // 保存先前数据,做悔棋之用
- for ( i = 0; i < 572; i++)
- {
- m_nOldWin[0][i] = m_Win[0][i];
- m_nOldWin[1][i] = m_Win[1][i];
- m_bOldPlayer[i] = m_Player[stepPut.x][stepPut.y][i];
- m_bOldComputer[i] = m_Computer[stepPut.x][stepPut.y][i];
- }
- // 修改玩家下子后棋盘状态的变化
- for ( i = 0; i < 572; i++ )
- {
- // 修改状态变化
- if ( m_Player[stepPut.x][stepPut.y][i] && m_Win[0][i] != -1 )
- m_Win[0][i]++;
- if ( m_Computer[stepPut.x][stepPut.y][i] )
- {
- m_Computer[stepPut.x][stepPut.y][i] = false;
- m_Win[1][i] = -1;
- }
- }
- if ( m_bStart )
- {
- // 手动确定第一步:天元或(8, 8)
- if ( -1 == m_pTable->m_data[7][7] )
- {
- bestx = 7;
- besty = 7;
- }
- else
- {
- bestx = 8;
- besty = 8;
- }
- m_bStart = false;
- }
- else
- {
- STEP step;
- // 寻找最佳位置
- GetTable( ctempTable, m_pTable->m_data );
- while ( SearchBlank( i, j, ctempTable ) )
- {
- n = 0;
- pscore = 10;
- GetTable( ptempTable, m_pTable->m_data );
- ctempTable[i][j] = 2; // 标记已被查找
- step.color = 1 - m_pTable->GetColor();
- step.x = i;
- step.y = j;
- // 给这个空位打分
- ctemp = GiveScore( step );
- for ( m = 0; m < 572; m++ )
- {
- // 暂时更改玩家信息
- if ( m_Player[i][j][m] )
- {
- temp1[n] = m;
- m_Player[i][j][m] = false;
- temp2[n] = m_Win[0][m];
- m_Win[0][m] = -1;
- n++;
- }
- }
- ptempTable[i][j] = 0;
- pi = i;
- pj = j;
- while ( SearchBlank( i, j, ptempTable ) )
- {
- ptempTable[i][j] = 2; // 标记已被查找
- step.color = m_pTable->GetColor();
- step.x = i;
- step.y = j;
- ptemp = GiveScore( step );
- if ( pscore > ptemp ) // 此时为玩家下子,运用极小极大法时应选取最小值
- pscore = ptemp;
- }
- for ( m = 0; m < n; m++ )
- {
- // 恢复玩家信息
- m_Player[pi][pj][temp1[m]] = true;
- m_Win[0][temp1[m]] = temp2[m];
- }
- if ( ctemp + pscore > cscore ) // 此时为计算机下子,运用极小极大法时应选取最最大值
- {
- cscore = ctemp + pscore;
- bestx = pi;
- besty = pj;
- }
- }
- }
- m_step.color = 1 - m_pTable->GetColor();
- m_step.x = bestx;
- m_step.y = besty;
- for ( i = 0; i < 572; i++ )
- {
- // 修改计算机下子后,棋盘的变化状况
- if ( m_Computer[bestx][besty][i] && m_Win[1][i] != -1 )
- m_Win[1][i]++;
- if ( m_Player[bestx][besty][i] )
- {
- m_Player[bestx][besty][i] = false;
- m_Win[0][i] = -1;
- }
- }
- m_pTable->GetParent()->GetDlgItem( IDC_BTN_BACK )->EnableWindow();
- // 由于是单人游戏,所以直接接收数据
- m_pTable->Receive();
- }
- void COneGame::ReceiveMsg( MSGSTRUCT *pMsg )
- {
- pMsg->color = m_step.color;
- pMsg->x = m_step.x;
- pMsg->y = m_step.y;
- pMsg->uMsg = MSG_PUTSTEP;
- }
- void COneGame::Back()
- {
- int i;
- // 单人游戏直接允许悔棋
- STEP step;
- // 悔第一步(电脑落子)
- step = *( m_StepList.begin() );
- m_StepList.pop_front();
- m_pTable->m_data[step.x][step.y] = -1;
- // 恢复原有胜负布局
- for ( i = 0; i < 572; i++ )
- {
- m_Win[0][i] = m_nOldWin[0][i];
- m_Win[1][i] = m_nOldWin[1][i];
- m_Player[step.x][step.y][i] = m_bOldPlayer[i];
- }
- // 悔第二步(玩家落子)
- step = *( m_StepList.begin() );
- m_StepList.pop_front();
- m_pTable->m_data[step.x][step.y] = -1;
- // 恢复原有胜负布局
- for ( i = 0; i < 572; i++ )
- {
- m_Computer[step.x][step.y][i] = m_bOldComputer[i];
- }
- m_pTable->Invalidate();
- // 考虑到程序的负荷,这时候就不允许悔棋了
- AfxGetMainWnd()->GetDlgItem( IDC_BTN_BACK )->EnableWindow( FALSE );
- }
- int COneGame::GiveScore( const STEP& stepPut )
- {
- int i, nScore = 0;
- for ( i = 0; i < 572; i++ )
- {
- if ( m_pTable->GetColor() == stepPut.color )
- {
- // 玩家下
- if ( m_Player[stepPut.x][stepPut.y][i] )
- {
- switch ( m_Win[0][i] )
- {
- case 1:
- nScore -= 5;
- break;
- case 2:
- nScore -= 50;
- break;
- case 3:
- nScore -= 500;
- break;
- case 4:
- nScore -= 5000;
- break;
- default:
- break;
- }
- }
- }
- else
- {
- // 计算机下
- if ( m_Computer[stepPut.x][stepPut.y][i] )
- {
- switch ( m_Win[1][i] )
- {
- case 1:
- nScore += 5;
- break;
- case 2:
- nScore += 50;
- break;
- case 3:
- nScore += 100;
- break;
- case 4:
- nScore += 10000;
- break;
- default:
- break;
- }
- }
- }
- }
- return nScore;
- }
- void COneGame::GetTable( int tempTable[][15], int nowTable[][15] )
- {
- int i, j;
- for ( i = 0; i < 15; i++ )
- {
- for ( j = 0; j < 15; j++ )
- {
- tempTable[i][j] = nowTable[i][j];
- }
- }
- }
- bool COneGame::SearchBlank( int &i, int &j, int nowTable[][15] )
- {
- int x, y;
- for ( x = 0; x < 15; x++ )
- {
- for ( y = 0; y < 15; y++ )
- {
- if ( nowTable[x][y] == -1 && nowTable[x][y] != 2 )
- {
- i = x;
- j = y;
- return true;
- }
- }
- }
- return false;
- }
- //////////////////////////////////////////////////////////////////////////
- // CTwoGame类的实现部分
- //////////////////////////////////////////////////////////////////////////
- CTwoGame::~CTwoGame()
- {
- }
- //////////////////////////////////////////////////////////////////////////
- void CTwoGame::Init()
- {
- }
- void CTwoGame::Win( const STEP& stepSend )
- {
- SendStep( stepSend );
- }
- void CTwoGame::SendStep( const STEP& stepPut )
- {
- MSGSTRUCT msg;
- msg.uMsg = MSG_PUTSTEP;
- msg.color = stepPut.color;
- msg.x = stepPut.x;
- msg.y = stepPut.y;
- m_pTable->m_conn.Send( (LPCVOID)&msg, sizeof( MSGSTRUCT ) );
- }
- void CTwoGame::ReceiveMsg( MSGSTRUCT *pMsg )
- {
- int nRet = m_pTable->m_conn.Receive( pMsg, sizeof( MSGSTRUCT ) );
- if ( SOCKET_ERROR == nRet )
- {
- AfxGetMainWnd()->MessageBox( _T("接收数据时发生错误,请检查您的网络连接。"), _T("错误"), MB_ICONSTOP );
- }
- }
- void CTwoGame::Back()
- {
- CDialog *pDlg = (CDialog *)AfxGetMainWnd();
- // 使按钮失效
- pDlg->GetDlgItem( IDC_BTN_BACK )->EnableWindow( FALSE );
- pDlg->GetDlgItem( IDC_BTN_HQ )->EnableWindow( FALSE );
- pDlg->GetDlgItem( IDC_BTN_LOST )->EnableWindow( FALSE );
- // 设置等待标志
- m_pTable->SetWait( TRUE );
- MSGSTRUCT msg;
- msg.uMsg = MSG_BACK;
- m_pTable->m_conn.Send( (LPCVOID)&msg, sizeof( MSGSTRUCT ) );
- }