會有這個程式,是因為聽一位朋友說,他光是寫井字遊戲的AI就用掉近千行。
然後當時我就宣稱不用一百行,我就能做出含視窗介面、AI 和流程控制的井字遊戲。
後來當然寫出來了,事實上大概有七成都是寫 GUI 跑不掉的程式碼,其餘是遊戲流程控制,只有藍色的部分是井字遊戲的 AI。
這種程式碼純粹為了好玩,完全不值得學習。小朋友請勿模仿,叔叔是有練過的
編譯時記得要開 Win32 專案
#include <windows.h> #include <tchar.h> int AI(unsigned bb1, unsigned bb2, unsigned& mv, int d) { const unsigned link3[8] = {7, 56, 448, 73, 146, 292, 84, 273}; unsigned em = ~(bb1 | bb2) & 511u, i, u; int s = -d-1, t; for (i = 0; i < 8; ++i) if (link3[i] == (bb2 & link3[i])) return s; if (em == 0 || d == 0) return 0; for (; em && (u = em & -em); em ^= u) ((t = -AI(bb2, bb1 | u, i, d-1)) > s) && (s = t, mv = u); return s; } const TCHAR* symbol[2] = {_T("O"), _T("X")}; const TCHAR* outcome[] = {_T("You LOSE!!"), _T("Draw Game!!"), _T("@@")}; HWND hWnd, hBtn[9]; unsigned bb[2] = {0}, side = 0; LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { unsigned idx = LOWORD(wParam) - 101, mv; if (msg == WM_COMMAND && 0 <= idx && idx < 9) { if ((mv = 1u << idx) & ~(bb[0] | bb[1])) { bb[side] |= mv; SetWindowText(hBtn[idx], symbol[side]); int val = -AI(bb[side^1], bb[side], mv=0, 10); switch (mv != 0) { case 1: bb[side^1] |= mv; for (idx = 0; mv>>=1; idx++); SetWindowText(hBtn[idx], symbol[side^1]); val = AI(bb[side], bb[side^1], mv=0, 1); if (mv) break; default: MessageBox(hWnd, outcome[((val>0)-(val<0))+1], _T("Game"), MB_OK); for (int i = 0; i < 9; ++i) SetWindowText(hBtn[i], _T(" ")); if ((bb[1] = 0) || (bb[0] = (side^=1))) SetWindowText(hBtn[0], symbol[side^1]); } } } else if (msg == WM_DESTROY) { PostQuitMessage(0); } return DefWindowProc(hWnd, msg, wParam, lParam); } int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR arg, int mode) { MSG msg; WNDCLASSEX wincls = {sizeof(WNDCLASSEX), CS_HREDRAW|CS_VREDRAW, &WinProc, 0, 0, hInst, LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), (HBRUSH) (COLOR_BTNFACE+1), 0, _T("OOXX"),LoadIcon(NULL, IDI_APPLICATION)}; if (!RegisterClassEx(&wincls)) return 0; hWnd = CreateWindowEx(0, _T("OOXX"), _T("Game"), (WS_OVERLAPPEDWINDOW|WS_VISIBLE), CW_USEDEFAULT, CW_USEDEFAULT, 40*4, 40*5, HWND_DESKTOP, NULL, hInst, NULL); for (int i = 0; i < 9; ++i) { hBtn[i] = CreateWindowEx(0, _T("button"), _T(" "), BS_FLAT |WS_CHILD|WS_VISIBLE, (i/3)*40+16, (i%3)*40+16, 40, 40, hWnd, HMENU(101+i), hInst, 0); } while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }
全站熱搜