// I_goV1.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include <time.h>
#include "resource.h"
#define MAX_LOADSTRING 100
#define UNIT_SIZE 15//模块单元大小
#define SQUARE_AMOUNT 17//窗体中模块单元的数目
#define WM_NEWSQUARE WM_USER+1//自定义消息
#define MYTIMER 1//自定义时钟标示
#define DIFLEVEL 500//难易度,即时钟间隔
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
// 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);
typedef struct _Square
{
POINT ps[4];
HWND hUnitWnd[4];
int type;
}Square,*pSquare;
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_I_GOV1, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_I_GOV1);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
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_I_GOV1);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_I_GOV1;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_CAPTION|WS_SYSMENU,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
static RECT rc;
static BOOL IsFilled[SQUARE_AMOUNT][SQUARE_AMOUNT];
static HWND hWndSquare[SQUARE_AMOUNT][SQUARE_AMOUNT];
static Square sq;
int i,j;
int xFirstUnitPos = SQUARE_AMOUNT/2;
static HMENU hMenu;
switch (message)
{
case WM_CREATE:
rc.left = rc.top = 0;
rc.right = rc.bottom = UNIT_SIZE*SQUARE_AMOUNT;
AdjustWindowRect(&rc, WS_CAPTION|WS_SYSMENU,TRUE);
SetWindowPos(hWnd,NULL,0,0,rc.right-rc.left,rc.bottom-rc.top,SWP_NOMOVE);
break;
case WM_TIMER:
//是否不能再往下落了
for ( i=0;i<4;i++)
{
if (IsFilled[sq.ps[i].x][sq.ps[i].y] == 1 )
{
KillTimer(hWnd,MYTIMER);
MessageBox(hWnd,"你已失败","注意",MB_OK) ;
PostMessage(hWnd,WM_DESTROY,0,0);
return 0;
}
if (sq.ps[i].y == SQUARE_AMOUNT-1 || IsFilled[sq.ps[i].x][sq.ps[i].y+1] == TRUE )
{
for (j=0;j<4;j++)//填充方块所占的区域
{
IsFilled[sq.ps[j].x][sq.ps[j].y] = TRUE;
hWndSquare[sq.ps[j].x][sq.ps[j].y] = sq.hUnitWnd[j];
}
KillTimer(hWnd,MYTIMER);
//消去方块
//浏览,产生记录条
{//procedure
unsigned int flag = 0;
for(i=SQUARE_AMOUNT-1;i>=0;i--)//y shaft
{
for(j=0;j<SQUARE_AMOUNT;j++)//x shaft
if ( !IsFilled[j][i] )
break;
if ( j == SQUARE_AMOUNT )
flag |=1l<<i;
}
if (flag) //有行要消掉
{
for( i=SQUARE_AMOUNT-1;i>=0;i-- )
if (flag&1l<<i) //消去这一行
for(j=0;j<SQUARE_AMOUNT;j++)
{
DestroyWindow(hWndSquare[j][i]);
IsFilled[j][i] = FALSE;
}
for (i=SQUARE_AMOUNT-1;i>=0;i--)
if ( !(flag&1l<<i) )//这行没有消去,进行下落处理
{
int temp,offset;
temp=i+1;
offset=0;
while(temp<SQUARE_AMOUNT)
{
if ( flag&1l<<temp )
offset++;
temp++;
}
for (j=0;j<SQUARE_AMOUNT;j++)
{
RECT rcUnit;
if ( IsFilled[j][i] )
{
GetWindowRect(hWndSquare[j][i],&rcUnit);
POINT pt;
pt.x = rcUnit.left;
pt.y = rcUnit.top;
ScreenToClient(hWnd,&pt);
MoveWindow(hWndSquare[j][i],pt.x,pt.y+offset*UNIT_SIZE,
UNIT_SIZE,UNIT_SIZE,TRUE);
IsFilled[j][i] = FALSE;
IsFilled[j][i+offset] = TRUE;
hWndSquare[j][i+offset] = hWndSquare[j][i];
}
}
}
}
}//procedure
SendMessage(hWnd,WM_NEWSQUARE,NULL,NULL);
return 0;
}
}
//移动方块
for ( i= 0;i<4;i++)
{
//_beginthread();
MoveWindow(sq.hUnitWnd[i],sq.ps[i].x*UNIT_SIZE,
(++sq.ps[i].y)*UNIT_SIZE,UNIT_SIZE,UNIT_SIZE,TRUE);
}
break;
case WM_NEWSQUARE://生成方块
srand( (unsigned)time( NULL ) );
switch ( rand()%6 )
{
/* @@@@ */
case 0:
sq.type = 0;
xFirstUnitPos = 8;
for( i=0;i<4;i++)
{
sq.ps[i].x = xFirstUnitPos+i;
sq.ps[i].y = 0;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
break;
/* @
@@@ */
case 1:
sq.type = 1;
for( i=0;i<4;i++)
{
if ( 0==i)
{
sq.ps[i].x = xFirstUnitPos;
sq.ps[i].y = 0;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,sq.ps[i].y,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
else
{
sq.ps[i].x = xFirstUnitPos + i-1;
sq.ps[i].y = 1;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,sq.ps[i].y,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
}
break;
/* @@
@@ */
case 2:
sq.type = 2;
for( i=0;i<4;i++)
{
if (i==0 || i==1 )
{
sq.ps[i].x = xFirstUnitPos+i;
sq.ps[i].y = 0;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
else
{
sq.ps[i].x = xFirstUnitPos+i-2;
sq.ps[i].y = 1;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
}
break;
/* @
@@@*/
case 3:
sq.type = 3;
for( i=0;i<4;i++)
{
if (i==0 )
{
sq.ps[i].x = xFirstUnitPos+1;
sq.ps[i].y = 0;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
else
{
sq.ps[i].x = xFirstUnitPos+i-1;
sq.ps[i].y = 1;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
}
break;
/* @@
@@ */
case 4:
sq.type = 4;
for( i=0;i<4;i++)
{
if (i==0 || i==1 )
{
sq.ps[i].x = xFirstUnitPos+i;
sq.ps[i].y = 0;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
else
{
sq.ps[i].x = xFirstUnitPos+i-1;
sq.ps[i].y = 1;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
}
break;
/* @@
@@ */
case 5:
sq.type = 5;
for( i=0;i<4;i++)
{
if (i==0 || i==1 )
{
sq.ps[i].x = xFirstUnitPos+i+1;
sq.ps[i].y = 0;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
else
{
sq.ps[i].x = xFirstUnitPos+i-2;
sq.ps[i].y = 1;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
}
break;
}
SetTimer(hWnd,MYTIMER,DIFLEVEL,NULL);
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_LEFT:
for (i=0;i<4;i++)
{
if ( sq.ps[i].x-1 < 0 || IsFilled[sq.ps[i].x-1][sq.ps[i].y] == TRUE )
return 0;
}
for (i=0;i<4;i++)
MoveWindow(sq.hUnitWnd[i],--sq.ps[i].x*UNIT_SIZE,
sq.ps[i].y*UNIT_SIZE,UNIT_SIZE,UNIT_SIZE,TRUE);
break;
case VK_RIGHT:
for (i=0;i<4;i++)
{
if ( sq.ps[i].x+1 > SQUARE_AMOUNT-1 || IsFilled[sq.ps[i].x+1][sq.ps[i].y] == TRUE )
return 0;
}
for (i=0;i<4;i++)
MoveWindow(sq.hUnitWnd[i],++sq.ps[i].x*UNIT_SIZE,
sq.ps[i].y*UNIT_SIZE,UNIT_SIZE,UNIT_SIZE,TRUE);
break;
case VK_DOWN:
SendMessage(hWnd,WM_TIMER,0,0);
break;
case VK_SPACE://方块变形
int shaft;
switch(sq.type)//确定每个方块的中轴方向
{
/* @@@@ */
case 0:
shaft = 1;
break;
/* @
@@@ */
case 1:
shaft = 1;
break;
/* @@
@@ */
case 2:
return 0;
break;
/* @
@@@*/
case 3:
shaft = 2;
break;
/* @@
@@ */
case 4:
shaft = 2;
break;
/* @@
@@ */
case 5:
shaft = 0;
break;
}
int offset[4][2];//保存每个unit和中心轴模块的距离,以判断所在象限和区域
for (i=0;i<4;i++)
{
offset[i][0] = sq.ps[i].x - sq.ps[shaft].x;
offset[i][1] = sq.ps[i].y - sq.ps[shaft].y;
}
Square sqTemp = sq;
long tempx,tempy;
for (i=0;i<4;i++)
if ( offset[i][0]>0 && offset[i][1]==0 )//x轴正半轴
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = 0 + sq.ps[shaft].x;
sqTemp.ps[i].y = tempx + sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}else
if (offset[i][0]>0 && offset[i][1] >0 )//第一象限
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = -tempx + sq.ps[shaft].x;
sqTemp.ps[i].y = tempy + sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}else
if (offset[i][0] == 0 && offset[i][1] >0 )//y轴正半轴
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = -tempy + sq.ps[shaft].x;
sqTemp.ps[i].y = 0+ sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}else
if (offset[i][0]<0 && offset[i][1] >0 )//第二象限
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = tempx + sq.ps[shaft].x;
sqTemp.ps[i].y = -tempy + sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}
else
if (offset[i][0]<0 && offset[i][1] == 0 )//x轴负半轴
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = 0 + sq.ps[shaft].x;
sqTemp.ps[i].y = tempx + sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}
else
if (offset[i][0]<0 && offset[i][1] <0 )//第三象限
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = -tempx + sq.ps[shaft].x;
sqTemp.ps[i].y = tempy + sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}
else
if (offset[i][0] == 0 && offset[i][1] <0 )//y轴负半轴
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = -tempy + sq.ps[shaft].x;
sqTemp.ps[i].y = 0 + sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}
else
if (offset[i][0]>0 && offset[i][1] <0 )//第四象限
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = tempx + sq.ps[shaft].x;
sqTemp.ps[i].y = -tempy + sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}
sq = sqTemp;
for (i=0;i<4;i++)//重新移动方块
MoveWindow(sq.hUnitWnd[i],sq.ps[i].x*UNIT_SIZE,sq.ps[i].y*UNIT_SIZE,
UNIT_SIZE,UNIT_SIZE,TRUE);
break;
}
break;
case WM_COMMAND:
hMenu= GetMenu(hWnd);
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_START:
SendMessage(hWnd,WM_NEWSQUARE,NULL,NULL);
EnableMenuItem(hMenu,IDM_START,MF_DISABLED|MF_GRAYED);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
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);
break;
case WM_DESTROY:
KillTimer(hWnd,MYTIMER);
PostQuitMessage(0);
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;
}
//
#include "stdafx.h"
#include <time.h>
#include "resource.h"
#define MAX_LOADSTRING 100
#define UNIT_SIZE 15//模块单元大小
#define SQUARE_AMOUNT 17//窗体中模块单元的数目
#define WM_NEWSQUARE WM_USER+1//自定义消息
#define MYTIMER 1//自定义时钟标示
#define DIFLEVEL 500//难易度,即时钟间隔
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
// 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);
typedef struct _Square
{
POINT ps[4];
HWND hUnitWnd[4];
int type;
}Square,*pSquare;
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_I_GOV1, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_I_GOV1);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
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_I_GOV1);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_I_GOV1;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_CAPTION|WS_SYSMENU,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
static RECT rc;
static BOOL IsFilled[SQUARE_AMOUNT][SQUARE_AMOUNT];
static HWND hWndSquare[SQUARE_AMOUNT][SQUARE_AMOUNT];
static Square sq;
int i,j;
int xFirstUnitPos = SQUARE_AMOUNT/2;
static HMENU hMenu;
switch (message)
{
case WM_CREATE:
rc.left = rc.top = 0;
rc.right = rc.bottom = UNIT_SIZE*SQUARE_AMOUNT;
AdjustWindowRect(&rc, WS_CAPTION|WS_SYSMENU,TRUE);
SetWindowPos(hWnd,NULL,0,0,rc.right-rc.left,rc.bottom-rc.top,SWP_NOMOVE);
break;
case WM_TIMER:
//是否不能再往下落了
for ( i=0;i<4;i++)
{
if (IsFilled[sq.ps[i].x][sq.ps[i].y] == 1 )
{
KillTimer(hWnd,MYTIMER);
MessageBox(hWnd,"你已失败","注意",MB_OK) ;
PostMessage(hWnd,WM_DESTROY,0,0);
return 0;
}
if (sq.ps[i].y == SQUARE_AMOUNT-1 || IsFilled[sq.ps[i].x][sq.ps[i].y+1] == TRUE )
{
for (j=0;j<4;j++)//填充方块所占的区域
{
IsFilled[sq.ps[j].x][sq.ps[j].y] = TRUE;
hWndSquare[sq.ps[j].x][sq.ps[j].y] = sq.hUnitWnd[j];
}
KillTimer(hWnd,MYTIMER);
//消去方块
//浏览,产生记录条
{//procedure
unsigned int flag = 0;
for(i=SQUARE_AMOUNT-1;i>=0;i--)//y shaft
{
for(j=0;j<SQUARE_AMOUNT;j++)//x shaft
if ( !IsFilled[j][i] )
break;
if ( j == SQUARE_AMOUNT )
flag |=1l<<i;
}
if (flag) //有行要消掉
{
for( i=SQUARE_AMOUNT-1;i>=0;i-- )
if (flag&1l<<i) //消去这一行
for(j=0;j<SQUARE_AMOUNT;j++)
{
DestroyWindow(hWndSquare[j][i]);
IsFilled[j][i] = FALSE;
}
for (i=SQUARE_AMOUNT-1;i>=0;i--)
if ( !(flag&1l<<i) )//这行没有消去,进行下落处理
{
int temp,offset;
temp=i+1;
offset=0;
while(temp<SQUARE_AMOUNT)
{
if ( flag&1l<<temp )
offset++;
temp++;
}
for (j=0;j<SQUARE_AMOUNT;j++)
{
RECT rcUnit;
if ( IsFilled[j][i] )
{
GetWindowRect(hWndSquare[j][i],&rcUnit);
POINT pt;
pt.x = rcUnit.left;
pt.y = rcUnit.top;
ScreenToClient(hWnd,&pt);
MoveWindow(hWndSquare[j][i],pt.x,pt.y+offset*UNIT_SIZE,
UNIT_SIZE,UNIT_SIZE,TRUE);
IsFilled[j][i] = FALSE;
IsFilled[j][i+offset] = TRUE;
hWndSquare[j][i+offset] = hWndSquare[j][i];
}
}
}
}
}//procedure
SendMessage(hWnd,WM_NEWSQUARE,NULL,NULL);
return 0;
}
}
//移动方块
for ( i= 0;i<4;i++)
{
//_beginthread();
MoveWindow(sq.hUnitWnd[i],sq.ps[i].x*UNIT_SIZE,
(++sq.ps[i].y)*UNIT_SIZE,UNIT_SIZE,UNIT_SIZE,TRUE);
}
break;
case WM_NEWSQUARE://生成方块
srand( (unsigned)time( NULL ) );
switch ( rand()%6 )
{
/* @@@@ */
case 0:
sq.type = 0;
xFirstUnitPos = 8;
for( i=0;i<4;i++)
{
sq.ps[i].x = xFirstUnitPos+i;
sq.ps[i].y = 0;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
break;
/* @
@@@ */
case 1:
sq.type = 1;
for( i=0;i<4;i++)
{
if ( 0==i)
{
sq.ps[i].x = xFirstUnitPos;
sq.ps[i].y = 0;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,sq.ps[i].y,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
else
{
sq.ps[i].x = xFirstUnitPos + i-1;
sq.ps[i].y = 1;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,sq.ps[i].y,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
}
break;
/* @@
@@ */
case 2:
sq.type = 2;
for( i=0;i<4;i++)
{
if (i==0 || i==1 )
{
sq.ps[i].x = xFirstUnitPos+i;
sq.ps[i].y = 0;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
else
{
sq.ps[i].x = xFirstUnitPos+i-2;
sq.ps[i].y = 1;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
}
break;
/* @
@@@*/
case 3:
sq.type = 3;
for( i=0;i<4;i++)
{
if (i==0 )
{
sq.ps[i].x = xFirstUnitPos+1;
sq.ps[i].y = 0;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
else
{
sq.ps[i].x = xFirstUnitPos+i-1;
sq.ps[i].y = 1;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
}
break;
/* @@
@@ */
case 4:
sq.type = 4;
for( i=0;i<4;i++)
{
if (i==0 || i==1 )
{
sq.ps[i].x = xFirstUnitPos+i;
sq.ps[i].y = 0;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
else
{
sq.ps[i].x = xFirstUnitPos+i-1;
sq.ps[i].y = 1;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
}
break;
/* @@
@@ */
case 5:
sq.type = 5;
for( i=0;i<4;i++)
{
if (i==0 || i==1 )
{
sq.ps[i].x = xFirstUnitPos+i+1;
sq.ps[i].y = 0;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
else
{
sq.ps[i].x = xFirstUnitPos+i-2;
sq.ps[i].y = 1;
sq.hUnitWnd[i] = CreateWindow("BUTTON",NULL,WS_VISIBLE|WS_CHILD,sq.ps[i].x*UNIT_SIZE,0,
UNIT_SIZE,UNIT_SIZE,hWnd,NULL,hInst,NULL);
}
}
break;
}
SetTimer(hWnd,MYTIMER,DIFLEVEL,NULL);
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_LEFT:
for (i=0;i<4;i++)
{
if ( sq.ps[i].x-1 < 0 || IsFilled[sq.ps[i].x-1][sq.ps[i].y] == TRUE )
return 0;
}
for (i=0;i<4;i++)
MoveWindow(sq.hUnitWnd[i],--sq.ps[i].x*UNIT_SIZE,
sq.ps[i].y*UNIT_SIZE,UNIT_SIZE,UNIT_SIZE,TRUE);
break;
case VK_RIGHT:
for (i=0;i<4;i++)
{
if ( sq.ps[i].x+1 > SQUARE_AMOUNT-1 || IsFilled[sq.ps[i].x+1][sq.ps[i].y] == TRUE )
return 0;
}
for (i=0;i<4;i++)
MoveWindow(sq.hUnitWnd[i],++sq.ps[i].x*UNIT_SIZE,
sq.ps[i].y*UNIT_SIZE,UNIT_SIZE,UNIT_SIZE,TRUE);
break;
case VK_DOWN:
SendMessage(hWnd,WM_TIMER,0,0);
break;
case VK_SPACE://方块变形
int shaft;
switch(sq.type)//确定每个方块的中轴方向
{
/* @@@@ */
case 0:
shaft = 1;
break;
/* @
@@@ */
case 1:
shaft = 1;
break;
/* @@
@@ */
case 2:
return 0;
break;
/* @
@@@*/
case 3:
shaft = 2;
break;
/* @@
@@ */
case 4:
shaft = 2;
break;
/* @@
@@ */
case 5:
shaft = 0;
break;
}
int offset[4][2];//保存每个unit和中心轴模块的距离,以判断所在象限和区域
for (i=0;i<4;i++)
{
offset[i][0] = sq.ps[i].x - sq.ps[shaft].x;
offset[i][1] = sq.ps[i].y - sq.ps[shaft].y;
}
Square sqTemp = sq;
long tempx,tempy;
for (i=0;i<4;i++)
if ( offset[i][0]>0 && offset[i][1]==0 )//x轴正半轴
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = 0 + sq.ps[shaft].x;
sqTemp.ps[i].y = tempx + sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}else
if (offset[i][0]>0 && offset[i][1] >0 )//第一象限
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = -tempx + sq.ps[shaft].x;
sqTemp.ps[i].y = tempy + sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}else
if (offset[i][0] == 0 && offset[i][1] >0 )//y轴正半轴
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = -tempy + sq.ps[shaft].x;
sqTemp.ps[i].y = 0+ sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}else
if (offset[i][0]<0 && offset[i][1] >0 )//第二象限
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = tempx + sq.ps[shaft].x;
sqTemp.ps[i].y = -tempy + sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}
else
if (offset[i][0]<0 && offset[i][1] == 0 )//x轴负半轴
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = 0 + sq.ps[shaft].x;
sqTemp.ps[i].y = tempx + sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}
else
if (offset[i][0]<0 && offset[i][1] <0 )//第三象限
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = -tempx + sq.ps[shaft].x;
sqTemp.ps[i].y = tempy + sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}
else
if (offset[i][0] == 0 && offset[i][1] <0 )//y轴负半轴
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = -tempy + sq.ps[shaft].x;
sqTemp.ps[i].y = 0 + sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}
else
if (offset[i][0]>0 && offset[i][1] <0 )//第四象限
{
tempx = offset[i][0];
tempy = offset[i][1];
sqTemp.ps[i].x = tempx + sq.ps[shaft].x;
sqTemp.ps[i].y = -tempy + sq.ps[shaft].y;
if ( IsFilled[sqTemp.ps[i].x][sqTemp.ps[i].y] ||
sqTemp.ps[i].x<0 ||sqTemp.ps[i].x>SQUARE_AMOUNT-1 ||
sqTemp.ps[i].y<0 ||sqTemp.ps[i].y>SQUARE_AMOUNT-1 )
return 0;//检测是否越界或是与已有方块冲突
}
sq = sqTemp;
for (i=0;i<4;i++)//重新移动方块
MoveWindow(sq.hUnitWnd[i],sq.ps[i].x*UNIT_SIZE,sq.ps[i].y*UNIT_SIZE,
UNIT_SIZE,UNIT_SIZE,TRUE);
break;
}
break;
case WM_COMMAND:
hMenu= GetMenu(hWnd);
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_START:
SendMessage(hWnd,WM_NEWSQUARE,NULL,NULL);
EnableMenuItem(hMenu,IDM_START,MF_DISABLED|MF_GRAYED);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
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);
break;
case WM_DESTROY:
KillTimer(hWnd,MYTIMER);
PostQuitMessage(0);
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;
}