📄 pp.cpp
字号:
// pp.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#include "stdio.h"
#include <time.h>
#include <fstream.h>
#define MAX_LOADSTRING 100
#define LEFT 150
#define TOP 20
#define RIGHT 450
#define BOTTOM 320
#define SIZE 100
#define MOVE_UP 38
#define MOVE_DOWN 40
#define MOVE_LEFT 37
#define MOVE_RIGHT 39
#define STOP 0
#define USER 1
#define AUTO 2
#define DISPLAY 3
#define LEN 10
#define FAIL -1
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
int map[10]={0};//存储九宫图数据
int *stack,*stack_top;//自定义堆栈
int *knowledge=NULL,*knowledge_top=NULL;//存储知识,即已存储的状态即走法
int knowledge_len=0;//存储已存记录的长度(个数)
int sign;//标志当前游戏状态(停止、玩家、自动、演示)
long len;//堆栈长度
long max_len;//堆栈最大长度
BOOL searching;//正在用Search进行搜索的标志
HWND hwnd;//
BOOL study;//
FILE *fp;//外部文件
int playspeed=400;//演示速度
long step;//演示步数
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
void ReDraw();//重画九宫图
void NewGame();//开始新游戏
void Auto();//开启自动搜索
BOOL MoveUp();//向上移动
BOOL MoveLeft();//左
BOOL MoveRight();//右
BOOL MoveBottom();//下
int GetReverse();//获取当前状态的逆序数
BOOL Success();//判断是否成功
BOOL Search(int direct);//自动搜索的递归算法
BOOL Push();//将当前状态压入自定义的堆栈
void Pop();//出栈,放入当前状态
void ShowWaiting();//显示“Please Waiting”
void AutoSearch();//自动搜索的函数,被Auto调用,调用Search
void OpenStudy();//开启学习状态
void CloseStudy();//关闭学习状态
void ReadKnowledge();//读取已存状态
void SaveKnowledge();//保存状态
int SearchKnowledge();//在状态中搜索当前状态,如有,返回应走方向,否则返回0
void Study(int direct);//学习,保存当前状态及走法
int Judge();//在未搜索到的情况下判断走法
void GetDistance(int pos1,int pos2,BOOL& narrow,int& direct);//获得两点位置关系
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_PP, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_PP);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_PP);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_PP;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
hwnd=hWnd;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
int the_Direct;
// HMENU hmenu;
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_CREATE:
sign=STOP;
stack=(int*)malloc(sizeof(int)*100000*LEN);
stack_top=stack;
len=0;
max_len=100000;//初始化堆栈
study=false;
ReadKnowledge();//读取已存知识
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_NEW:
NewGame();//开始新游戏
break;
case IDM_AUTO:
Auto();//开启自动搜索
break;
case IDM_STUDY:
//hmenu=GetMenu(hWnd);
if(study==false)
{
// CheckMenuItem(hmenu,IDM_STUDY,MF_CHECKED);
OpenStudy();
// study=true;
}
else
{
// CheckMenuItem(hmenu,IDM_STUDY,MF_UNCHECKED);
CloseStudy();//打开、关闭学习开关
// study=false;
}
break;
case IDM_LOWSPEED:
playspeed=800;
break;
case IDM_MIDDLESPEED:
playspeed=400;
break;
case IDM_HIGHSPEED:
playspeed=100;
break;
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
if(study==true)
CloseStudy();//存储已存状态
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
//TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
ReDraw();
break;
case WM_KEYDOWN:
if(sign!=USER)
return 0;
the_Direct=int(wParam);
switch(the_Direct)
{
case MOVE_UP:
if(MoveUp()==false)
MessageBeep(MB_OK);
break;
case MOVE_DOWN:
if(MoveBottom()==false)
MessageBeep(MB_OK);
break;
case MOVE_LEFT:
if(MoveLeft()==false)
MessageBeep(MB_OK);
break;
case MOVE_RIGHT:
if(MoveRight()==false)//接收键盘输入
MessageBeep(MB_OK);
break;
default:
return 0;
}
ReDraw();
if(Success()==true)
{
if(MessageBox(hWnd,"再来一局?","胜利!!!",MB_OKCANCEL)==IDOK)
NewGame();
else
sign=STOP;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
free(stack);
SaveKnowledge();
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
void ReDraw()
{
HDC hdc;
hdc=GetDC(hwnd);
HBRUSH hBr1,hBr2;
LPPOINT lppoint=NULL;
hBr1=(HBRUSH)GetStockObject(DKGRAY_BRUSH);
SelectObject(hdc,hBr1);
Rectangle(hdc,LEFT,TOP,RIGHT,BOTTOM);
if(map[0]!=0)
{
hBr2=(HBRUSH)GetStockObject(GRAY_BRUSH);
SelectObject(hdc,hBr2);
int x,y;
switch(map[0])
{
case 1:
x=1;y=1;break;
case 2:
x=2;y=1;break;
case 3:
x=3;y=1;break;
case 4:
x=1;y=2;break;
case 5:
x=2;y=2;break;
case 6:
x=3;y=2;break;
case 7:
x=1;y=3;break;
case 8:
x=2;y=3;break;
case 9:
x=3;y=3;break;
}
Rectangle(hdc,LEFT+(x-1)*100,TOP+(y-1)*100,LEFT+x*100,TOP+y*100);
//Draw the text
for(int j=1;j<=9;j++)
{
switch(j)
{
case 1:
x=1;y=1;break;
case 2:
x=2;y=1;break;
case 3:
x=3;y=1;break;
case 4:
x=1;y=2;break;
case 5:
x=2;y=2;break;
case 6:
x=3;y=2;break;
case 7:
x=1;y=3;break;
case 8:
x=2;y=3;break;
case 9:
x=3;y=3;break;
}
if(j!=map[0])
{
char out_text[2];
sprintf(out_text,"%d",map[j]);
TextOut(hdc,LEFT+(x-1)*100+45,TOP+(y-1)*100+45,out_text,1);
}
}
DeleteObject(hBr2);
}
MoveToEx(hdc,LEFT+100,TOP,lppoint);
LineTo(hdc,LEFT+100,BOTTOM);
MoveToEx(hdc,LEFT+200,TOP,lppoint);
LineTo(hdc,LEFT+200,BOTTOM);
MoveToEx(hdc,LEFT,TOP+100,lppoint);
LineTo(hdc,RIGHT,TOP+100);
MoveToEx(hdc,LEFT,TOP+200,lppoint);
LineTo(hdc,RIGHT,TOP+200);
DeleteObject(hBr1);
if(sign==DISPLAY)
{
char dstep[20];
sprintf(dstep,"(Steps:%5ld /",step);
TextOut(hdc,230,345,dstep,18);
}
ReleaseDC(hwnd,hdc);
}
void NewGame()
{
int i,j,k,temp;
if(sign==USER)//判断状态
{
if(MessageBox(hwnd,"放弃当前游戏?","提示",MB_OKCANCEL)==IDCANCEL)
{
return;
}
if(MessageBox(hwnd,"当前游戏是否无解?","提示",MB_OKCANCEL)==IDOK)
Study(FAIL);//如果此状态无解,也存入状态表中
}
srand((unsigned)time(NULL));
map[0]=9;
for(i=1;i<9;i++)
map[i]=i;
map[9]=0;
do{
for(i=0;i<10;i++)
{
j=rand()%9+1;
k=rand()%9+1;
temp=map[j];
map[j]=map[k];
map[k]=temp;
if(map[j]==0)
map[0]=j;
if(map[k]==0)
map[0]=k;
}
}while(GetReverse()==0);//随机产生一个状态
ReDraw();
sign=USER;
stack_top=stack;
len=0;
}
void Auto()
{
if(sign!=USER)
return;
sign=AUTO;
DWORD ID1;
DWORD ID2;
searching=true;
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ShowWaiting,NULL,0,&ID1);
//开启搜索线程
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)AutoSearch,NULL,0,&ID2);
//开启显示等待线程
//主线程接受用户输入
}
BOOL MoveUp()
{
if(map[0]==1||map[0]==2||map[0]==3)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -