Skip to content

Instantly share code, notes, and snippets.

@mak1a
Last active October 21, 2020 11:27
Show Gist options
  • Save mak1a/5b00be1dd7aadc903dd154d76d277803 to your computer and use it in GitHub Desktop.
Save mak1a/5b00be1dd7aadc903dd154d76d277803 to your computer and use it in GitHub Desktop.
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
/// <summary>
/// マスの状態
/// </summary>
enum class CellState {
None, // 未入力
Maru, // 丸
Batsu // バツ
};
/// <summary>
/// 手番
/// </summary>
enum class Turn {
First, // 先攻
Second // 後攻
};
/// <summary>
/// 一列が同じStateになっているか
/// </summary>
/// <param name=state1_></param>
/// <param name=state2_></param>
/// <param name=state3_></param>
/// <returns>一列が同じStateになっているか</returns>
bool CheckLine(const CellState& state1_, const CellState& state2_, const CellState& state3_) {
if (state1_ == CellState::None || state2_ == CellState::None || state3_ == CellState::None) {
return false;
}
return (state1_ == state2_ && state2_ == state3_);
}
void Main() {
// ウィンドウのタイトルを設定する
Window::SetTitle(U"○×ゲーム");
// 背景を水色にする
Scene::SetBackground(ColorF(0.8, 0.9, 1.0));
// 1マスのサイズ
constexpr int masuSize = 150;
// マス目を表示する際の場所の指標
const Rect ban(Arg::center(Scene::Center()), masuSize * 3);
// 9つのマスの配列
Array<Rect> masuArray;
for (int y : step(3)) {
for (int x : step(3)) {
masuArray << Rect(ban.tl().x + x * masuSize, ban.tl().y + y * masuSize, masuSize);
}
}
// masuArrayを2次元配列に変換
const Grid<Rect> masuData(3, 3, masuArray);
// マスの情報
// masuDataの要素数に対応している
Grid<CellState> masuInfo(3, 3);
// 現在の手番
Turn currentTurn = Turn::First;
// 1ゲームが終了したか
bool isEnd = false;
// ループ
while (System::Update()) {
// マス目の描画
// カーソルが重なっていたら、薄く黄色にする
for (const auto& rect : masuData) {
rect.draw(Palette::White).drawFrame(5, Palette::Black);
if (rect.mouseOver()) {
rect.draw(ColorF(Palette::Yellow, 0.5));
}
}
// マスの情報から、○や×を描画する
for (int y : step(3)) {
for (int x : step(3)) {
// ○の描画
if (masuInfo[y][x] == CellState::Maru) {
Circle(masuData[y][x].center(), masuSize * 0.4).drawFrame(5, Palette::Black);
}
// ×の描画
if (masuInfo[y][x] == CellState::Batsu) {
Shape2D::Cross(masuSize * 0.4, 5, masuData[y][x].center()).draw(Palette::Black);
}
}
}
// 縦3行を調べる
// trueが返ったら赤線を引く
for (int y : step(3)) {
if (CheckLine(masuInfo[y][0], masuInfo[y][1], masuInfo[y][2])) {
Line(masuData[y][0].center(), masuData[y][2].center()).stretched(30).draw(4, ColorF(Palette::Red, 0.6));
isEnd = true;
}
}
// 横3列を調べる
// trueが返ったら赤線を引く
for (int x : step(3)) {
if (CheckLine(masuInfo[0][x], masuInfo[1][x], masuInfo[2][x])) {
Line(masuData[0][x].center(), masuData[2][x].center()).stretched(30).draw(4, ColorF(Palette::Red, 0.6));
isEnd = true;
}
}
// 斜め(左上から右下)
// trueが返ったら赤線を引く
if (CheckLine(masuInfo[0][0], masuInfo[1][1], masuInfo[2][2])) {
Line(masuData[0][0].center(), masuData[2][2].center()).stretched(30).draw(4, ColorF(Palette::Red, 0.6));
isEnd = true;
}
// 斜め(右上から左下)
// trueが返ったら赤線を引く
if (CheckLine(masuInfo[2][0], masuInfo[1][1], masuInfo[0][2])) {
Line(masuData[2][0].center(), masuData[0][2].center()).stretched(30).draw(4, ColorF(Palette::Red, 0.6));
isEnd = true;
}
// ゲームが終了している場合
if (isEnd) {
// ボタンを押したか
if (SimpleGUI::Button(U"Retry", Scene::CenterF().movedBy(-100, 250), 200)) {
// マスの情報の配列を全て「None」に変更する
masuInfo.fill(CellState::None);
// 手番を先攻に戻す
currentTurn = Turn::First;
isEnd = false;
}
// While文の中の処理なので、
// returnではなくcontinue
continue;
}
isEnd = true;
// マスをクリックしたら手番によって変更する
for (int y : step(3)) {
for (int x : step(3)) {
// マスの状態が「None」ではなかったら早期リターン
// for文の中の処理なのでreturnではなくcontinue
if (masuInfo[y][x] != CellState::None) {
continue;
}
isEnd = false;
// マスをクリックしたら、状態を変更する
// 手番も変更する
if (masuData[y][x].leftClicked()) {
masuInfo[y][x] = (currentTurn == Turn::First) ? CellState::Maru : CellState::Batsu;
currentTurn = (currentTurn == Turn::First) ? Turn::Second : Turn::First;
}
}
}
}
}
//
// = お役立ちリンク =
//
// OpenSiv3D リファレンス
// https://siv3d.github.io/ja-jp/
//
// チュートリアル
// https://siv3d.github.io/ja-jp/tutorial/basic/
//
// よくある間違い
// https://siv3d.github.io/ja-jp/articles/mistakes/
//
// サポートについて
// https://siv3d.github.io/ja-jp/support/support/
//
// Siv3D Slack (ユーザコミュニティ) への参加
// https://siv3d.github.io/ja-jp/community/community/
//
// 新機能の提案やバグの報告
// https://github.com/Siv3D/OpenSiv3D/issues
//
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment