{"id":363,"date":"2013-12-16T23:56:09","date_gmt":"2013-12-16T15:56:09","guid":{"rendered":"http:\/\/blog.sorayuki.net\/?p=363"},"modified":"2013-12-17T00:07:56","modified_gmt":"2013-12-16T16:07:56","slug":"%e8%b4%aa%e9%a3%9f%e8%9b%87","status":"publish","type":"post","link":"https:\/\/blog.sorayuki.net\/?p=363","title":{"rendered":"\u8d2a\u98df\u86c7"},"content":{"rendered":"<p>\u6211\u662f\u4e3a\u4e86\u8bc1\u660e\u201c\u8fd9\u79cd\u4e1c\u897f\u5176\u5b9e\u6211\u4e5f\u53ef\u4ee5\u5199\u5f97\u51fa\u6765\u7684\uff01\u201d\u5417\uff1f<\/p>\n<p>\u611f\u60f3\uff1a\u7528WM_TIMER\u5b9a\u65f6\u5b9e\u5728\u662f\u4e0d\u591f\u51c6\uff0c\u504f\u5dee\u592a\u5927\u3002\u6700\u540e\u8fd8\u662f\u6362\u4e86WaitableTimer<\/p>\n<div id=\"scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:42ab43af-2ab4-494e-85c6-d875151b6c55\" class=\"wlWriterEditableSmartContent\" style=\"float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px\">\n<p> <a href=\"https:\/\/blog.sorayuki.net\/wp-content\/uploads\/2013\/12\/tss6.7z\" target=\"_blank\">\u4e0b\u8f7dEXE<\/a><\/p>\n<\/div>\n<p><!--more--><\/p>\n<div id=\"scid:887EC618-8FBE-49a5-A908-2339AF2EC720:74916c14-2dd8-47a6-b157-1dea829aa832\" class=\"wlWriterEditableSmartContent\" style=\"float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px\">         <code><\/p>\n<pre>#define _WIN32_WINNT 0x0400\n#include &lt;Windows.h&gt;\n#include &lt;commctrl.h&gt;\n#include &lt;stdlib.h&gt;\n#pragma comment(lib, \"user32.lib\")\n#pragma comment(lib, \"gdi32.lib\")\n#pragma comment(lib, \"comctl32.lib\")\n#pragma comment(linker, \"\/subsystem:windows\")\n\n\/\/\u53ef\u8c03\u6574\u7684\u521d\u59cb\u6570\u636e\nenum { BlockLen = 30, HCnt = 15, VCnt = 15, InitPosX = 5, InitPosY = 5, InitLen = 3, InitTimerInterval = 800 };\n\nstruct SnakeNode {\n    int x;\n    int y;\n    struct SnakeNode* next;\n};\n\nstruct Map {\n    SnakeNode* snake;\n    int eggx; \/\/\u86cb\u7684\u4f4d\u7f6e\n    int eggy;\n    int snakedx; \/\/\u86c7\u7684\u65b9\u5411\n    int snakedy;\n    int curLevel; \/\/\u96be\u5ea6\n    int eggCnt; \/\/\u5403\u7684\u86cb\u7684\u4e2a\u6570\n} gameMap;\n\nHWND hMain, hPic, hInfo;\n\nvoid GenEgg() \/\/\u751f\u6210\u65b0\u7684\u86cb\u7684\u4f4d\u7f6e\n{\n    int x, y;\n    for(;;) {\n        int flag = 0;\n        x = rand() % HCnt;\n        y = rand() % VCnt;\n        int snkCnt = 0;\n        struct SnakeNode* s = gameMap.snake;\n        while(s != 0) {\n            if (s-&gt;x == x && s-&gt;y == y) {\n                flag = 1;\n                ++snkCnt;\n            }\n            s = s-&gt;next;\n        }\n        if (snkCnt == HCnt * VCnt) break; \/\/\u5982\u679c\u5730\u56fe\u6ee1\u4e86\n        if (flag == 0) break;\n    }\n    gameMap.eggx = x;\n    gameMap.eggy = y;\n}\n\nvoid ReleaseGameMap()\n{\n    while(gameMap.snake != 0) {\n        void* p = gameMap.snake;\n        gameMap.snake = gameMap.snake-&gt;next;\n        free(p);\n    }\n}\n\nvoid InitGameMap()\n{\n    struct SnakeNode *ls = 0, *s;\n    int i;\n    int x = InitPosX, y = InitPosY;\n    \n    for(i = 0; i &lt; InitLen; ++i) {\n        s = (struct SnakeNode*) malloc(sizeof(*s));\n        s-&gt;x = x; s-&gt;y = y;\n        if (ls == 0) {\n            gameMap.snake = ls = s;\n        } else {\n            ls-&gt;next = s;\n            ls = s;\n        }\n        --x;\n    }\n    gameMap.snakedx = 0;\n    gameMap.snakedy = 0;\n    ls-&gt;next = 0;\n    gameMap.eggCnt = 0;\n    gameMap.curLevel = 0;\n    GenEgg();\n}\n\nvoid GenPic() {\n    HDC wdc = GetDC(hPic);\n    HBITMAP buf = CreateCompatibleBitmap(wdc, HCnt * BlockLen, VCnt * BlockLen);\n    HDC mdc = CreateCompatibleDC(wdc);\n    SelectObject(mdc, buf);\n    HBRUSH whiteBrush = CreateSolidBrush(RGB(255, 255, 255));\n    HPEN whitePen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));\n    HBRUSH redBrush = CreateSolidBrush(RGB(255, 0, 0));\n    HPEN redPen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));\n    ReleaseDC(hPic, wdc);\n\n    SelectObject(mdc, whitePen);\n    SelectObject(mdc, whiteBrush);\n    Rectangle(mdc, 0, 0, HCnt * BlockLen, VCnt * BlockLen);\n\n    \/\/\u753b\u86cb\n    SelectObject(mdc, redBrush);\n    SelectObject(mdc, redPen);\n    int eggl = gameMap.eggx * BlockLen;\n    int eggt = gameMap.eggy * BlockLen;\n    Ellipse(mdc, eggl, eggt, eggl + BlockLen, eggt + BlockLen);\n\n    \/\/\u753b\u86c7\n    LOGBRUSH lb;\n    lb.lbColor = RGB(0, 255, 0);\n    lb.lbStyle = BS_SOLID;\n    lb.lbHatch = 0;\n    HPEN snakePen = ExtCreatePen(PS_GEOMETRIC | PS_ENDCAP_ROUND | PS_JOIN_ROUND, BlockLen - 2, &lb, 0, 0);\n    SelectObject(mdc, snakePen);\n    int snkCnt = 0;\n    struct SnakeNode* sn = gameMap.snake;\n    while(sn != 0) {\n        ++snkCnt;\n        sn = sn-&gt;next;\n    }\n    POINT* pots = (POINT*) malloc(sizeof(POINT) * snkCnt);\n    int i = 0;\n    sn = gameMap.snake;\n    while(sn != 0) {\n        pots[i].x = sn-&gt;x * BlockLen + BlockLen \/ 2;\n        pots[i].y = sn-&gt;y * BlockLen + BlockLen \/ 2;\n        ++i;\n        sn = sn-&gt;next;\n    }\n    Polyline(mdc, pots, snkCnt);\n    free(pots);\n    \n    \/\/\u70b9\u86c7\u5934\n    SelectObject(mdc, redBrush);\n    SelectObject(mdc, redPen);\n    Ellipse(mdc, gameMap.snake-&gt;x * BlockLen, gameMap.snake-&gt;y * BlockLen, gameMap.snake-&gt;x * BlockLen + BlockLen, gameMap.snake-&gt;y * BlockLen + BlockLen);\n\n    DeleteObject(snakePen);\n    DeleteObject(redBrush);\n    DeleteObject(redPen);\n    DeleteObject(whiteBrush);\n    DeleteObject(whitePen);\n    DeleteDC(mdc);\n\n    HBITMAP oldbm = (HBITMAP)SendMessage(hPic, STM_GETIMAGE, (WPARAM)IMAGE_BITMAP, 0);\n    SendMessage(hPic, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)buf);\n    if (oldbm != 0)\n        DeleteObject(oldbm);\n    InvalidateRect(hPic, NULL, FALSE);\n\n    \/\/\u663e\u793a\u4fe1\u606f\n    TCHAR infoBuf[64];\n    wsprintf(infoBuf, TEXT(\"\u96be\u5ea6\uff1a%d \u5f97\u5206\uff1a%d\"), gameMap.curLevel, gameMap.eggCnt);\n    SetWindowText(hInfo, infoBuf);\n}\n\nvoid ChangeWay(int dx, int dy)\n{\n    struct SnakeNode* sn = gameMap.snake;\n    if (sn-&gt;x + dx == sn-&gt;next-&gt;x && sn-&gt;y + dy == sn-&gt;next-&gt;y)\n        ;\n    else\n        gameMap.snakedx = dx, gameMap.snakedy = dy;\n}\n\nbool Forward()\n{\n    bool ret = true;\n    if (gameMap.snakedx == 0 && gameMap.snakedy == 0)\n        return true;\n\n    int x = gameMap.snake-&gt;x;\n    int y = gameMap.snake-&gt;y;\n    x += gameMap.snakedx;\n    y += gameMap.snakedy;\n    struct SnakeNode* sn;\n\n    \/\/\u8d85\u51fa\u8fb9\u754c\n    if (x &lt; 0 || y &lt; 0 || x &gt;= HCnt || y &gt;= VCnt) {\n        ret = false;\n    } else {\n        sn = gameMap.snake;\n        while(sn != 0) {\n            if (sn-&gt;x == x && sn-&gt;y == y) {\n                ret = false; \/\/\u649e\u4e86\u81ea\u5df1\n                break;\n            }\n            sn = sn-&gt;next;\n        }\n    }\n\n    if (x == gameMap.eggx && y == gameMap.eggy) {\n        \/\/\u5403\u4e86\u86cb\n        sn = (struct SnakeNode*)malloc(sizeof(*sn));\n        sn-&gt;x = x;\n        sn-&gt;y = y;\n        sn-&gt;next = gameMap.snake;\n        gameMap.snake = sn;\n        ++gameMap.eggCnt;\n        GenEgg();\n    } else {\n        sn = (struct SnakeNode*)malloc(sizeof(*sn));\n        sn-&gt;x = x;\n        sn-&gt;y = y;\n        sn-&gt;next = gameMap.snake;\n        gameMap.snake = sn;\n        while(sn-&gt;next-&gt;next != 0)\n            sn = sn-&gt;next;\n        free(sn-&gt;next);\n        sn-&gt;next = 0;\n    }\n\n    return ret;\n}\n\nint APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmd, INT nShow)\n{\n    srand((unsigned int)GetTickCount());\n    InitCommonControls();\n    hMain = CreateWindow(TEXT(\"#32770\"), TEXT(\"\u8d2a\u98df\u86c7 by \u7a7a\u96ea\u68a6\u89c1 2013-12-16\"), WS_OVERLAPPEDWINDOW,\n        CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, hInst, 0);\n    hPic = CreateWindow(TEXT(\"Static\"), TEXT(\"\"), WS_CHILD | WS_VISIBLE | SS_BITMAP,\n        0, 0, BlockLen * HCnt, BlockLen * VCnt, hMain, 0, hInst, 0);\n    hInfo = CreateWindow(TEXT(\"Static\"), TEXT(\"\"), WS_CHILD | WS_VISIBLE,\n        20, BlockLen * VCnt, BlockLen * HCnt - 40, 30, hMain, 0, hInst, 0);\n    RECT r;\n    GetWindowRect(hMain, &r);\n    r.right = r.left + HCnt * BlockLen;\n    r.bottom = r.top + VCnt * BlockLen + 30;\n    AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);\n    MoveWindow(hMain, r.left, r.top, r.right - r.left, r.bottom - r.top, FALSE);\n    ShowWindow(hMain, nShow);\n\n    InitGameMap();\n    GenEgg();\n    GenPic();\n\n    GetAsyncKeyState(VK_UP);\n    GetAsyncKeyState(VK_DOWN);\n    GetAsyncKeyState(VK_LEFT);\n    GetAsyncKeyState(VK_RIGHT);\n\n    HANDLE hTimer = CreateWaitableTimer(0, FALSE, 0);\n    LARGE_INTEGER liDueTime;\n    liDueTime.QuadPart = -InitTimerInterval * 10000;\n    SetWaitableTimer(hTimer, &liDueTime, InitTimerInterval, 0, 0, TRUE);\n    MSG m;\n    for(;;) {\n        DWORD r = MsgWaitForMultipleObjects(1, &hTimer, FALSE, INFINITE, QS_ALLINPUT);\n\n        if (GetAsyncKeyState(VK_UP) & 1)\n            ChangeWay(0, -1);\n        else if (GetAsyncKeyState(VK_DOWN) & 1)\n            ChangeWay(0, 1);\n        else if (GetAsyncKeyState(VK_LEFT) & 1)\n            ChangeWay(-1, 0);\n        else if (GetAsyncKeyState(VK_RIGHT) & 1)\n            ChangeWay(1, 0);\n\n        if (r == WAIT_OBJECT_0) {\n            if (Forward() == false) {\n                GenPic();\n                MessageBox(hMain, TEXT(\"\u4f60\u6b7b\u4e86\"), TEXT(\"\u6b7b\u6b7b\u6b7b\u6b7b\u6b7b\"), MB_OK);\n                ReleaseGameMap();\n                InitGameMap();\n                liDueTime.QuadPart = -InitTimerInterval * 10000;\n                SetWaitableTimer(hTimer, &liDueTime, InitTimerInterval, 0, 0, TRUE);\n            }\n\n            if (gameMap.curLevel &lt;= gameMap.eggCnt \/ 10) {\n                int x = InitTimerInterval;\n                ++gameMap.curLevel;\n                int i, iend = gameMap.curLevel;\n                for (i = 0; i &lt; iend; ++i) {\n                    x *= 8;\n                    x \/= 10;\n                }\n                liDueTime.QuadPart = -x * 10000;\n                SetWaitableTimer(hTimer, &liDueTime, x, 0, 0, TRUE);\n            }\n\n            GenPic();\n        } else if (r == WAIT_OBJECT_0 + 1) {\n            bool quit = false;\n            while( PeekMessage(&m, 0, 0, 0, PM_REMOVE) != FALSE) {\n                if (m.hwnd == hMain && m.message == WM_COMMAND && m.wParam == (WPARAM)MAKEWORD(IDCANCEL, BN_CLICKED)) {\n                    quit = true;\n                    break;\n                }\n                TranslateMessage(&m);\n                DispatchMessage(&m);\n            }\n            if(quit)\n                break;\n        }\n    }\n    CloseHandle(hTimer);\n    return 0;\n}\n\n <\/pre>\n<p><\/code>\n      <\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u6211\u662f\u4e3a\u4e86\u8bc1\u660e\u201c\u8fd9\u79cd\u4e1c\u897f\u5176\u5b9e\u6211\u4e5f\u53ef\u4ee5\u5199\u5f97\u51fa\u6765\u7684\uff01\u201d\u5417\uff1f \u611f\u60f3\uff1a\u7528WM_TIMER\u5b9a\u65f6\u5b9e\u5728\u662f\u4e0d\u591f\u51c6\uff0c\u504f\u5dee\u592a\u5927\u3002\u6700\u540e &hellip; <a href=\"https:\/\/blog.sorayuki.net\/?p=363\" class=\"more-link\">\u7ee7\u7eed\u9605\u8bfb<span class=\"screen-reader-text\">\u8d2a\u98df\u86c7<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-363","post","type-post","status-publish","format-standard","hentry","category-windows"],"_links":{"self":[{"href":"https:\/\/blog.sorayuki.net\/index.php?rest_route=\/wp\/v2\/posts\/363","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.sorayuki.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.sorayuki.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.sorayuki.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.sorayuki.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=363"}],"version-history":[{"count":0,"href":"https:\/\/blog.sorayuki.net\/index.php?rest_route=\/wp\/v2\/posts\/363\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.sorayuki.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=363"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.sorayuki.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=363"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.sorayuki.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}