#include "stdafx.h"
#include "sokoban.h"
#include "gameDlg.h"
extern CgameDlg *mainDlg;
sokoban *pThis;
int levelArr[6][8] = {
{ 1, 1, 1, 1, 0, 0, 0, 0 },
{ 1, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 0, 2, 0, 0, 3, 0, 1 },
{ 1, 0, 3, 0, 0, 2, 4, 1 },
{ 1, 1, 1, 0, 0, 1, 1, 1 },
{ 0, 0, 1, 1, 1, 1, 0, 0 }
};
sokoban::sokoban()
{
pThis = this;
}
sokoban::~sokoban()
{
}
struct xSleepObj
{
int duration;
HANDLE evenHandle;
};
DWORD WINAPI xSleepThread(LPVOID pWaitTime)
{
xSleepObj *sleep = (xSleepObj*)pWaitTime;
Sleep(sleep->duration);
SetEvent(sleep->evenHandle);
return 0;
}
// 非阻塞延时
void xSleep(int nWaitInMsecs)
{
xSleepObj sleep;
sleep.duration = nWaitInMsecs;
sleep.evenHandle = CreateEvent(NULL, TRUE, FALSE, NULL);
DWORD dwThreadId;
CreateThread(NULL, 0, &xSleepThread, &sleep, 0, &dwThreadId);
MSG msg;
while (::WaitForSingleObject(sleep.evenHandle, 0) == WAIT_TIMEOUT)
{
// get and dispatch message
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
CloseHandle(sleep.evenHandle);
}
int sokoban::start(){
curRow = 0;
curCol = 0;
directPos.x = 0;
directPos.y = 0;
m_hThread[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadProc, (LPVOID)this, 0, NULL);
return 0;
}
DWORD WINAPI sokoban::threadProc(LPVOID lpParam) {
//sokoban *pThis = (sokoban*)lpParam;
xSleep(500);
pThis->drawMap();
return 0;
}
int sokoban::drawMap() {
mainDlg->drawMap(levelArr);
return 0;
}
void sokoban::moveLeft(){
TRACE("moveLeft\n");
canMove(0, -1);
}
void sokoban::moveRight(){
TRACE("moveRight\n");
canMove(0, 1);
}
void sokoban::moveUp(){
TRACE("moveUp\n");
canMove(-1, 0);
}
void sokoban::moveDown(){
TRACE("moveDown\n");
canMove(1, 0);
}
BOOL sokoban::canMove(int row, int col){
if (isWalkable(pThis->curRow + row, pThis->curCol + col)){
moveMan(row, col);
drawMap();
}else {
if (isBox((pThis->curRow + row),(pThis->curCol + col))) {
if (isWalkable((pThis->curRow + 2 * row), (pThis->curCol + 2 * col))) {
moveBox((pThis->curRow + row), (pThis->curCol + col), row, col);
moveMan(row, col);
drawMap();
}
}
}
return TRUE;
}
BOOL sokoban::isWalkable(int row, int col){
if (levelArr[row][col] % 2 == 0){
return TRUE;
}
else{
return FALSE;
}
}
//如果该行列位置被箱子(3,5)所占
BOOL sokoban::isBox(int row, int col){
int num= levelArr[row][col];
if (num % 2 == 1 && num > 1){
return TRUE;
}
else{
return FALSE;
}
}
void sokoban::moveMan(int row, int col){
levelArr[curRow + row][curCol + col] += 4;
levelArr[curRow][curCol] -= 4;
curRow += row;
curCol += col;
}
void sokoban::moveBox(int boxRow, int boxCol, int row, int col){
levelArr[boxRow + row][boxCol + col] += 3;
levelArr[boxRow][boxCol] -= 3;
}