// chess.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "chess.h"
#include "math.h"
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
HBITMAP chess[2];
HDC hdc,mdc,bufdc;
HWND hWnd;
DWORD tPre,tNow;
int board[10][10];
bool ptab[10][10][192];
bool ctab[10][10][192];
int win[2][192];
int num[2];
bool turn,over;
int winner;
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
void MyPaint(HDC hdc);
void InitGame();
void ComTurn();
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable;
// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_CHESS, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CHESS));
// 主消息循环:
/* while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}*/
while(TRUE)
{
if (GetMessage(&msg,NULL,0,0))
{
if (msg.message!=WM_QUIT)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
MyPaint(hdc);
}
}
else
break;
}
return (int) msg.wParam;
}
//
// 函数: MyRegisterClass()
//
// 目的: 注册窗口类。
//
// 注释:
//
// 仅当希望
// 此代码与添加到 Windows 95 中的“RegisterClassEx”
// 函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要,
// 这样应用程序就可以获得关联的
// “格式正确的”小图标。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CHESS));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_CHESS);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// 函数: InitInstance(HINSTANCE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
HBITMAP tile,bmp;
int rowNum,colNum;
int i,x,y;
hInst = hInstance; // 将实例句柄存储在全局变量中
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
MoveWindow(hWnd,0,0,600,600,TRUE);
UpdateWindow(hWnd);
hdc=GetDC(hWnd);
mdc=CreateCompatibleDC(hdc);
bufdc=CreateCompatibleDC(hdc);
bmp=CreateCompatibleBitmap(hdc,450,450);
SelectObject(mdc,bmp);
tile=(HBITMAP)LoadImage(NULL,"tile.bmp",IMAGE_BITMAP,45,45,LR_LOADFROMFILE);
chess[0]=(HBITMAP)LoadImage(NULL,"chess0.bmp",IMAGE_BITMAP,38,38,LR_LOADFROMFILE);
chess[1]=(HBITMAP)LoadImage(NULL,"chess1.bmp",IMAGE_BITMAP,38,38,LR_LOADFROMFILE);
for (i=0;i<100;i++)
{
rowNum=i/10;
colNum=i%10;
x=colNum*45;
y=rowNum*45;
SelectObject(bufdc,tile);
BitBlt(mdc,x,y,45,45,bufdc,0,0,SRCCOPY);
}
//BitBlt(hdc,0,0,640,480,mdc,0,0,SRCCOPY);
InitGame();
MyPaint(hdc);
return TRUE;
}
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
int x,y,m,n,i;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps);
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
case VK_F1:
InitGame();
break;
}
case WM_LBUTTONDOWN:
if(!over)
if (turn)
{
x=LOWORD(lParam);
y=HIWORD(lParam);
if (x>10&&x<460&&y>10&&y<460)
{
m=(int)floor((double)((x-10)/45));
n=(int)floor((double)((y-10)/45));
if (board[m][n]==2)
{
board[m][n]=0;
num[0]++;
if (num[0]==50&&num[1]==50)
{
winner=2;
over=true;
}
else
for (i=0;i<192;i++)
{
if (ptab[m][n][i])
{
win[0][i]++;
ctab[m][n][i]=false;
win[1][i]=7;
if (win[0][i]==5)
{
winner=0;
over=true;
}
}
}
turn=false;
}
}
}
break;
case WM_DESTROY:
DeleteDC(mdc);
DeleteDC(bufdc);
DeleteObject(chess[0]);
DeleteObject(chess[1]);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
void InitGame()
{
int i,j,k;
int count=0;
over=false;
num[0]=num[1]=0;
//设定玩家与计算机在各个获胜组合中的棋子数
for (i=0;i<192;i++)
{
win[0][i]=0;
win[1][i]=0;
}
//初始化棋盘状态
for(i=0;i<10;i++)
for(j=0;j<10;j++)
board[i][j]=2;
//设定水平方向的获胜组合
for(i=0;i<10;i++)
for (j=0;j<6;j++)
{
for(k=0;k<5;k++)
{
ptab[i][j+k][count]=TRUE;
ctab[i][j+k][count]=TRUE;
}
count++;
}
//设定垂直方向的获胜组合
for(i=0;i<10;i++)
for (j=0;j<6;j++)
{
for(k=0;k<5;k++)
{
ptab[j+k][i][count]=TRUE;
ctab[j+k][i][count]=TRUE;
}
count++;
}
//设定正对角线方向的获胜组合
for(i=0;i<10;i++)
for (j=0;j<6;j++)
{
for(k=0;k<5;k++)
{
ptab[j+k][i+k][count]=TRUE;
ctab[j+k][i+k][count]=TRUE;
}
count++;
}
//设定反对角线方向的获胜组合
for(i=0;i<6;i++)
for (j=9;j>=4;j--)
{
for(k=0;k<5;k++)
{
ptab[j-k][i+k][count]=TRUE;
ctab[j-k][i+k][count]=TRUE;
}
count++;
}
//随机数决定由哪一方先下棋子
srand(GetTickCount());
if(rand()%2==0)
turn=true;
else
turn=false;
}
void ComTurn()
{
int grades[2][10][10];
int m,n,i,max=0;
int u,v;
for (m=0;m<10;m++)
for (n=0;n<10;n++)
{
grades[0][m][n]=0;
grades[1][m][n]=0;
if (board[m][n]==2)
{
for (i=0;i<192;i++)
{
//计算玩家在空格上的获胜分数
if (ptab[m][n][i]&&win[0][i]!=7)
{
switch(win[0][i])
{
case 0:
grades[0][m][n]+=1;
break;
case 1:
grades[0][m][n]+=200;
break;
case 2:
grades[0][m][n]+=400;
break;
case 3:
grades[0][m][n]+=2000;
break;
case 4:
grades[0][m][n]+=10000;
break;
}
}
//计算计算机在空棋格上的获胜分数
if (ctab[m][n][i]&&win[1][i]!=7)
{
switch(win[1][i])
{
case 0:
grades[1][m][n]+=1;
break;
case 1:
grades[1][m][n]+=220;
break;
case 2:
grades[1][m][n]+=420;
break;
case 3:
grades[1][m][n]+=2100;
break;
case 4:
grades[1][m][n]+=20000;
break;
}
}
}
if (max==0)
{
u=m;
v=n;
}
if (grades[0][m][n]>max)
{
max=grades[0][m][n];
u=m;
v=n;
}
else if (grades[0][m][n]==max)
{
if (grades[1][m][n]>grades[1][u][v])
{
u=m;
v=n;
}
}
if (grades[1][m][n]>max)
{
max=grades[1][m][n];
u=m;
v=n;
}
else if (grades[1][m][n]==max)
{
if (grades[0][m][n]>grades[0][u][v])
{
u=m;
v=n;
}
}
}
}
board[u][v]=1;//设定为计算机的棋子
num[1]++;
if (num[0]==50&&num[1]==50)
{
winner=2;
over=true;
}
else
for (i=0;i<192;i++)
{
if (ctab[u][v][i])
{
win[1][i]++;
ptab[u][v][i]=false;
win[0][i]=7;
if (win[1][i]==5)
{
winner=1;
over=true;
}
}
}
turn=true; //换由玩家下
}
void MyPaint(HDC hdc)
{
int m,n;
char *str;
if (over)
{
switch(winner)
{
case 0:
str="您赢了!";
break;
case 1:
str="计算机赢了!";
break;
case 2:
str="不分胜负!";
break;
}
TextOut(hdc,10,470,str,strlen(str));
}
else if (!turn)
{
str="计算机思考中...";
TextOut(hdc,10,470,str,strlen(str));
ComTurn();
}
else
{
str="该您下了...";
TextOut(hdc,10,470,str,strlen(str));
}
for (m=0;m<10;m++)
for (n=0;n<10;n++)
{
if (board[m][n]==0)
{
SelectObject(bufdc,chess[0]);
BitBlt(mdc,m*45+3,n*45+3,38,38,bufdc,0,0,SRCCOPY);
}
else if (board[m][n]==1)
{
SelectObject(bufdc,chess[1]);
BitBlt(mdc,m*45+3,n*45+3,38,38,bufdc,0,0,SRCCOPY);
}
else
{
SelectObject(bufdc,chess[1]);
BitBlt(mdc,m*45+3,n*45+3,38,38,bufdc,0,0,WHITENESS);
}
}
BitBlt(hdc,10,10,450,450,mdc,0,0,SRCCOPY);
tPre=GetTickCount();
}