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