C++如何用栈实现五子棋的悔棋功能?以下是我的代码,但是实现不了悔棋,哪位高手能帮帮我修改一下,谢谢!

伯符 2012-05-16 04:04:34
//#include <windows.h>
#include "StdAfx.h"
#include <stdio.h>
#include <stdlib.h>
#define MAX 20
#define TextWidth 200
#define Time1 1
#define Time2 2
#define times 200
#define NO1 1
#define NO2 2
#define ERROR 0
#define NO 0
#define OK 1
#define true
#define false
int leng=1;
#define DEFAULT 0;

HDC hdc,hdc1,hdc2;
int xw,yw;
int iGame[MAX][MAX];
POINT point;



enum {Default,Player1,Player2}play;
enum {Stop,Play,Paush}plays;

typedef struct node
{
int X;
int Y;
struct node *Ppre;
}
Node;
Node *pTop = NULL; // 栈一开始就存在 , 并且为空

void Init(HWND hwnd);
void paint(int play,int x,int y);
void chagePlayer();
int Look(int x,int y,int play);
void over(HWND hwnd,int play);
void timechage(HWND hwnd);

bool StackEmpty();

void push(int Xcoordinates,int Ycoordinate);

void pop();



LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);


char szClassName[ ] = "五子棋 -WIN32版";

int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)

{
HWND hwnd;
MSG messages;
WNDCLASSEX wincl;


wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof (WNDCLASSEX);


wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;


if (!RegisterClassEx (&wincl))
return 0;


hwnd = CreateWindowEx (
1,
szClassName,
szClassName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
800,
600,
HWND_DESKTOP,
NULL,
hThisInstance,
NULL
);


ShowWindow (hwnd, nFunsterStil);


while (GetMessage (&messages, NULL, 0, 0))
{

TranslateMessage(&messages);

DispatchMessage(&messages);
}


return messages.wParam;
}




LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{



PAINTSTRUCT ps;

static HPEN hpen,hpen1,hpen2;
static HBRUSH hbrush,hbrush1,hbrush2;
int x,y;

switch (message) /* handle the messages */
{
case WM_KEYDOWN:
switch (wParam)
{
case VK_F5:
Init(hwnd);
Rectangle(hdc,0,0,xw,yw);
for(x=0;x<MAX;x++)
for(y=0;y<MAX;y++)
{
Rectangle(hdc,x*xw/MAX,y*yw/MAX,(x+1)*xw/MAX,(y+1)*yw/MAX) ;
iGame[x][y]=Default;
}
SetTimer(hwnd,Time1,times,NULL);
leng=1;
plays=Play;
break;
case VK_F1:
break;
case VK_F2:

SetTimer(hwnd,Time1,times,NULL);
leng=1;
plays=Play;
break;
case VK_F3:
if(plays==Play)
{
KillTimer(hwnd,Time1);
plays=Paush;
}
else
if(plays==Paush)
{
SetTimer(hwnd,Time1,times,NULL);
plays=Play;
}

break;
case VK_F4:
pop();
break;
}
break;
case WM_TIMER:
switch (wParam)
{
case Time1:
timechage(hwnd);
break;
}
break;
case WM_CREATE:
plays=Stop;
play=Player1;
break;
case WM_SIZE:
xw=LOWORD(lParam);
yw=HIWORD(lParam);
xw-=TextWidth;
InvalidateRect(hwnd,NULL,TRUE);

break;
case WM_LBUTTONDOWN:
//获取当前鼠标坐标
point.x=LOWORD(lParam);
point.y=HIWORD(lParam);
//初始化设备DC
Init(hwnd);
//鼠标坐标换为数组坐标
x=(point.x)/(xw/MAX);
y=(point.y)/(yw/MAX);
if(plays==Stop)break;

if(x<MAX&&y<MAX)
{

if(iGame[x][y]==Default&&plays==Play)//判断但前位置是否有棋子覆盖
{
leng=1;
paint(play,x,y);
if(Look(x,y,play))
over(hwnd,play);

chagePlayer();

}
}


break;
case WM_PAINT:

hdc=BeginPaint(hwnd,&ps);
Init(hwnd);


Rectangle(hdc,0,0,xw,yw);
for(x=0;x<MAX;x++)
for(y=0;y<MAX;y++)
{
Rectangle(hdc,x*xw/MAX,y*yw/MAX,(x+1)*xw/MAX,(y+1)*yw/MAX) ;
paint(iGame[x][y],x,y);
}
EndPaint(hwnd,&ps);
break;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}

return 0;
}






void Init(HWND hwnd)
{
hdc1=GetDC(hwnd);
hdc2=GetDC(hwnd);
//初始背景
SelectObject(hdc,CreatePen(0,1,RGB(255,0,0)));
SelectObject(hdc,CreateSolidBrush(RGB(0,0,0)));
//初始玩家一图形
SelectObject(hdc1,CreatePen(0,1,RGB(0,0,0)));
SelectObject(hdc1,CreateSolidBrush(RGB(0,255,0)));
//初始玩家二图形

SelectObject(hdc2,CreatePen(0,1,RGB(0,0,0)));
SelectObject(hdc2,CreateSolidBrush(RGB(0,0,255)));
SetBkMode(hdc,0);

Rectangle(hdc,xw+1,1,xw+30,yw);
Rectangle(hdc,xw+31,29,xw+200,30);
TextOut(hdc,xw+80,10,"五子棋",6);
TextOut(hdc,xw+45,100,"F2 - 开始游戏",13);
TextOut(hdc,xw+45,120,"F3 - 暂停/继续游戏",18);
TextOut(hdc,xw+45,140,"F4 - 悔棋",20);
TextOut(hdc,xw+45,160,"F5 - 重新开始游戏",16);
Rectangle(hdc,xw+31,180,xw+200,181);

TextOut(hdc,xw+49,189," 帮助文档 ",15);
TextOut(hdc,xw+45,210,"*建议最大化窗口游戏",19);
TextOut(hdc,xw+45,240," 1 按 F2启动游戏",18);
TextOut(hdc,xw+45,260," 2 鼠标点击棋盘",17);
TextOut(hdc,xw+30,320,"注意:滚动条为限制时间",22);


}





void timechage(HWND hwnd)
{
if(play==Player1)
{
Rectangle(hdc1,xw+1,leng++,xw+30,yw);
TextOut(hdc1,xw+33,30,"当前下棋主动权:玩家一",22);

if(leng>yw)
{
KillTimer(hwnd,Time1);
MessageBox(NULL,"时间到!玩家一您输了!","TimeOver",0);
SendMessage(hwnd,WM_KEYDOWN,VK_F5,NULL);
KillTimer(hwnd,Time1);
}
}
else
{
TextOut(hdc2,xw+33,30,"当前下棋主动权:玩家二",22);
Rectangle(hdc2,xw+1,leng++,xw+30,yw);
if(leng>yw)
{
KillTimer(hwnd,Time1);
MessageBox(NULL,"时间到!玩家二您输了!","TimeOver",0);
SendMessage(hwnd,WM_KEYDOWN,VK_F5,NULL);
KillTimer(hwnd,Time1);
}
}
}






void paint(int play,int x,int y) //画棋子
{
switch (play)
{
case Player1:
// if(iGame[x][y]!=Default);

push(x,y);
Ellipse(hdc1, x*xw/MAX, y*yw/MAX, (x+1)*xw/MAX, (y+1)*yw/MAX);

iGame[x][y]=Player1;

break;
case Player2:
// if(iGame[x][y]!=Default);

push(x,y);
Ellipse(hdc2,x*xw/MAX,y*yw/MAX,(x+1)*xw/MAX,(y+1)*yw/MAX);
iGame[x][y]=Player2;


break;


}

}

void chagePlayer() //改变玩家
{
if(play==Player1) play=Player2;
else
play=Player1;
}

int Look(int x,int y,int play) // 检查模块

{
int i,tempx,tempy;

int Up = 0;
int Down = 0;
int left = 0;
int right = 0;
int leUp = 0;
int leDn = 0;
int rgUp = 0;
int rgDn = 0;


tempx=x;tempy=y;
for(i=0;i<5&&iGame[tempx][tempy]==play;tempy--,i++)
{
Up++;
}
if(Up == 1)
Up = 0;
if(i>=5) return OK; //向上核对

tempx=x;tempy=y;
for(i=0;i<5&&iGame[tempx][tempy]==play;tempy++,i++)
{
Down ++;
}
if(Down == 1)
Down =0;
if(i>=5) return OK; //向下核对

if((Up + Down) >=5)
{
return OK;
}

tempx=x;tempy=y;
for(i=0;i<5&&iGame[tempx][tempy]==play;tempx--,i++)
{
left++;
}
if(left == 1)
left = 0;
if(i>=5) return OK; //向左核对


tempx=x;tempy=y;
for(i=0;i<5&&iGame[tempx][tempy]==play;tempx++,i++)
{
right ++;
}
if(right == 1)
right =0;
if(i>=5) return OK; //向右核对
if((left + right) >= 5)
return OK;

tempx=x;tempy=y;
for(i=0;i<5&&iGame[tempx][tempy]==play;tempx--,tempy--,i++)
{
leUp++;
}
if(leUp == 1)
leUp = 0;
if(i>=5) return OK; //向左上核对



tempx=x;tempy=y;
for(i=0;i<5&&iGame[tempx][tempy]==play;tempx++,tempy++,i++)
{
rgDn++;
}

if(rgDn == 1)
rgDn = 0;
if(i>=5) return OK; //向右下核对
if((leUp + rgDn) >= 5)
return OK;

tempx=x;tempy=y;
for(i=0;i<5&&iGame[tempx][tempy]==play;tempx--,tempy++,i++)
{
leDn ++;
}
if(leDn == 1)
leDn = 0;
if(i>=5) return OK; //向左下核对

tempx=x;tempy=y;
for(i=0;i<5&&iGame[tempx][tempy]==play;tempx++,tempy--,i++)
{
rgUp++;
}
if(rgUp == 1)
rgUp = 0;
if(i>=5) return OK; //向右上核对

if((leDn + rgUp) >= 5)
return OK;



return NO;
}

void over(HWND hwnd,int play)
{
switch(play)
{
case Player1:
KillTimer(hwnd,Time1);
MessageBox(hwnd,"恭喜玩家一获得胜利","胜利",0);
SendMessage(hwnd,WM_KEYDOWN,VK_F5,NULL);
KillTimer(hwnd,Time1);
plays=Stop;
// g_xPos = 0;
// g_yPos = 0;
break;
case Player2:
KillTimer(hwnd,Time1);
MessageBox(hwnd,"恭喜玩家二获得胜利","胜利",0);
SendMessage(hwnd,WM_KEYDOWN,VK_F5,NULL);
KillTimer(hwnd,Time1);
plays=Stop;
// g_xPos = 0;
// g_yPos = 0;
break;
}
}

//判断 栈是否为空
bool StackEmpty()
{
if(NULL==pTop )
{
return TRUE;
}
return FALSE;
}


//进栈
void push(int Xcoordinates,int Ycoordinate)
{

Node *tt = (Node *)malloc(sizeof(Node));
tt->Y = Ycoordinate;
tt->X = Xcoordinates;
tt->Ppre = pTop;
pTop = tt;
}

//出栈
void pop()
{
Node *tt;

if(StackEmpty())
{
return;
}
tt = pTop;
pTop = pTop->Ppre;
free(tt);
}
...全文
547 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
W170532934 2012-05-17
  • 打赏
  • 举报
回复
用栈来记录每一步的记录。可以记住谁的动作,棋子的坐标等信息
Kevin_Perkins 2012-05-17
  • 打赏
  • 举报
回复
记住上一步的坐标就可以了。
某大一菜鸟 2012-05-17
  • 打赏
  • 举报
回复
同上,每生成一个最佳走法之后将走法入栈,需要悔棋时出栈即可..

64,653

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧