リソースはできたので、後はCUIで確認したCCOINSクラスとCNIMクラスをスケルトンに実装します。
【Nim.cpp】
//////////////////////////////////////////
// Nim.cpp
//Copyright (c) 01/10/2022 by BCCSkelton
//////////////////////////////////////////
#include "Nim.h"
#include "NimProc.h"
////////////////
// WinMain関数
////////////////
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) {
//2重起動防止
if(!Nim.IsOnlyOne()) {
//ここに2重起動時の処理を書く(下記は1例)
HWND hWnd = FindWindow("MainWnd", "Nim");
if(IsIconic(hWnd))
ShowWindow(hWnd, SW_RESTORE);
SetForegroundWindow(hWnd);
return 0L;
}
//ウィンドウ登録 - Init(ClassName, hInstance, WndProc, "IDM_MAIN",
// (以下省略可)MAKEINTRESOURCE(IDI_ICON), IDC_ARROW, Brush)
Nim.Init("MainWnd", hInstance, SDIPROC, "IDM_MAIN", MAKEINTRESOURCE(IDI_ICON));
//ウィンドウ作成と表示-Create(WindowTitle, (以下省略可)Style,
// ExStyle, hParent, hMenu, x, y, w, h)
if(!Nim.Create("Nim", WS_OVERLAPPEDWINDOW, NULL, NULL, NULL,
CW_USEDEFAULT, CW_USEDEFAULT, 336, 381))
return 0L;
//メッセージループに入る
return Nim.Loop();
}
//(解説:メインプログラムなんですけど、いつも地味です。ほぼSkeltonWizard通りで二重起動防止のところだけコメントをはずしました。)
【Nim.h】
//////////////////////////////////////////
// Nim.h
// Copyright (c) 01/10/2022 by BCCSkelton
//////////////////////////////////////////
//BCCSkeltonのヘッダー-これに必要なヘッダーが入っている
#include "BCCSkelton.h"
//リソースIDのヘッダー
#include "ResNim.h"
//CNIMクラスのヘッダー
#include "CNIMW.h"
//(解説:CNIMクラスのヘッダーですが、これを入れるとbcc32ではコンパイルできなくなるので、スケルトンの動きを確認するまではコメントアウト(//)しておくことが必要です。)
/////////////////////////////////////////////////////////////////////
//CMyWndクラスをCSDIクラスから派生させ、メッセージ用の関数を宣言する
/////////////////////////////////////////////////////////////////////
class CMyWnd : public CSDI
{
public: //以下はコールバック関数マクロと関連している
//2重起動防止用のMutex用ID名称
CMyWnd(char* UName) : CSDI(UName) {}
//メンバー変数(システム)
int m_Width; //ウインドウ幅
int m_Height; //ウインドウ高さ
int m_Span; //1コマ幅、高さ
CANVAS m_cvs; //仮想ウィンドウ
//メンバー変数(ゲーム)
CNIM m_Nim; //Nim本体
int m_You; //Player(先手-1、後手-2)
int m_Type; //各種対戦のID(1-人間対乱数、2-人間対評価関数、3-人間対経験値、4-乱数対関数、5-乱数対経験値、6-関数対経験値)
int m_No; //連続対戦のゲーム数
int m_Games; //対戦の通算ゲーム数
int m_1st; //先手の勝数
int m_2nd; //後手の勝数
//(解説:ここはマニュアルで追加した部分です。最初の「(システム)」の幅、高さ、一コマ幅(高さ-正方形なので)は最小サイズ確保と描画の為の変数です。CANVASクラスも勿論描画の為です。次の「(ゲーム)」がCUIのcppプログラムにもあったゲーム用の変数ですね。)
//メニュー項目、ダイアログコントロール関連
bool OnRandom();
bool OnEval();
bool OnExp();
bool OnRvf();
bool OnRve();
bool OnFve();
bool OnExit();
bool OnInfo();
bool OnAbout();
bool OnVersion();
//(解説:ここまではメニュー項目です。)
//ウィンドウメッセージ関連
bool OnCreate(WPARAM, LPARAM);
bool OnLButtonDown(WPARAM, LPARAM);
bool OnRButtonDown(WPARAM, LPARAM);
bool OnNotify(WPARAM, LPARAM);
bool OnSize(WPARAM, LPARAM);
bool OnPaint(WPARAM, LPARAM);
bool OnMinMax(WPARAM, LPARAM);
bool OnClose(WPARAM, LPARAM);
//(解説:いつもと違うのはマウスのボタンダウンメッセージをSkeltonWizardで追加したのと、マニュアルで最小サイズメッセージ(OnMiniMax関数)を追加したことです。)
//ユーザー定義関数
void ShowCoins(); //ウィンドウにコインを表示する
void GameInit(); //ゲーム初期化関数
void PCvsMan(); //PC対人間対戦
void PCvsPC(); //PC対PC対戦
void WhenOver(); //ゲーム終了処理
void ChangeMenuStatus(bool); //メニュー、ツールバーの有無効化
//(解説:これらはげーん処理の関数です。上からGUIのコイン表示関数、ゲーム初期化関数、PC対人間対戦の関数、PC対PC対戦の関数、終了時処理関数と最後が対戦中のメニュー、ツールバーボタンの無効化関数です。)
};
////////////////////////////////////////////////////////////////////////
//派生させたCMyWndクラスのインスタンスとコールバック関数(マクロ)の作成
//主ウィンドウはダイアログと違い、コールバック関数は一つしか作れない
////////////////////////////////////////////////////////////////////////
CMyWnd Nim("Nim"); //ウィンドウクラスインスタンスの生成
BEGIN_SDIMSG(Nim) //ダイアログと違い、コールバック関数名を特定しない
//メニュー項目、ダイアログコントロール関連
ON_COMMAND(Nim, IDM_RANDOM, OnRandom())
ON_COMMAND(Nim, IDM_EVAL, OnEval())
ON_COMMAND(Nim, IDM_EXP, OnExp())
ON_COMMAND(Nim, IDM_RVF, OnRvf())
ON_COMMAND(Nim, IDM_RVE, OnRve())
ON_COMMAND(Nim, IDM_FVE, OnFve())
ON_COMMAND(Nim, IDM_EXIT, OnExit())
ON_COMMAND(Nim, IDM_INFO, OnInfo())
ON_COMMAND(Nim, IDM_ABOUT, OnAbout())
ON_COMMAND(Nim, IDM_VERSION, OnVersion())
//ウィンドウメッセージ関連
ON_CREATE(Nim)
ON_LBUTTONDOWN(Nim)
ON_RBUTTONDOWN(Nim)
ON_NOTIFY(Nim)
ON_SIZE(Nim)
ON_PAINT(Nim)
ON_(Nim, WM_GETMINMAXINFO, OnMinMax(wParam, lParam))
ON_CLOSE(Nim)
END_WNDMSG
//(解説:いつものマクロテーブルです。しつこいですが、WM_GETMINMAXINFOは手書きです。赤字で書いたBCCSkeltonで対応していないウィンドウメッセージの取り込み方(ON_(インスタンス名, メッセージ定数, 呼び先の関数と引数))も覚えてください。マクロテーブルでのウィンドウメッセージ関連の関数呼び出しには通常wParamとlParam(実体のある変数名)を忘れずに入れてください。また、クラスのメンバー関数宣言部はWPARAM、LPARAMという変数型式名で全て大文字になることに注意してください。)
///////////////////
//ツールバーの作成
///////////////////
CTBAR TBar;
///////////////////////
//ステータスバーの作成
///////////////////////
CSBAR SBar;
///////////////////////
//ビットマップハンドル
///////////////////////
HBITMAP g_hCoin;
HBITMAP g_hBlanc;
//(解説:これらは十円玉と背景のビットマップ用ハンドルです。)
////////////////////////
//CARGクラスインスタンス
////////////////////////
CARG g_arg;
//(解説:データ保存、読み込み用に使います。)
//////////////////////
//Helpファイルパス、名
//////////////////////
CSTR g_HelpFile;
//(解説:ヘルプはMicrosoft HTML Help Workshopを使っています。)
///////////////////////////////////////////
// CDLGクラスからTAKECOINSDLGクラスを派生
// 複数の同一ダイアログ変数とダイアログも作
// れるが、一つのダイアログに一つの派生ダイ
// アログクラスを作成するのが基本
///////////////////////////////////////////
class TAKECOINSDLG : public CDLG {
public:
bool OnInit(WPARAM, LPARAM);
bool OnCol(WPARAM, LPARAM);
bool OnIdok();
bool OnIdcancel();
};
//(解説:いつもと違うのはOnColです。これはOnInitで列番号を入れたドロップダウンリスト(コンボボックス)が選択された時に、取るコイン数のドロップダウンリストに個数を設定する為に必要です。)
////////////////////////////////////////////////////////////////////////////
// TAKECOINSDLGクラスダイアログ変数の生成とコールバック関数(マクロ)を定義
// 複数同一クラスのダイアログを作成することを予期してコールバック関数を明記
////////////////////////////////////////////////////////////////////////////
TAKECOINSDLG takecoinsdlg;
BEGIN_MODALDLGMSG(takecoinsdlgProc, takecoinsdlg) //第1引数がコールバック関数の名前
ON_COMMAND(takecoinsdlg, IDC_COL, OnCol(wParam, lParam))
//(解説:このIDC_COLが列番号用のドロップダウンリストです。)
ON_COMMAND(takecoinsdlg, IDOK, OnIdok())
ON_COMMAND(takecoinsdlg, IDCANCEL, OnIdok())
END_DLGMSG
///////////////////////////////////////////
// CDLGクラスからINPUTDLGクラスを派生
// 複数の同一ダイアログ変数とダイアログも作
// れるが、一つのダイアログに一つの派生ダイ
// アログクラスを作成するのが基本
///////////////////////////////////////////
class INPUTDLG : public CDLG {
public:
bool OnInit(WPARAM, LPARAM);
bool OnIdok();
bool OnIdcancel();
};
//(解説:このダイアログはMENACEからの流用です。)
////////////////////////////////////////////////////////////////////////////
// INPUTDLGクラスダイアログ変数の生成とそのコールバック関数(マクロ)を定義
// 複数同一クラスのダイアログを作成することを予期してコールバック関数を明記
////////////////////////////////////////////////////////////////////////////
INPUTDLG inputdlg;
BEGIN_MODALDLGMSG(inputdlgProc, inputdlg) //第1引数がコールバック関数の名前
ON_COMMAND(inputdlg, IDOK, OnIdok())
ON_COMMAND(inputdlg, IDCANCEL, OnIdok())
END_DLGMSG
///////////////////////////////////////////
// CDLGクラスからINFODLGクラスを派生
// 複数の同一ダイアログ変数とダイアログも作
// れるが、一つのダイアログに一つの派生ダイ
// アログクラスを作成するのが基本
///////////////////////////////////////////
class INFODLG : public CDLG {
public:
bool OnInit(WPARAM, LPARAM);
bool OnIdok();
bool OnIdcancel();
};
//(解説:このダイアログもMENACEからの流用です。)
////////////////////////////////////////////////////////////////////////////
// INFODLGクラスダイアログ変数の生成とそのコールバック関数(マクロ)を定義
// 複数同一クラスのダイアログを作成することを予期してコールバック関数を明記
////////////////////////////////////////////////////////////////////////////
INFODLG infodlg;
BEGIN_MODALDLGMSG(infodlgProc, infodlg) //第1引数がコールバック関数の名前
ON_COMMAND(infodlg, IDOK, OnIdok())
ON_COMMAND(infodlg, IDCANCEL, OnIdcancel())
END_DLGMSG
///////////////////////////////////////////
// CDLGクラスからVERSIONDLGクラスを派生
// 複数の同一ダイアログ変数とダイアログも作
// れるが、一つのダイアログに一つの派生ダイ
// アログクラスを作成するのが基本
///////////////////////////////////////////
class VERSIONDLG : public CDLG {
public:
bool OnIdok();
bool OnIdcancel();
};
//(解説:このダイアログもMENACE以前からの使い廻しです。)
////////////////////////////////////////////////////////////////////////////
// VERSIONDLGクラスダイアログ変数の生成とそのコールバック関数(マクロ)を定義
// 複数同一クラスのダイアログを作成することを予期してコールバック関数を明記
////////////////////////////////////////////////////////////////////////////
VERSIONDLG versiondlg;
BEGIN_MODALDLGMSG(versiondlgProc, versiondlg) //第1引数がコールバック関数の名前
ON_COMMAND(versiondlg, IDOK, OnIdok())
ON_COMMAND(versiondlg, IDCANCEL, OnIdcancel())
END_DLGMSG
後はNimProc.hの宣言した関数の実装とゲームの運営の説明だけですね。次回にBatchGoodの作ったバッチファイルも載せましょう。