//
//TCHAR.h
/
#ifndef __TRECT
#define __TRECT
#include <windef.h>
struct TRECT
:public RECT
{
BOOL bRedOrBlack;
};
#endif
//
//TWindow.h
/
#pragma once
#include <windows.h>
#include <tchar.h>
#include "TRECT.h"
#define BLACK FALSE
#define RED TRUE
class TWindow
{
public:
TWindow(PCTSTR pszClassName,PCTSTR pszWindowName,HINSTANCE hInstance,int nCmdShow);
virtual ~TWindow(void);
static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
ATOM CreateWindowClass(void);
void CreateMainWindow(void);
static TWindow* CreateNewWindow(PCTSTR pszClassName, PCTSTR pszWindowName, HINSTANCE hInstance, int nCmdShow);
BOOL UpdateWindow(void);
BOOL ShowWindow(void);
void DrawFork(const TRECT& rect, HDC hDC);
void DrawRound(const TRECT& rect, HDC hDC);
int GetWinner(void);
ULONG GetEmptyRect(void);
private:
static TWindow* m_p;
HWND m_hWnd;
int m_nCmdShow;
HINSTANCE m_hInstance;
TCHAR m_szClassName[128];
TCHAR m_szWindowName[128];
TRECT m_Rects[9];
DWORD m_dwCount;
int m_nWinner;
};
//
//TWindow.cpp
/
#include "TWindow.h"
#include <stdlib.h>
TWindow* TWindow::m_p = NULL;
TWindow::TWindow(PCTSTR pszClassName,PCTSTR pszWindowName,HINSTANCE hInstance,int nCmdShow)
:m_nCmdShow(nCmdShow),
m_hInstance(hInstance),
m_dwCount(0),
m_nWinner(-2)
{
lstrcpyn(m_szClassName,pszClassName,128);
lstrcpyn(m_szWindowName,pszWindowName,128);
}
TWindow::~TWindow(void)
{
}
LRESULT CALLBACK TWindow::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static DWORD cxClient=0,cyClient=0;
static DWORD dwYCubicle=0,dwXCubicle=0;
static HPEN hPen=NULL;
static BOOL bRedOrBlack=BLACK;
PAINTSTRUCT ps;
HDC hDC=NULL;
switch (msg)
{
case WM_CREATE:
ZeroMemory(m_p->m_Rects,sizeof(TRECT)*9);
for (int i=0;i<9;i++)
{
m_p->m_Rects[i].bRedOrBlack=-1;
}
hPen=CreatePen(PS_SOLID,2,RGB(255,100,0));
break;
case WM_SIZE:
{
ULONG x=0,y=0;
TRECT* pr=m_p->m_Rects;
cyClient=HIWORD(lParam);
cxClient=LOWORD(lParam);
dwYCubicle=cyClient/3;
dwXCubicle=cxClient/3;
for (ULONG i=0;i<3;i++)
{
x=0;
for (ULONG j=0;j<3;j++)
{
m_p->m_Rects[i*3+j].left=x;
m_p->m_Rects[i*3+j].right=x+dwXCubicle;
m_p->m_Rects[i*3+j].top=y;
m_p->m_Rects[i*3+j].bottom=y+dwYCubicle;
x+=dwXCubicle;
}
y+=dwYCubicle;
}
}
break;
case WM_PAINT:
hDC=BeginPaint(hWnd,&ps);
hPen=(HPEN)SelectObject(hDC,hPen);
for (ULONG i=dwYCubicle;i<cyClient;i+=dwYCubicle)
{
MoveToEx(hDC,0,i,NULL);
LineTo(hDC,cxClient,i);
}
for (ULONG i=dwXCubicle;i<cxClient;i+=dwXCubicle)
{
MoveToEx(hDC,i,0,NULL);
LineTo(hDC,i,cyClient);
}
for (int i=0;i<9;i++)
{
switch(m_p->m_Rects[i].bRedOrBlack)
{
case RED:
m_p->DrawRound(m_p->m_Rects[i],hDC);
break;
case BLACK:
m_p->DrawFork(m_p->m_Rects[i],hDC);
break;
}
}
hPen=(HPEN)SelectObject(hDC,hPen);
EndPaint(hWnd,&ps);
break;
case WM_LBUTTONDOWN:
{
BEGIN:
if (m_p->m_dwCount==9)
{
if (m_p->m_nWinner==-2)
{
TCHAR szWinner[56]=TEXT("");
swprintf_s(szWinner,56,L"No Winner");
MessageBox(NULL,szWinner,TEXT("NO WINNNER"),MB_OK);
goto END;
}
else
goto PRINT_WINNER;
}
int dw=-2;
TCHAR szWinner[56]=TEXT("");
hDC=GetDC(hWnd);
POINT point;
point.x=LOWORD(lParam);
point.y=HIWORD(lParam);
for (ULONG i=0;i<9;i++)
{
if (PtInRect(m_p->m_Rects+i,point))
{
if (-1==m_p->m_Rects[i].bRedOrBlack)
{
m_p->DrawRound(m_p->m_Rects[i],hDC);
m_p->m_Rects[i].bRedOrBlack=RED;
break;
}
}
}
if (m_p->m_nWinner!=-2)
{
dw=m_p->m_nWinner;
}
else
dw=m_p->GetWinner();
if (dw==-2&&m_p->m_dwCount==9)
{
goto BEGIN;
}
if (dw!=-2)
{
if (RED==dw)
{
swprintf_s(szWinner,56,L"Winner is %s",L"player");
MessageBox(NULL,szWinner,TEXT("WIN!!!"),MB_OK);
break;
}
if (BLACK==dw)
{
swprintf_s(szWinner,56,L"Winner is %s",L"computer");
MessageBox(NULL,szWinner,TEXT("FAILED!!!"),MB_OK);
break;
}
goto END;
}
ULONG ul=m_p->GetEmptyRect();
if (ul==9)
{
goto END;
}
m_p->m_Rects[ul].bRedOrBlack=BLACK;
m_p->DrawFork(m_p->m_Rects[ul],hDC);
PRINT_WINNER:
if (m_p->m_nWinner!=-2)
{
dw=m_p->m_nWinner;
}
else
dw=m_p->GetWinner();
if (dw!=-2)
{
if (RED==dw)
{
swprintf_s(szWinner,56,L"Winner is %s",L"player");
MessageBox(NULL,szWinner,TEXT("WIN!!!"),MB_OK);
break;
}
if (BLACK==dw)
{
swprintf_s(szWinner,56,L"Winner is %s",L"computer");
MessageBox(NULL,szWinner,TEXT("FAILED!!!"),MB_OK);
break;
}
}
END:
ReleaseDC(hWnd,hDC);
break;
}
case WM_RBUTTONDOWN:
for (int i=0;i<9;i++)
{
m_p->m_Rects[i].bRedOrBlack=-1;
}
m_p->m_nWinner=-2;
m_p->m_dwCount=0;
::InvalidateRect(hWnd,NULL,TRUE);
::UpdateWindow(hWnd);
break;
case WM_DESTROY:
DeleteObject(hPen);
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd,msg,wParam,lParam);
}
ATOM TWindow::CreateWindowClass(void)
{
WNDCLASS wc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wc.hInstance=m_hInstance;
wc.lpfnWndProc=TWindow::WndProc;
wc.lpszClassName=m_szClassName;
wc.lpszMenuName=NULL;
wc.style=CS_VREDRAW|CS_HREDRAW;
return RegisterClass(&wc);
}
void TWindow::CreateMainWindow(void)
{
m_hWnd=CreateWindow(m_szClassName,
m_szWindowName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
m_hInstance,
NULL);
}
TWindow* TWindow::CreateNewWindow(PCTSTR pszClassName, PCTSTR pszWindowName, HINSTANCE hInstance, int nCmdShow)
{
if (m_p!=NULL)
{
return m_p;
}
m_p=new TWindow(pszClassName,pszWindowName,hInstance,nCmdShow);
m_p->CreateWindowClass();
m_p->CreateMainWindow();
m_p->UpdateWindow();
m_p->ShowWindow();
return m_p;
}
BOOL TWindow::UpdateWindow(void)
{
return ::UpdateWindow(m_hWnd);
}
BOOL TWindow::ShowWindow(void)
{
return ::ShowWindow(m_hWnd,m_nCmdShow);
}
void TWindow::DrawFork(const TRECT& rect, HDC hDC)
{
HPEN hPen=(HPEN)CreatePen(PS_SOLID,2,RGB(0,0,0));
hPen=(HPEN)SelectObject(hDC,hPen);
m_dwCount++;
MoveToEx(hDC,rect.left+20,rect.top+20,NULL);
LineTo(hDC,rect.right-20,rect.bottom-20);
MoveToEx(hDC,rect.right-20,rect.top+20,NULL);
LineTo(hDC,rect.left+20,rect.bottom-20);
SelectObject(hDC,hPen);
}
void TWindow::DrawRound(const TRECT& rect, HDC hDC)
{
HPEN hPen=(HPEN)CreatePen(PS_SOLID,2,RGB(255,0,0));
hPen=(HPEN)SelectObject(hDC,hPen);
m_dwCount++;
::Ellipse(hDC,rect.left+20,rect.top+20,rect.right-20,rect.bottom-20);
SelectObject(hDC,hPen);
}
int TWindow::GetWinner(void)
{
for (ULONG i=0;i<=6;i+=3)
{
if (m_Rects[i].bRedOrBlack==m_Rects[i+1].bRedOrBlack&&
m_Rects[i+1].bRedOrBlack==m_Rects[i+2].bRedOrBlack&&
-1!=m_Rects[i].bRedOrBlack)
{
m_nWinner=m_Rects[i].bRedOrBlack;
return m_Rects[i].bRedOrBlack;
}
}
for (ULONG i=0;i<3;i++)
{
if (m_Rects[i].bRedOrBlack==m_Rects[i+3].bRedOrBlack&&
m_Rects[i+3].bRedOrBlack==m_Rects[i+6].bRedOrBlack&&
-1!=m_Rects[i].bRedOrBlack)
{
m_nWinner=m_Rects[i].bRedOrBlack;
return m_Rects[i].bRedOrBlack;
}
}
if (m_Rects[0].bRedOrBlack==m_Rects[4].bRedOrBlack&&
m_Rects[4].bRedOrBlack==m_Rects[8].bRedOrBlack&&
-1!=m_Rects[0].bRedOrBlack)
{
m_nWinner=m_Rects[0].bRedOrBlack;
return m_Rects[0].bRedOrBlack;
}
if (m_Rects[2].bRedOrBlack==m_Rects[4].bRedOrBlack&&
m_Rects[4].bRedOrBlack==m_Rects[6].bRedOrBlack&&
-1!=m_Rects[2].bRedOrBlack)
{
m_nWinner=m_Rects[2].bRedOrBlack;
return m_Rects[2].bRedOrBlack;
}
return -2;
}
ULONG TWindow::GetEmptyRect(void)
{
ULONG iRetVal=0xFFFFFFFF;
for (ULONG i=0;i<=6;i+=3)
{
if (m_Rects[i].bRedOrBlack==m_Rects[i+2].bRedOrBlack&&
-1==m_Rects[i+1].bRedOrBlack&&
-1!=m_Rects[i].bRedOrBlack)
{
if (BLACK==m_Rects[i+2].bRedOrBlack)
{
return i+1;
}
iRetVal=i+1;
}
if ((m_Rects[i].bRedOrBlack==m_Rects[i+1].bRedOrBlack||
m_Rects[i+1].bRedOrBlack==m_Rects[i+2].bRedOrBlack)&&-1!=m_Rects[i+1].bRedOrBlack)
{
if (BLACK==m_Rects[i+1].bRedOrBlack)
{
if (m_Rects[i].bRedOrBlack==-1)
{
return i;
}
if (m_Rects[i+2].bRedOrBlack==-1)
{
return i+2;
}
}
if (m_Rects[i].bRedOrBlack==-1)
{
iRetVal=i;
}
if (m_Rects[i+2].bRedOrBlack==-1)
{
iRetVal=i+2;
}
}
}
for (ULONG i=0;i<3;i++)
{
if (m_Rects[i].bRedOrBlack==m_Rects[i+6].bRedOrBlack&&
-1==m_Rects[i+3].bRedOrBlack&&
-1!=m_Rects[i].bRedOrBlack)
{
if (BLACK==m_Rects[i].bRedOrBlack)
{
return i+3;
}
iRetVal =i+3;
}
if ((m_Rects[i].bRedOrBlack==m_Rects[i+3].bRedOrBlack||
m_Rects[i+3].bRedOrBlack==m_Rects[i+6].bRedOrBlack)&&-1!=m_Rects[i+3].bRedOrBlack)
{
if (BLACK==m_Rects[i+3].bRedOrBlack)
{
if (m_Rects[i].bRedOrBlack==-1)
{
return i;
}
if (m_Rects[i+6].bRedOrBlack==-1)
{
return i+6;
}
}
if (m_Rects[i].bRedOrBlack==-1)
{
iRetVal=i;
}
if (m_Rects[i+6].bRedOrBlack==-1)
{
iRetVal=i+6;
}
}
}
if (m_Rects[0].bRedOrBlack==m_Rects[8].bRedOrBlack&&
-1==m_Rects[4].bRedOrBlack&&
-1!=m_Rects[0].bRedOrBlack)
{
if (BLACK==m_Rects[0].bRedOrBlack)
{
return 4;
}
iRetVal=4;
}
if ((m_Rects[0].bRedOrBlack==m_Rects[4].bRedOrBlack||
m_Rects[4].bRedOrBlack==m_Rects[8].bRedOrBlack)&&-1!=m_Rects[4].bRedOrBlack)
{
if (BLACK==m_Rects[4].bRedOrBlack)
{
if (m_Rects[0].bRedOrBlack==-1)
{
return 0;
}
if (m_Rects[8].bRedOrBlack==-1)
{
return 8;
}
}
if (m_Rects[0].bRedOrBlack==-1)
{
iRetVal=0;
}
if (m_Rects[8].bRedOrBlack==-1)
{
iRetVal=8;
}
}
if (m_Rects[2].bRedOrBlack==m_Rects[6].bRedOrBlack&&
-1==m_Rects[4].bRedOrBlack&&
-1!=m_Rects[2].bRedOrBlack)
{
if (BLACK==m_Rects[2].bRedOrBlack)
{
return 4;
}
iRetVal=4;
}
if ((m_Rects[2].bRedOrBlack==m_Rects[4].bRedOrBlack||
m_Rects[4].bRedOrBlack==m_Rects[6].bRedOrBlack)&&-1!=m_Rects[4].bRedOrBlack)
{
if (BLACK==m_Rects[4].bRedOrBlack)
{
if (m_Rects[2].bRedOrBlack==-1)
{
return 2;
}
if (m_Rects[6].bRedOrBlack==-1)
{
return 6;
}
}
if (m_Rects[2].bRedOrBlack==-1)
{
iRetVal=2;
}
if (m_Rects[6].bRedOrBlack==-1)
{
iRetVal=6;
}
}
if (iRetVal!=0xFFFFFFFF)
{
return iRetVal;
}
if (m_dwCount==9)
{
return 9;
}
while(TRUE)
{
DWORD dw=(DWORD)rand()%9;
if (-1==m_Rects[dw].bRedOrBlack)
{
return dw;
}
}
return 0;
}
///
//main.h
//
#include "TWindow.h"
int APIENTRY _tWinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPWSTR lpCmdLine, __in int nShowCmd )
{
TWindow* p=TWindow::CreateNewWindow(TEXT("MainWndClass"),TEXT("Main Window"),hInstance,nShowCmd);
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
delete p;
return 0;
}