5目並べを作成しました

# C++で簡単な五目並べをプログラムを作成してみました。
C++初心者です。C++で何かプログラムを作りたかったので、五目並べを作ってみました。
至らぬ点ばかりだとは思いますが、何卒ご容赦お願いします。
以下がソースコードです。
あくまで大まかな流れをとりあえず作りたかったので、入力チェックなどはまだ不十分です。今後改善予定です。

```C++:main.cpp
#include <iostream>
#include <string>

#include "Board.h"
#include "CommonData.h"
int main(void)
{
	Board board;
	CommonData::PlayerKind nowPlayer = CommonData::PlayerKind::Black;
			
	while (true)
	{
		bool isPutSucceed = false;
		std::string dispStr;

		while (!isPutSucceed)
		{
			// 盤面の描画
			board.Draw();

			// 勝敗判定
			CommonData::PlayerKind winPlayer = board.Judge();
			if (winPlayer != CommonData::PlayerKind::None)
			{
				if (winPlayer == CommonData::PlayerKind::Black) {
					dispStr = "黒";
				}
				else {
					dispStr = "白";
				}

				// ゲーム終了
				std::cout << dispStr << "の勝ち！やったね！！！";
				std::rewind(stdin);
				std::getchar();
				return 0;
			}

			if (nowPlayer == CommonData::PlayerKind::Black) {
				dispStr = "黒";
			}
			else {
				dispStr = "白";
			}

			// 置く石の位置の入力
			std::cout << dispStr << "の手番です。横・縦の順に入力してください。" << std::endl;
			int x, y;
			std::cout << "横:";
			std::cin >> x;
			std::cout << "縦:";
			std::cin >> y;

			isPutSucceed = board.PutStone(nowPlayer, x, y);
			if(!isPutSucceed)
			{
				std::cout << "正しい場所に置いてください！" << std::endl;
				std::rewind(stdin);
				std::getchar();
				std::system("cls");
			}
		}

		// 番の変更
		if (nowPlayer == CommonData::PlayerKind::Black) {
			nowPlayer = CommonData::PlayerKind::White;
		}else {
			nowPlayer = CommonData::PlayerKind::Black;
		}
		std::system("cls");
	}
	return 0;
}
```

```C++:Board.h
#pragma once
#include <array>

#include "CommonData.h"

class Board
{
	enum JudegeKind
	{
		Tete,
		Yoko,
		Naname1,
		Naname2,
	};

public:
	Board();
	~Board();

	void Draw(void);

	bool PutStone(CommonData::PlayerKind player, int x, int y);
	CommonData::PlayerKind Judge(void);

private:
	std::array<std::array<CommonData::PlayerKind, CommonData::BoardSizeY>, CommonData::BoardSizeX> m_boardData;

	CommonData::PlayerKind JudgeBaseStone(JudegeKind judgeKind, int x, int y);

	bool IsRangeOk(int x, int y);
	bool IsPutOk(int x, int y);

};
```

```C++:Board.cpp
#include <string>
#include <iostream>

#include "Board.h"


namespace
{
	const char* NumberStr[] = {"１", "２", "３", "４", "５", "６", "７", "８", "９" };
}


Board::Board()
{
	// 配列の初期化
	for (int y = 0; y < CommonData::BoardSizeY; y++)
	{
		for (int x = 0; x < CommonData::BoardSizeX; x++)
		{
			m_boardData[y][x] = CommonData::PlayerKind::None;
		}
	}
}

Board::~Board()
{
}


// 盤の描画
void Board::Draw()
{
	// 一番上
	std::string drawStr = "　";
	for (int i = 0; i < CommonData::BoardSizeX; i++)
	{
		drawStr = drawStr + NumberStr[i];
	}
	std::cout << drawStr << std::endl;

	for (int y = 0; y < CommonData::BoardSizeY; y++)
	{
		drawStr = NumberStr[y];
		for (int x = 0; x < CommonData::BoardSizeX; x++)
		{
			switch (m_boardData[y][x])
			{
			case CommonData::PlayerKind::None:
				drawStr = drawStr + "・";
				break;

			case CommonData::PlayerKind::White:
				drawStr = drawStr + "●";
				break;

			case CommonData::PlayerKind::Black:
				drawStr = drawStr + "○";
				break;
			}
		}
		std::cout << drawStr << std::endl;
	}

}


// 石を置く
bool Board::PutStone(CommonData::PlayerKind player, int x, int y)
{
	if (IsPutOk(x, y))
	{
		m_boardData[y - 1][x - 1] = player;
		return true;
	}
	else {
		return false;
	}
}



// 勝敗の判定
CommonData::PlayerKind Board::Judge(void)
{
	// すべてのマスごとに、5つ並んでいるか判定を行う
	for (int y = 0; y < CommonData::BoardSizeY; y++)
	{
		for (int x = 0; x < CommonData::BoardSizeX; x++)
		{
			CommonData::PlayerKind playerResult;

			// 縦の判定
			playerResult = JudgeBaseStone(JudegeKind::Tete, x, y);
			if (playerResult != CommonData::PlayerKind::None) {
				return playerResult;
			}

			// 横の判定
			playerResult = JudgeBaseStone(JudegeKind::Yoko, x, y);
			if (playerResult != CommonData::PlayerKind::None) {
				return playerResult;
			}

			// 斜めの判定(左上→右下)
			playerResult = JudgeBaseStone(JudegeKind::Naname1, x, y);
			if (playerResult != CommonData::PlayerKind::None) {
				return playerResult;
			}

			// 斜めの判定(右上→左下）
			playerResult = JudgeBaseStone(JudegeKind::Naname2, x, y);
			if (playerResult != CommonData::PlayerKind::None) {
				return playerResult;
			}
		}
	}

	return CommonData::PlayerKind::None;
}

// 基点となる石から5つならんでいるか判定する
CommonData::PlayerKind Board::JudgeBaseStone(JudegeKind judgeKind, int x, int y)
{
	CommonData::PlayerKind basePlayerKind;

	// 5回ループ
	for (int i = 0; i < 5; i++)
	{
		// 基点の色を保存しておく
		if (i == 0) {
			basePlayerKind = m_boardData[y][x];
		}

		int searchX;
		int searchY;
		switch (judgeKind)
		{
		case JudegeKind::Tete:
			searchX = x;
			searchY = y + i;
			break;

		case JudegeKind::Yoko:
			searchX = x + i;
			searchY = y;
			break;

		case JudegeKind::Naname1:
			searchX = x + i;
			searchY = y + i;
			break;

		case JudegeKind::Naname2:
			searchX = x - i;
			searchY = y + i;
			break;
		}
	

		if (IsRangeOk(searchX, searchY))
		{
			if (m_boardData[searchY][searchX] != basePlayerKind)
			{
				// 5つ並んでいない
				return CommonData::PlayerKind::None;
			}
		}
		else
		{
			// 範囲外のときはNG
			return CommonData::PlayerKind::None;
		}
	}

	// 5つならんだ駒を返す
	return basePlayerKind;
}



// 盤の範囲内か判定を行う
bool Board::IsRangeOk(int x, int y)
{
	if (x >= 0 && x < CommonData::BoardSizeX &&
		y >= 0 && y < CommonData::BoardSizeX)
	{
		return true;
	}
	return false;
}

// 盤に駒が置けるかの判定を行う
bool Board::IsPutOk(int x, int y)
{
	if (!IsRangeOk(x-1, y-1)) {
		return false;
	}

	if (m_boardData[y-1][x-1] != CommonData::PlayerKind::None) {
		return false;
	}

	return true;
}
```

```C++:CommonData.h
#pragma once

namespace CommonData
{
	const int BoardSizeX = 9;
	const int BoardSizeY = 9;

	enum PlayerKind
	{
		None,
		White,
		Black,
	};
}
```

## 実際の画面
![新しいビットマップ イメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639022/e5003478-8730-c567-e4d3-b7f6799e54b5.jpeg)
上記のような画面が表示されます
○ … 黒
● … 白　です（コンソールだと色が反転するので…）
横・縦の順に入力します。
縦・横・斜めのどれかに5つ揃えると、終わりです。

それだけです。


## 開発環境
- Visual Studio 2017
- Windows 7

## 意識したポイント
- なるべくマジックナンバーを使わない。
    - 描画する"○""●"やJudgeBaseStone関数のfor文の中の5(5個分石が並んでいるか判定の意味)などは、多分変更が無いのと、１箇所だけなので、とりあえず直接書いています。
- なるべくC++っぽく書く。
    - 配列などは、 std::array　を使うことにした。（std::vectorとどちらを使うか悩んだが、可変長である必要がないのでarrayにしました）
    - #defineは使用せず、constやenumを使用する

## 今後改善したい点
- 5個並べる判定の部分は現在かなり~~ゴミ~~宜しくないので、アルゴリズム改善したい。
- Player vs Player しかできない為、Comとの対戦できるようにしたい。