コード:  
#include "DxLib.h"		// DxLib
#include <iostream>		// cerr
#include <array>		// array
#include <vector>		// vector
#include <functional>	// function
#include <memory>		// unique_ptr
#include <crtdbg.h>		// _CrtSetDbgFlag
// DXライブラリ簡易ラップクラス
struct DxLibApp final
{
	DxLibApp(const char* pWindowText = nullptr) try
		: windowWidth_(384)
		, windowHeight_(384)
		, colorBitDepth_(32)
	{
		if (pWindowText != nullptr){
			DxLib::SetWindowText(pWindowText);
		}
		SetGraphMode(windowWidth_, windowHeight_, colorBitDepth_);
		ChangeWindowMode(TRUE);
		if (DxLib_Init() == -1){
			throw "DXライブラリの初期化に失敗しました。";
		}
		SetDrawScreen(DX_SCREEN_BACK);
	}
	catch (char* errStr) {
		std::cerr << errStr << std::endl;
	}
	~DxLibApp(){
		DxLib_End();
	}
	static bool ProcessLoop(){
		return (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0);
	}
	int windowWidth_;       // ウィンドウ横幅
	int windowHeight_;      // ウィンドウ縦幅
	int colorBitDepth_;     // カラービット数
};
// 簡易入力クラス
struct InputKey final
{
	InputKey()
		: keyBuffer_()
		, backKeyBuffer_()
	{}
	~InputKey(){}
	inline int Update() {
		std::copy(keyBuffer_.begin(), keyBuffer_.end(), backKeyBuffer_.begin());
		return GetHitKeyStateAll(&keyBuffer_.front());
	}
	inline bool IsPress(const int keyCode) const {
		return keyBuffer_[keyCode] ? true : false;
	}
	inline bool IsDown(const int keyCode) const {
		return (keyBuffer_[keyCode] && !backKeyBuffer_[keyCode]);
	}
	inline bool IsUp(const int keyCode) const {
		return (!keyBuffer_[keyCode] && backKeyBuffer_[keyCode]);
	}
private:
	typedef std::array<char, 256> KeyStateBuffer;
	KeyStateBuffer  keyBuffer_;
	KeyStateBuffer  backKeyBuffer_;
};
// 色定義
struct Color final
{
	// Color型の内容
	union {
		unsigned long value;
		std::array<unsigned char, 4> d;
		struct {
			unsigned char b;
			unsigned char g;
			unsigned char r;
			unsigned char a;
		};
	};
	// コンパイル時定数
	template <unsigned char r, unsigned char g, unsigned char b, unsigned char a = 255>
	struct GetColor_RGBA final {
		enum : unsigned long {
			value = static_cast<unsigned long>(((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff))
		};
	};
	static const unsigned int White = GetColor_RGBA<255, 255, 255>::value;
	// アサート
	static_assert(sizeof(unsigned long) == (sizeof(unsigned char) * 4), "Color型が正常に動作しない環境です。");
};
// グローバル変数
static DxLibApp app("シーン変更");
static InputKey inputKey;
// シーン列挙
enum eScene : unsigned int
{
	Scene_Top,		// トップ画面
	Scene_Game,		// ゲーム画面
	Scene_Count		// シーン数
};
// Taskインターフェース
struct ITask {
	enum CommonResult : int
	{
		Result_OK = 0,
		Result_Faile = -1
	};
	virtual int Init() = 0;	// 初期処理
	virtual int End() = 0;	// 終了処理
	virtual int Update() = 0;	// 更新処理
	virtual int Draw() = 0;	// 描画処理
};
// Sceneインターフェース
struct IScene : public ITask
{
	IScene(){}
	virtual ~IScene(){}
	virtual void ChangeScene(eScene scene) = 0;
};
// Sceneアブストラクト
// (規定の動作を実装するクラス 必要に応じて継承して使う)
struct BaseScene : public IScene
{
	BaseScene(){}
	virtual ~BaseScene(){}
	virtual int Init() override {
		return CommonResult::Result_OK;
	}
	virtual int End() override {
		return CommonResult::Result_OK;
	}
};
// シーンコントローラ
struct SceneController final : public IScene
{
	SceneController()
		: sceneIndex_(0)
		, sceneArrayList_()
	{}
	~SceneController(){}
	// Topシーン
	// (※ インナーが嫌だったら、適当にファイル分割して外に出す)
	struct TopScene final : public IScene
	{
		TopScene()
			: pSceneController_(nullptr)
		{}
		TopScene(SceneController* pSceneController)
			: pSceneController_(pSceneController)
		{}
		~TopScene(){}
		int Init() override {
			return CommonResult::Result_OK;
		}
		int End() override {
			return CommonResult::Result_OK;
		}
		int Update() override {
			if (inputKey.IsDown(KEY_INPUT_Z)){
				this->ChangeScene(eScene::Scene_Game);
			}
			return CommonResult::Result_OK;
		}
		int Draw() override {
			DrawString(0, 0, "トップシーン\n(Zキーでゲームシーンに変更)", Color::White);
			return CommonResult::Result_OK;
		}
		void ChangeScene(eScene scene) override {
			pSceneController_->ChangeScene(scene);
		}
	private:
		SceneController*    pSceneController_;
	};
	// ゲームシーン
	// (※ インナーが嫌だったら、適当にファイル分割して外に出す)
	struct GameScene final : public IScene
	{
		GameScene()
			: GameScene(nullptr)
		{}
		GameScene(SceneController* pSceneController)
			: pSceneController_(pSceneController)
			, board()
			, msg()
			, msg_wait()
			, think({{
				std::bind(&GameScene::think1, this, std::placeholders::_1),
				std::bind(&GameScene::think2, this, std::placeholders::_1)
			}})
			, pieces()
			, back()
			, status(2)
			, turn(1)
		{
		}
		~GameScene(){}
		int Init() override {
			DxLib::LoadDivGraph("piece.png", 2, 2, 1, 48, 48, &pieces.front());
			back = DxLib::LoadGraph("back.png");
			board[3][3] = board[4][4] = 1;
			board[4][3] = board[3][4] = 2;
			setMsg(turn, 0);
			return CommonResult::Result_OK;
		}
		int End() override {
			DxLib::InitGraph();
			return CommonResult::Result_OK;
		}
		int Update() override {
			if (inputKey.IsDown(KEY_INPUT_Z)){
				this->ChangeScene(eScene::Scene_Top);
			}
			switch (status) {
			case 1:
				if (isPass(turn)) {
					setMsg(turn, 1);
					status = 3;
				}
				else {
					if (think[turn - 1](turn)) {
						turn = 3 - turn; status = 2;
						setMsg(turn, 0);
					}
				}
				if (checkResult()) status = 4;
				break;
			case 2:
				if (msg_wait > 0) msg_wait--;
				else status = 1;
				break;
			case 3:
				if (msg_wait > 0) msg_wait--;
				else {
					turn = 3 - turn; status = 2;
					setMsg(turn, 0);
				}
				break;
			}
			return CommonResult::Result_OK;
		}
		int Draw() override {
			DrawGraph(0, 0, back, FALSE);
			for (int y = 0; y < 8; y++) for (int x = 0; x < 8; x++) {
				if (board[y][x]) DrawGraph(x * 48, y * 48, pieces[board[y][x] - 1], TRUE);
			}
			if (status > 1) {
				int mw = DxLib::GetDrawStringWidth(msg.c_str(), msg.size());
				DxLib::DrawBox(192 - mw / 2 - 30, 172, 192 + mw / 2 + 30, 208, Color::GetColor_RGBA<200, 180, 150>::value, TRUE);
				DrawString(192 - mw / 2, 182, msg.c_str(), Color::White);
			}
			return CommonResult::Result_OK;
		}
		void ChangeScene(eScene scene) override {
			pSceneController_->ChangeScene(scene);
		}
	private:
		// 指定した位置にコマを置く
		int putPiece(int x, int y, int turn, bool put_flag) {
			int sum = 0;
			if (board[y][x] > 0) return 0;
			for (int dy = -1; dy <= 1; dy++) for (int dx = -1; dx <= 1; dx++) {
				int wx[8], wy[8];
				for (int wn = 0;; wn++) {
					int kx = x + dx * (wn + 1); int ky = y + dy * (wn + 1);
					if (kx < 0 || kx > 7 || ky < 0 || ky > 7 || board[ky][kx] == 0) break;
					if (board[ky][kx] == turn) {
						if (put_flag) for (int i = 0; i < wn; i++) board[wy[i]][wx[i]] = turn;
						sum += wn;
						break;
					}
					wx[wn] = kx; wy[wn] = ky;
				}
			}
			if (sum > 0 && put_flag) board[y][x] = turn;
			return sum;
		}
		// パスチェック
		bool isPass(int turn) {
			for (int y = 0; y < 8; y++) for (int x = 0; x < 8; x++) {
				if (putPiece(x, y, turn, false)) return false;
			}
			return true;
		}
		// 思考ルーチン1 プレイヤー
		bool think1(int turn) {
			static bool mouse_flag = false;
			if (DxLib::GetMouseInput() & MOUSE_INPUT_LEFT) {
				if (!mouse_flag) {
					mouse_flag = true;
					int mx, my;
					DxLib::GetMousePoint(&mx, &my);
					if (putPiece(mx / 48, my / 48, turn, true)) return true;
				}
			}
			else mouse_flag = false;
			return false;
		}
		// 思考ルーチン2 最も多く取れるところに置く
		bool think2(int turn) {
			int max = 0, wx, wy;
			for (int y = 0; y < 8; y++) for (int x = 0; x < 8; x++) {
				int num = putPiece(x, y, turn, false);
				if (max < num || (max == num && GetRand(1) == 0)) {
					max = num; wx = x; wy = y;
				}
			}
			putPiece(wx, wy, turn, true);
			return true;
		}
		// 思考ルーチン3 優先順位の高いところに置く
		bool think3(int turn) {
			static const int priority[8][8] = {
				{ 0, 6, 2, 1, 1, 2, 6, 0 },
				{ 6, 6, 5, 4, 4, 5, 6, 6 },
				{ 2, 5, 2, 3, 3, 2, 5, 2 },
				{ 1, 4, 3, 3, 3, 3, 4, 1 },
				{ 1, 4, 3, 3, 3, 3, 4, 1 },
				{ 2, 5, 2, 3, 3, 2, 5, 2 },
				{ 6, 6, 5, 4, 4, 5, 6, 6 },
				{ 0, 6, 2, 1, 1, 2, 6, 0 },
			};
			int max = 0, wx, wy;
			for (int p = 0; p <= 6 && max == 0; p++) {
				for (int y = 0; y < 8; y++) for (int x = 0; x < 8; x++) {
					if (priority[y][x] != p) continue;
					int num = putPiece(x, y, turn, false);
					if (max < num || (max == num && GetRand(1) == 0)) {
						max = num; wx = x; wy = y;
					}
				}
			}
			putPiece(wx, wy, turn, true);
			return true;
		}
		// メッセージセット
		// turn ... 1:BLACK 2:WHITE 3:DRAW
		// type ... 0:TURN 1:PASS 2:WIN!
		void setMsg(int turn, int type) {
			std::string turn_str[] = { "黒", "白", "DRAW" };
			std::string type_str[] = { "ターン", "パス", "勝利!" };
			msg = turn_str[turn - 1];
			if (turn != 3) msg += " " + type_str[type];
			msg_wait = 50;
		}
		// 勝敗チェック
		int checkResult() {
			int pnum[2] = {};
			int result = 0;
			for (int y = 0; y < 8; y++) for (int x = 0; x < 8; x++) {
				if (board[y][x] > 0) pnum[board[y][x] - 1]++;
			}
			if (isPass(1) && isPass(2)) {
				if (pnum[0] > pnum[1]) result = 1;
				else if (pnum[0] < pnum[1]) result = 2;
				else result = 3;
			}
			if (result) setMsg(result, 2);
			return result;
		}
	private:
		SceneController*	pSceneController_;
		template <unsigned int size>
		struct Board {
			typedef std::array<std::array<int, size>, size> Type;
		};
		Board<8>::Type	board;		// 盤のデータ(0:なし 1:黒コマ 2:白コマ)
		std::string		msg;
		int				msg_wait;
		std::array<std::function<bool(int)>, 2> think;
		std::array<int, 2> pieces;
		int back;
		int status;				// 1:プレイ中 2:TURNメッセージ中 3:パスメッセージ中 4:終了
		int turn;				// 1:黒ターン 2:白ターン
	};
	int Init() override
	{
		// シーン登録
		sceneArrayList_.clear();
		sceneArrayList_.emplace_back(new (std::nothrow) TopScene(this));
		sceneArrayList_.emplace_back(new (std::nothrow) GameScene(this));
		// シーンの作成に失敗していたらfalseを戻す
		for (auto it = sceneArrayList_.begin(); it != sceneArrayList_.end(); ++it) {
			if (!(*it)){
				return CommonResult::Result_Faile;
			}
		}
		sceneIndex_ = eScene::Scene_Top;
		return sceneArrayList_[sceneIndex_]->Init();
	}
	int End() override {
		return sceneArrayList_[sceneIndex_]->End();
	}
	int Update() override {
		return sceneArrayList_[sceneIndex_]->Update();
	}
	int Draw() override {
		return sceneArrayList_[sceneIndex_]->Draw();
	}
	void ChangeScene(eScene scene) {
		// 現在のシーンを終了し、変更後のシーンの初期化
		sceneArrayList_[sceneIndex_]->End();
		sceneIndex_ = scene;
		sceneArrayList_[sceneIndex_]->Init();
	}
private:
	unsigned int    sceneIndex_;
	std::vector<std::unique_ptr<IScene>>    sceneArrayList_;
};
// エントリーポイント
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	// メモリリーク検出
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
	SceneController sceneController;
	if (sceneController.Init() != ITask::CommonResult::Result_OK){
		return -1;
	}
	while (DxLibApp::ProcessLoop() && inputKey.Update() == 0)
	{
		sceneController.Update();
		sceneController.Draw();
	}
	if (sceneController.End() != ITask::CommonResult::Result_OK){
		return -1;
	}
	return 0;
}