質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

解決済

[Unity]ボードゲームにおける詰み(駒を置けない状態)の判断方法について意見を聞きたい

yuki_pooh117
yuki_pooh117

総合スコア16

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

2回答

0リアクション

3クリップ

315閲覧

投稿2019/01/09 10:36

前提・実現したいこと

現在Unityを使ってBlokusというボードゲームを製作しております。
Blokusというゲームについて

ゲーム画面
盤面、盤面上のピースはタイルマップによって描画されています。画像右側の手持ちのピースはスプライトによって描画されています。画像の通り、手持ちのピースをドラッグして盤面にゲームルール(同じ色の斜めにしか置けずとなりに同じ色があったら置けない)の通りに設置するところまでは実装できました。
ここで本題ですが、あるプレイヤーの番になったときに盤面でこれ以上置けるところがない場合、そのプレイヤーのターンを強制的にパスさせることや、置ける場所がないためゲーム終了、といった具合に詰みの状態の判定方法がこの先必須となっております。ただ、21個のピースはすべて形が違く、回転もできるように実装したので、恥ずかしながら詰みの判定の実装方法がよくわからず困っております。実装の方針やアイデアなどをご教授いただければ幸いです。

発生している問題・エラーメッセージ

詰みの状態の判定方法を知りたい

現在実装しているピース設置時の判定

C#

public void onDragEnd() { Debug.Log("EndDrag"); if (isPutable()) { Debug.Log("Putable!"); switch (gameManager_Script.turn) { case "red": drawTile = redTile; break; case "blue": drawTile = blueTile; break; case "green": drawTile = greenTile; break; case "yellow": drawTile = yellowTile; break; } for (int i = 0; i < this.transform.childCount; i++) //親オブジェクトが持っている子オブジェクトの数 回 { position = this.transform.GetChild(i).gameObject.transform.position; //子オブジェクトのポジションを代入 //position = transform.localPosition; //このスクリプトがアタッチされたオブジェクトのローカル座標 Vector3Int cellPos = tileManager.tilemap.WorldToCell(position); //positionと被っているタイルのベクトル取得 tileManager.drawTile(cellPos, drawTile); //tileManager.csのメソッド //Destroy(this.gameObject); //gameobject削除 } gameObject.SetActive(false); switch (gameManager_Script.turn) { case "red": redPlayer_Script.SetIsUsed(GetNumberOfArray(), true); gameManager_Script.turn = "blue"; break; case "blue": bluePlayer_Script.SetIsUsed(GetNumberOfArray(), true); gameManager_Script.turn = "green"; break; case "green": greenPlayer_Script.SetIsUsed(GetNumberOfArray(), true); gameManager_Script.turn = "yellow"; break; case "yellow": yellowPlayer_Script.SetIsUsed(GetNumberOfArray(), true); gameManager_Script.turn = "red"; break; } gameManager_Script.turnChanged = true; }else //置けなかったら { this.transform.position = gameManager_Script.prefabPos[GetNumberOfArray()] + tileManager.tilemap.transform.position; } uiManager_Script.rotateRightBtn.gameObject.SetActive(false); uiManager_Script.rotateLeftBtn.gameObject.SetActive(false); } public bool isPutable() { int childAmount = this.transform.childCount; int decider = childAmount; Vector3Int[] positions = new Vector3Int[childAmount]; for(int i = 0; i < childAmount; i++) { position = this.transform.GetChild(i).gameObject.transform.position; //子オブジェクトのポジションを代入 positions[i] = tileManager.tilemap.WorldToCell(position); //positionと被っているタイルのベクトルを配列に格納 } for(int i = 0; i < childAmount; i++) { if (isPutbableChecker(positions[i]) == true) { decider -= 1; } //一つ一つのタイルについて回りを調べ //おけるようならchildAmount - 1 をしていく //最終的にchildAmountが0になったらtrueをreturnする } if(decider == 0 && isSlantingSame == true) { Debug.Log(isSlantingSame); isSlantingSame = false; return true; } return false; } public bool isPutbableChecker(Vector3Int pos) //一つのタイルについておくことができるかを確認 第一引数:おこうとしているタイルのpos { if (tileManager.tilemap.GetSprite(pos) == sprite_background) //posの位置のタイルのスプライトが背景のだったら { Debug.Log("背景だった"); if(tileManager.tilemap.GetSprite(pos + up) != this.transform.GetChild(0).gameObject.GetComponent<SpriteRenderer>().sprite //posの一つ上のタイルがおこうとしているタイルと違うなら && tileManager.tilemap.GetSprite(pos + down) != this.transform.GetChild(0).gameObject.GetComponent<SpriteRenderer>().sprite && tileManager.tilemap.GetSprite(pos + right) != this.transform.GetChild(0).gameObject.GetComponent<SpriteRenderer>().sprite && tileManager.tilemap.GetSprite(pos + left) != this.transform.GetChild(0).gameObject.GetComponent<SpriteRenderer>().sprite ) //上下左右に同じスプライトのタイルがなかったら進む { Debug.Log("隣に同じタイルはなかった"); if(tileManager.tilemap.GetSprite(pos + up + right) == this.transform.GetChild(0).gameObject.GetComponent<SpriteRenderer>().sprite || tileManager.tilemap.GetSprite(pos + up + left) == this.transform.GetChild(0).gameObject.GetComponent<SpriteRenderer>().sprite || tileManager.tilemap.GetSprite(pos + down + right) == this.transform.GetChild(0).gameObject.GetComponent<SpriteRenderer>().sprite || tileManager.tilemap.GetSprite(pos + down + left) == this.transform.GetChild(0).gameObject.GetComponent<SpriteRenderer>().sprite ) //ななめにあるスプライトが同じなら進む { Debug.Log("斜めに同じスプライトがあった"); isSlantingSame = true; } return true; //斜めは関係なしに上下左右に同じスプライトがないところまで進めたらtrueを返す } } return false; //条件を満たさなかった }

試したこと

パスするボタンを設置してユーザーにパスさせるということも考えましたが、それでは、パソコンでやるメリットが減ってしまったり、これから先敵AIを作成する際に詰まると思いやめました。

補足情報(FW/ツールのバージョンなど)

Unityのバージョンは2018.3.0f2です。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

papinianus

2019/01/09 10:48

ルールを伺います。図では盤外に緑しかないのですが、プレイヤーは任意の形の任意の色のブロックを置けるのですか?それとも予め手持ちのブロックが決まっていますか?
yuki_pooh117

2019/01/09 10:59

質問ありがとうございます。あらかじめ手持ちのブロックは決まっています。ブロックの種類は質問の中で載せたリンク先にございます。ゲームスタート時に最初のプレイヤー(赤、青、緑、黄色のどれか)をランダムで決め、そこからは時計回りで順番で置いていきます。ブロックを置くことができたら次のプレイヤーの番になるようになっています。プレイヤーごとに使ったブロックの情報が記録されており、各プレイヤーが21個のブロックを使えるようになっています。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。