您的位置:首页 > 其它

[游戏模版18] Win32 五子棋

2014-05-18 14:14 357 查看
>_<:Learning its AI logic.

>_<:resource

>_<:code:



#include <windows.h>
// C 运行时头文件
#include <stdlib.h>
#include <cstdio>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <time.h>
#include <string>
#include <cmath>

#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst;                                // 当前实例
TCHAR szTitle[MAX_LOADSTRING];                    // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名
HBITMAP cheers[2];
HDC hdc,mdc,bufdc;
HWND hWnd;
DWORD tPre,tNow;
int board[10][10];     //记录棋盘上格子的信息0,1,2分标表示玩家棋子、电脑棋子、空
bool ptab[10][10][192];    //玩家获胜表
bool ctab[10][10][192];    //电脑获胜表
int win[2][192];
int num[2];                //分别计算玩家和计算机下棋个数
bool turn,over;//turn 用来指示是有哪一方下棋,true玩家;false电脑;;over 指示棋局是否结束,ture结束
int begin;
int winner;    //指示当前棋局谁赢0表示玩家赢;1表示电脑赢;2表示平局

// 此代码模块中包含的函数的前向声明:
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){

MSG msg;
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow)){
return FALSE;
}
// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}

//  函数: MyRegisterClass()
//
//  目的: 注册窗口类。
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            = NULL;
wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName    = "Beautifulzzzz";
wcex.lpszClassName    = "Beautifulzzzz";
wcex.hIconSm        = NULL;

return RegisterClassEx(&wcex);
}

//
//   函数: InitInstance(HINSTANCE, int)
//
//   目的: 保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//        棋盘拼接以及调用InitGame()开始棋局
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){
HBITMAP tile,bmp;
int rowNum,colNum;
int i,x,y;

hInst = hInstance; // 将实例句柄存储在全局变量中

begin=9;
hWnd = CreateWindow("Beautifulzzzz","Beautifulzzzz", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

if (!hWnd)
{
return FALSE;
}

MoveWindow(hWnd,10,10,480,550,true);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

hdc=GetDC(hWnd);
mdc=CreateCompatibleDC(hdc);
bufdc=CreateCompatibleDC(hdc);

bmp=CreateCompatibleBitmap(hdc,450,450);
SelectObject(mdc,bmp);

tile=(HBITMAP)LoadImageA(NULL,"tile.bmp",IMAGE_BITMAP,45,45,LR_LOADFROMFILE);
cheers[0]=(HBITMAP)LoadImageA(NULL,"cheers[0].bmp",IMAGE_BITMAP,38,38,LR_LOADFROMFILE);
cheers[1]=(HBITMAP)LoadImageA(NULL,"cheers[1].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);
}

InitGame();//初始化

SetTimer(hWnd,1,200,NULL);
MyPaint(hdc);

begin=8;
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;
int x,y,m,n,i;

switch (message){
case WM_TIMER:
A:MyPaint(hdc);
break;
case WM_KEYDOWN://按下见消息
switch(wParam){
case VK_ESCAPE:
PostQuitMessage(0);
break;
case VK_F1:
InitGame();
break;
}
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]
==2)
{
board[m]
=0;
num[0]++;

if(num[0]==50 && num[1]==50)
{
winner=2;
over=true;
}
else for(i=0;i<192;i++)
{
if(ptab[m]
[i])
{
win[0][i]++;
ctab[m]
[i]=false;
win[1][i]=7;

if(win[0][i]==5)
{
winner=0;
over=true;
}
}
}
turn=false;//换由计算机下
}
}
}
break;
case WM_PAINT:
if(begin==8){
hdc = BeginPaint(hWnd, &ps);
goto A;// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps);}
break;
case WM_DESTROY:
DeleteDC(mdc);
DeleteDC(bufdc);
DeleteObject(cheers[0]);
DeleteObject(cheers[1]);

ReleaseDC(hWnd,hdc);

PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

//初始化棋盘
//1、设定棋盘初始状态及获胜表内容
//2、决定先下子的一方`
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++){//5个棋子1个获胜组合

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<6;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;
}

//计算机下棋函数
//1、计算获胜分数
//2、选择最佳位置进行下棋
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]
=0;
grades[1][m]
=0;

if(board[m]
==2){
for(i=0;i<192;i++){
//计算玩家在空棋格上的获胜分数
if(ptab[m]
[i] && win[0][i]!=7){
switch(win[0][i]){
case 0:
grades[0][m]
+=1;
break;
case 1:
grades[0][m]
+=200;
break;
case 2:
grades[0][m]
+=400;
break;
case 3:
grades[0][m]
+=2000;
break;
case 4:
grades[0][m]
+=10000;
break;
}
}

//计算计算机在空格上的获胜分数
if(ctab[m]
[i] && win[1][i]!=7){
switch(win[1][i]){
case 0:
grades[1][m]
+=1;
break;
case 1:
grades[1][m]
+=220;
break;
case 2:
grades[1][m]
+=420;
break;
case 3:
grades[1][m]
+=2100;
break;
case 4:
grades[1][m]
+=20000;
break;
}
}
}

if(max==0){
u=m;
v=n;
}

if(grades[0][m]
>max){
max=grades[0][m]
;
u=m;
v=n;
}else if(grades[0][m]
==max){
if(grades[1][m]
>grades[1][u][v]){
u=m;
v=n;
}
}

if(grades[1][m]
>max){
max=grades[1][m]
;
u=m;
v=n;
}else if(grades[1][m]
==max){
if(grades[0][m]
>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;
}

//MyPaint()
void MyPaint(HDC hdc){
int m,n;
char* str;
char* whitestr="                                                                                                 ";

if(over){
switch(winner){
case 0:
str="您赢了!按下[F1]键可重新进行游戏..";
break;
case 1:
str="计算机赢了!按下[F1]键可重新进行游戏..";
break;
case 2:
str="不分胜负!按下[F1]键可重新进行游戏..";
break;
}
TextOutA(hdc,10,470,whitestr,strlen(whitestr));
TextOutA(hdc,10,470,str,strlen(str));
}

else if(!turn){   //电脑下棋
TextOutA(hdc,10,470,whitestr,strlen(whitestr));
str="计算机思考中...";
TextOutA(hdc,10,470,str,strlen(str));
ComTurn();
}else{
TextOutA(hdc,10,470,whitestr,strlen(whitestr));
str="该您下了...";
TextOutA(hdc,10,470,str,strlen(str));
}

for(m=0;m<10;m++)
for(n=0;n<10;n++)
{
if(board[m]
==0)//贴上玩家棋子
{
SelectObject(bufdc,cheers[0]);
BitBlt(mdc,m*45+3,n*45+3,38,38,bufdc,0,0,SRCCOPY);
}
else if(board[m]
==1)//贴上计算机棋子
{
SelectObject(bufdc,cheers[1]);
BitBlt(mdc,m*45+3,n*45+3,38,38,bufdc,0,0,SRCCOPY);
}
else
{
SelectObject(bufdc,cheers[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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: