⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 table.cpp

📁 五子棋游戏 用MFC编的程序 比较简单的
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "Five.h"
#include "Table.h"
#include "Messages.h"
#include "Resource.h"

//////////////////////////////////////////////////////////////////////////
// 构造函数,初始化棋盘数据以及图像数据
//////////////////////////////////////////////////////////////////////////
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;
}
//////////////////////////////////////////////////////////////////////////
// 发送再玩一次请求
//////////////////////////////////////////////////////////////////////////
void CTable::PlayAgain()
{
    MSGSTRUCT msg;
    msg.uMsg = MSG_PLAYAGAIN;
    m_conn.Send( (LPCVOID)&msg, sizeof( MSGSTRUCT ) );
}
//////////////////////////////////////////////////////////////////////////
// 发送和棋请求
//////////////////////////////////////////////////////////////////////////
void CTable::DrawGame()
{
    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 );

    // 设置等待标志
    SetWait( TRUE );

    MSGSTRUCT msg;
    msg.uMsg = MSG_DRAW;
    m_conn.Send( (LPCVOID)&msg, sizeof( MSGSTRUCT ) );
}
//////////////////////////////////////////////////////////////////////////
// 设置游戏模式
//////////////////////////////////////////////////////////////////////////
void CTable::SetGameMode( int nGameMode )
{
    if ( 1 == nGameMode )
        m_pGame = new COneGame( this );
    else
        m_pGame = new CTwoGame( this );
    m_pGame->Init();
}
//////////////////////////////////////////////////////////////////////////
// 悔棋
//////////////////////////////////////////////////////////////////////////
void CTable::Back()
{
    m_pGame->Back();
}
//////////////////////////////////////////////////////////////////////////
// 处理对方落子后的工作
//////////////////////////////////////////////////////////////////////////
void CTable::Over()
{
    // 判断对方是否胜利
    if ( Win( 1 - m_color ) )
    {
        CFiveApp *pApp = (CFiveApp *)AfxGetApp();
        pApp->m_nLost++;
        CDialog *pDlg = (CDialog *)GetParent();
        PlaySound( MAKEINTRESOURCE( IDR_WAVE_LOST ), NULL, SND_RESOURCE | SND_SYNC );
        pDlg->MessageBox( _T("您输了,不过不要灰心,失败乃成功之母哦!"), _T("失败"), MB_ICONINFORMATION );
        pDlg->GetDlgItem( IDC_BTN_HQ )->EnableWindow( FALSE );
        pDlg->GetDlgItem( IDC_BTN_BACK )->EnableWindow( FALSE );
        pDlg->GetDlgItem( IDC_BTN_LOST )->EnableWindow( FALSE );
        // 如果是网络对战,则生效“重玩”
        if ( m_bConnected )
        {
            pDlg->GetMenu()->EnableMenuItem( ID_MENU_PLAYAGAIN, MF_ENABLED | MF_BYCOMMAND );
        }
        return;
    }
    m_bWait = FALSE;
}
//////////////////////////////////////////////////////////////////////////
// 设置菜单状态(主要为网络对战准备)
//////////////////////////////////////////////////////////////////////////
void CTable::SetMenuState( BOOL bEnable )
{
    UINT uEnable, uDisable;
    if ( bEnable )
    {
        uEnable = MF_ENABLED;
        uDisable = MF_GRAYED | MF_DISABLED;
    }
    else
    {
        uEnable = MF_GRAYED | MF_DISABLED;
        uDisable = MF_ENABLED;
    }
    CMenu *pMenu = GetParent()->GetMenu();
    pMenu->GetSubMenu( 0 )->EnableMenuItem( 0, uEnable | MF_BYPOSITION );
    pMenu->EnableMenuItem( ID_MENU_SERVER, uEnable );
    pMenu->EnableMenuItem( ID_MENU_CLIENT, uEnable );
    pMenu->EnableMenuItem( ID_MENU_LEAVE, uDisable );
    pMenu->EnableMenuItem( ID_MENU_PLAYAGAIN, uEnable );
}
//////////////////////////////////////////////////////////////////////////
// 接受连接
//////////////////////////////////////////////////////////////////////////
void CTable::Accept( int nGameMode )
{
    if ( 2 == nGameMode )
    {
        m_sock.Accept( m_conn );
    }
    m_bConnected = TRUE;
	SetColor( 0 );
    Clear( FALSE );
    SetGameMode( nGameMode );
}
//////////////////////////////////////////////////////////////////////////
// 主动连接
//////////////////////////////////////////////////////////////////////////
void CTable::Connect( int nGameMode )
{
    SetColor( 1 );
    Clear( TRUE );
    SetGameMode( nGameMode );
}
//////////////////////////////////////////////////////////////////////////
// 发送聊天消息
//////////////////////////////////////////////////////////////////////////
void CTable::Chat( LPCTSTR lpszMsg )
{
    MSGSTRUCT msg;
    msg.uMsg = MSG_CHAT;
    lstrcpy( msg.szMsg, lpszMsg );

    m_conn.Send( (LPCVOID)&msg, sizeof( MSGSTRUCT ) );
}
//////////////////////////////////////////////////////////////////////////
// 发送认输消息
//////////////////////////////////////////////////////////////////////////
void CTable::GiveUp()
{
    CFiveApp *pApp = (CFiveApp *)AfxGetApp();
    pApp->m_nLost++;
    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 );
    // 修改等待状态
    SetWait( TRUE );
    // 生效菜单项

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -