では、プログラムを見てみましょう。
リソース・スクリプトに変更はありません。
// 35702.cpp #ifndef STRICT #define STRICT #endif #include <windows.h> #include <windowsx.h> #include <stdlib.h> #include <time.h> #include "resource.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK MyDlgProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE, int); BOOL StartGame(HWND); BOOL ShowStone(HWND); int comp_take(HWND); int human_take(HWND); int judge(HWND); int no_of_0(); int ShowCompMsg(HWND, int, int); char szClassName[] = "game35702"; //ウィンドウクラス HINSTANCE hInst; int nStone[3]; //各山の石の数 char szTxt[3][8], szStone[3][32]; BOOL bSente, bOrder;//コンピュータが先手かどうか, 現在の差し手 int nMtOrder, nTakeStone;no_of_0, ShowCompMsg関数が増えました。前者は石が0である山の数を 調べ、後者はコンピュータがどの山からいくつ石を取るかをメッセージボックスで 表示する関数です。(ま、名前の通りです)
WinMain, InitApp, InitInstance, WndProc, StartGame, ShowStone, MyDlgProc の各関数に変更はありません。
int comp_take(HWND hWnd) { int mtorder, stone, i; char szBuf[256]; srand((unsigned)time(NULL)); if (no_of_0() == 0) { //どの山も0ではない //2-4-6パターンにする if (nStone[0] == 3 && nStone[1] == 4 && nStone[2] == 6) { mtorder = 0; stone = 1; nStone[0] = 2; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[1] == 5 && nStone[0] == 2 && nStone[2] == 6) { mtorder = 1; stone = 1; nStone[1] = 4; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[2] == 7 && nStone[0] == 2 && nStone[1] == 4) { mtorder = 2; stone = 1; nStone[2] = 6; ShowCompMsg(hWnd, mtorder, stone); } //1-4-5パターンにする if (nStone[0] > 1 && nStone[1] + nStone[2] == 9 && nStone[1] * nStone[2] == 20) { mtorder = 0; stone = nStone[0] - 1; nStone[0] = 1; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[1] > 4 && nStone[0] == 1 && nStone[2] == 5) { mtorder = 1; stone = nStone[1] - 4; nStone[1] = 4; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[2] > 4 && nStone[0] == 1 && nStone[1] == 5) { mtorder = 2; stone = nStone[2] - 4; nStone[2] = 4; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[2] > 5 && nStone[0] == 1 && nStone[1] == 4) { mtorder = 2; stone = nStone[2] - 4; nStone[2] = 4; ShowCompMsg(hWnd, mtorder, stone); } //1-2-3パターンにする if (nStone[0] > 1 && nStone[1] + nStone[2] == 5 && nStone[1] * nStone[2] == 6) { mtorder = 0; stone = nStone[0] - 1; nStone[0] = 1; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[0] > 2 && nStone[1] + nStone[2] == 4 && nStone[1] * nStone[2] == 3) { mtorder = 0; stone = nStone[0] - 2; nStone[0] = 2; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[0] == 3 && nStone[1] + nStone[2] == 3 && nStone[1] * nStone[2] == 2) { mtorder = 0; stone = nStone[0] - 3; nStone[0] = 3; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[1] > 1 && nStone[0] + nStone[2] == 5 && nStone[0] * nStone[2] == 6) { mtorder = 1; stone = nStone[1] - 1; nStone[1] = 1; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[1] > 2 && nStone[0] + nStone[2] == 4 && nStone[0] * nStone[2] == 3) { mtorder = 1; stone = nStone[1] - 2; nStone[1] = 2; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[1] > 3 && nStone[0] + nStone[2] == 3 && nStone[0] * nStone[2] == 2) { mtorder = 1; stone = nStone[1] - 3; nStone[1] = 3; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[2] > 1 && nStone[0] + nStone[1] == 5 && nStone[0] * nStone[1] == 6) { mtorder = 2; stone = nStone[2] - 1; nStone[2] = 1; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[2] > 2 && nStone[0] + nStone[1] == 4 && nStone[0] * nStone[1] == 3) { mtorder = 2; stone = nStone[2] - 2; nStone[2] = 2; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[2] > 3 && nStone[0] + nStone[1] == 3 && nStone[0] * nStone[1] == 2) { mtorder = 2; stone = nStone[2] - 3; nStone[2] = 3; ShowCompMsg(hWnd, mtorder, stone); } //1-1-1パターンにする if (nStone[0] == nStone[1] && nStone[0] == 1 && nStone[2] > 1) { mtorder = 2; stone = nStone[2] - 1; nStone[2] = 1; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[1] == nStone[2] && nStone[1] == 1 && nStone[0] > 1) { mtorder = 0; stone = nStone[0] - 1; nStone[0] = 1; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[0] == nStone[2] && nStone[0] == 1 && nStone[1] > 1) { mtorder = 1; stone = nStone[1] - 1; nStone[1] = 1; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[0] == nStone[1]) { mtorder = 2; stone = nStone[2]; nStone[mtorder] = 0; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[1] == nStone[2]) { mtorder = 0; stone = nStone[0]; nStone[mtorder] = 0; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[2] == nStone[0]) { mtorder = 1; stone = nStone[1]; nStone[mtorder] = 0; ShowCompMsg(hWnd, mtorder, stone); } } //0の山が1つだけである if (no_of_0() == 1) { if (nStone[0] == 0) { if (nStone[1] == 1) { mtorder = 2; stone = nStone[2]; nStone[2] = 0; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[2] == 1) { mtorder = 1; stone = nStone[1]; nStone[1] = 0; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[1] > nStone[2]) { mtorder = 1; stone = nStone[1] - nStone[2]; nStone[mtorder] -= stone; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[2] > nStone[1]) { mtorder = 2; stone = nStone[2] - nStone[1]; nStone[mtorder] -= stone; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[2] == nStone[1]){ mtorder = 1; stone = 1; nStone[mtorder] -= stone; ShowCompMsg(hWnd, mtorder, stone); } } if (nStone[1] == 0) { if (nStone[0] == 1) { mtorder = 2; stone = nStone[2]; nStone[2] = 0; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[2] == 1) { mtorder = 0; stone = nStone[0]; nStone[0] = 0; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[0] > nStone[2]) { mtorder = 0; stone = nStone[0] - nStone[2]; nStone[mtorder] -= stone; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[2] > nStone[0]) { mtorder = 2; stone = nStone[2] - nStone[0]; nStone[mtorder] -= stone; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[0] == nStone[2]) { mtorder = 2; stone = 1; nStone[mtorder] -= stone; ShowCompMsg(hWnd, mtorder, stone); } } if (nStone[2] == 0) { if (nStone[1] == 1) { mtorder = 0; stone = nStone[0]; nStone[0] = 0; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[0] == 1) { mtorder = 1; stone = nStone[1]; nStone[1] = 0; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[0] > nStone[1]) { mtorder = 0; stone = nStone[0] - nStone[1]; nStone[mtorder] -= stone; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[1] > nStone[0]) { mtorder = 1; stone = nStone[1] - nStone[0]; nStone[mtorder] -= stone; ShowCompMsg(hWnd, mtorder, stone); } if (nStone[1] == nStone[0]) { mtorder = 0; stone = 1; nStone[mtorder] -= 1; ShowCompMsg(hWnd, mtorder, stone); } } } if (no_of_0() == 2) { for (i = 0; i < 3; i++) { if (nStone[i] != 0) { stone = nStone[i] - 1; mtorder = i; nStone[i] = 1; ShowCompMsg(hWnd, mtorder, stone); } } } while (1) { mtorder = rand() % 3; if (nStone[mtorder] == 0) continue; else break; } while (1) { stone = 1; nStone[mtorder] -= stone; if (nStone[0] + nStone[1] + nStone[2] == 0) { nStone[mtorder] += stone; continue; } else { break; } } return 0; }こりゃ、ちょっと長い関数ですが、中身はC言語編第77章と 同じです。どこが違うかというと、C言語編では、コンピュータが取る石の数が決まったら gotoで関数の最後の方にあるend:に行っていましたが、今度はShowCompMsg関数を 呼び出すことにしました。結局のところGUIだろうが何だろうが、基本的な部分は大して 変わりません。
int ShowCompMsg(HWND hWnd, int mtorder, int stone) { char szBuf[256]; wsprintf(szBuf, "コンピュータは%cから%d個取りました\n", mtorder + 'A', stone); MessageBox(hWnd, szBuf, "コンピュータ", MB_OK); ShowStone(hWnd); if (judge(hWnd) == 0) { MessageBox(hWnd, "コンピュータの勝ちです", "判定", MB_OK); return -1; } bOrder = !bOrder; return 0; }コンピュータが、どの山からいくつ石を取るかを表示する関数です。 すべて前出のcomp_take関数から呼ばれます。
特に説明は不要ですね。
int no_of_0() { int no, i; no = 0; for (i = 0; i < 3; i++) { if (nStone[i] == 0) no++; } return no; }これも簡単です。山を一つ一つ調べて石のない山の数を返します。
human_take, judge関数に変更はありません。と、いうことで前章のプログラムはかなり強くなりました。あとは、対戦成績を ファイルに記録するとか、いろいろ付加機能をつけてみてください。
Update 04/Jun/2002 By Y.Kumei