// JingZiQiView.cpp : implementation of the CJingZiQiView class
//
#include "stdafx.h"
#include "JingZiQi.h"
#include "JingZiQiDoc.h"
#include "JingZiQiView.h"
#include "MainFrm.h"
#define TCOLOR RGB( 0, 248, 0 ) //文字颜色1:用于显示游戏状态和提示信息
#define TCOLOR2 RGB( 255, 255, 255 ) //文字颜色2:用于显示游戏结果
#define BCOLOR RGB( 80, 64, 79 ) //显示游戏状态区域的颜色
#define BGROUND RGB( 209, 146, 34 ) //背景颜色
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CJingZiQiView
IMPLEMENT_DYNCREATE( CJingZiQiView, CView )
BEGIN_MESSAGE_MAP( CJingZiQiView, CView )
//{{AFX_MSG_MAP(CJingZiQiView)
ON_WM_SETCURSOR( )
ON_WM_LBUTTONUP( )
ON_COMMAND( ID_Start, OnStart )
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CJingZiQiView construction/destruction
CJingZiQiView::CJingZiQiView( )
{
CurBlack = AfxGetApp()->LoadCursor( IDC_CURSOR1 ); //加载光标
m_bmRed.LoadBitmap( IDB_BITMAP2 ); //加载红方(计算机)棋子位图
m_bmBlack.LoadBitmap( IDB_BITMAP1 ); //加载黑方(人)棋子位图
for( int i=0; i<3; i++ )
{
for( int j=0; j<3; j++ )
{
QP[i][j] = 0; pre_qp[i][j] = 0;
}
}
man_turn = 1; cmptfirst = false;
Level = 2; over = 0;
}
CJingZiQiView::~CJingZiQiView()
{
}
BOOL CJingZiQiView::PreCreateWindow(CREATESTRUCT& cs)
{
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CJingZiQiView drawing
void CJingZiQiView::OnDraw( CDC* pDC )
{
CJingZiQiDoc* pDoc = GetDocument( );
ASSERT_VALID( pDoc );
//画背景
CBrush mybrush; mybrush.CreateSolidBrush( BGROUND );
CRect myrect( 0, 0, 1200, 800 ); //所画区域大大超出了客户区区域
pDC->FillRect( myrect, &mybrush );
mybrush.DeleteObject( );
//注意:绘制显示游戏状态的区域是在ShowState( )函数中实现的
//画棋盘
CPen *oldpen, mypen; int i, j;
mypen.CreatePen( PS_SOLID, 1, RGB(255,255,255) ); //白色画笔画棋盘
oldpen = pDC->SelectObject( &mypen );
for( i=0;i<4;i++ ) //画四根横线和竖线
{
pDC->MoveTo( 60, 60+i*60 );
pDC->LineTo( 240, 60+i*60 ); //画横线
pDC->MoveTo( 60+i*60, 60 );
pDC->LineTo( 60+60*i, 240 ); //画竖线
}
pDC->SelectObject( oldpen );
//画棋子
CDC DC;
if( DC.CreateCompatibleDC( pDC ) == FALSE )
AfxMessageBox( "Fail to create DC!" );
for( i=0; i<3; i++ )
{
for( j=0; j<3; j++ )
{
if( QP[i][j]==1 )
{
DC.SelectObject( m_bmBlack );
pDC->BitBlt( 64+i*60, 64+j*60, 60,60, &DC, 0, 0, SRCCOPY );
}
else if( QP[i][j]==-1 )
{
DC.SelectObject( m_bmRed );
pDC->BitBlt( 64+i*60, 64+j*60, 60, 60, &DC, 0, 0, SRCCOPY );
}
}
}
ShowState( );
}
void CJingZiQiView::ShowState( ) //显示当前游戏状态
{
CDC *pDC = GetDC( );
CRect CltRect, rect;
GetClientRect( CltRect );
rect.CopyRect( CltRect );
rect.left += 300; //空出300个像素的宽度用于显示棋盘
//画背景
CBrush mybrush; mybrush.CreateSolidBrush( BCOLOR );
pDC->FillRect( rect, &mybrush );
//定义显示man_turn、computerfirst、Level状态信息和输赢的区域
CRect ModeRect( rect.left+5, rect.top+50, rect.right, rect.top+80 ); //显示游戏模式
CRect LevelRect( rect.left+5, rect.top+90, rect.right, rect.top+120 ); //显示游戏级别
CRect FstRect( rect.left+5, rect.top+130, rect.right, rect.top+160 ); //显示人或电脑先下
CRect TurnRect( rect.left+5, rect.top+170, rect.right, rect.top+200 ); //显示轮到电脑或人下
CRect ReltRect( rect.left+5, rect.top+210, rect.right, rect.top+240 ); //显示游戏结果
pDC->SetTextColor( TCOLOR );
pDC->SetBkMode( TRANSPARENT );
pDC->DrawText( "模式: 人机对弈", ModeRect, 0 );
if( Level==1 ) pDC->DrawText("难度: 易", LevelRect, 0 );
else pDC->DrawText( "难度: 难", LevelRect, 0 );
if( cmptfirst ) pDC->DrawText( "先下: 计算机", FstRect, 0 );
else pDC->DrawText( "先下: 人", FstRect, 0 );
if( man_turn&&!over ) pDC->DrawText( "当前: 该你下了!", TurnRect, 0 );
else if( !over ) pDC->DrawText( "当前: 计算机下,稍等...", TurnRect, 0 );
else pDC->DrawText( "当前: 游戏结束!", TurnRect, 0 );
switch( over )
{
case 0: if( !over ) pDC->DrawText( "结果: 正在进行...", ReltRect+CPoint(1,1), 0 ); break;
case 1: pDC->SetTextColor( TCOLOR2 ); pDC->DrawText( "结果: 你输了-_- 加油!", ReltRect, 0 ); break;
case 2: pDC->SetTextColor( TCOLOR2 ); pDC->DrawText( "结果: 你赢了,真棒!^_^", ReltRect, 0 ); break;
case 3: pDC->SetTextColor( TCOLOR2 ); pDC->DrawText( "结果: 打成平手!", ReltRect, 0 ); break;
default: break;
}
}
/////////////////////////////////////////////////////////////////////////////
// CJingZiQiView printing
BOOL CJingZiQiView::OnPreparePrinting( CPrintInfo* pInfo )
{
return DoPreparePrinting( pInfo );
}
void CJingZiQiView::OnBeginPrinting( CDC* /*pDC*/, CPrintInfo* /*pInfo*/ )
{
}
void CJingZiQiView::OnEndPrinting( CDC* /*pDC*/, CPrintInfo* /*pInfo*/ )
{
}
/////////////////////////////////////////////////////////////////////////////
// CJingZiQiView diagnostics
#ifdef _DEBUG
void CJingZiQiView::AssertValid( ) const
{
CView::AssertValid( );
}
void CJingZiQiView::Dump( CDumpContext& dc ) const
{
CView::Dump( dc );
}
CJingZiQiDoc* CJingZiQiView::GetDocument( ) // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf( RUNTIME_CLASS(CJingZiQiDoc)) );
return (CJingZiQiDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CJingZiQiView message handlers
BOOL CJingZiQiView::OnSetCursor( CWnd* pWnd, UINT nHitTest, UINT message )
{
if( nHitTest==HTCLIENT ) //光标在客户区
{
if( man_turn )
{
SetCursor( CurBlack ); return 1;
}
}
return CView::OnSetCursor(pWnd, nHitTest, message);
}
//鼠标左键按下后再松开 : 计算机走棋并显示游戏状态和结果
//注意:鼠标左键有按下和松开两个消息,应该是在松开鼠标左键时光标所处的位置下棋子
void CJingZiQiView::OnLButtonUp( UINT nFlags, CPoint point )
{
int x, y, px, py; int j, k; //px和py取值为0~2,表示光标位置对应的数组元素在数组中的行和列
x = point.x; y = point.y;
CDC *pDC = GetDC( ); CDC DC;
if( DC.CreateCompatibleDC(pDC)==FALSE )
MessageBox( "fail to create DC!" );
if( !over ) //游戏没有结束
{
if( x>60 && x<240 && y>60 && y<240 )
{
px = (x-60)/60; py = (y-60)/60;
if( man_turn && QP[px][py]==0 ) //轮到人下,且该位置可以下棋
{
for( k=0; k<3; k++ ) //备份棋盘当前状态
{
for( j=0; j<3; j++ )
pre_qp[k][j] = QP[k][j];
}
//人在(px,py)处下黑棋子
DC.SelectObject( m_bmBlack );
pDC->BitBlt( 64+60*px, 64+60*py, 60, 60, &DC, 0, 0, SRCCOPY );
QP[px][py] = 1;
man_turn = 0;
if( !result( ) ) //游戏还没结束
{
computerdown( ); result( ); //计算机走棋并统计结果
}
}
}
}
CView::OnLButtonUp( nFlags, point );
}
void CJingZiQiView::computerdown( ) //计算机走棋(易)
{
CDC *pDC=GetDC( );
CDC DC;
if( DC.CreateCompatibleDC(pDC) == FALSE )
MessageBox( "fail to create DC!" );
int i, j, k1, k2, temp1, temp2;
int flag = 1; //flag为1表示没有地方可以下棋子了,为0表示至少还有一个位置可以下棋
for( i=0; i<3; i++ )
{
for( j=0; j<3; j++ )
{
if( QP[i][j]==0 )
flag = 0;
}
}
if( flag==1 ) return; //每地方可供计算机下棋了,则游戏结束,游戏结果为上一步人走棋后的结果
//几个特殊布局的处理
if( QP[0][0]==0 && QP[0][1]==0 && QP[0][2]==0 && //第1种特殊布局
QP[1][0]==0 && QP[1][1]==1 && QP[1][2]==0 &&
QP[2][0]==0 && QP[2][1]==0 && QP[2][2]==0 )
{
QP[0][0] = -1;
DC.SelectObject( m_bmRed );
pDC->BitBlt( 64, 64, 60, 60, &DC, 0, 0, SRCCOPY );