作った作品
皆さんこんにちは。ハニワです。今回の新入生歓迎イベントではDynamicOthelloという作品を作りました。 本当は通信を実装してオンラインで対戦できるようにしたかったのですが能力と時間が足りず結果対面でしかできない作品となってしまいました。
実装について
プログラミングやっている人向けの話になるのですがオセロのプログラムを組んだことはありますか? 組むとしたら裏返しや設置判定はどのような方法と実装したでしょうか? for分を使って実装すれば良いと思う人もいるかと思いますが僕は今回そこら辺の判定は再帰を用いて実装しました。 コード汚いのですが興味がある人は下にコードを載せておくので参考にして下さい。 再帰使った関数は下の方にあります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System.Net.Sockets;
public class MangerScript : MonoBehaviour
{
// Start is called before the first frame update
private List<List<GameObject>> box_list = new List<List<GameObject>>();
public GameObject box_prefab;
BoxScript[,] boxScript = new BoxScript[21, 21];
public GameObject go_to_title_obj;
public GameObject canvas;
public Text order_text;
public GameObject end_canvas;
public Text end_massage_text;
public AudioClip sound1,sound2,sound3;
public AudioSource audioSource;
public CameraMove cameraMove;
int H_bottom = 8;
int H_Upper = 13;
int W_bottom = 8;
int W_Upper = 13;
public int set_player = 1;//1balck,2white
int black_num = 2;
int white_num = 2;
int need_change_point = 10;
int black_point = 0;
int white_point = 2;
public Text black_num_tx;
public Text black_point_tx;
public Text white_num_tx;
public Text white_point_tx;
void Start()
{
set_player = 1;
for (int i = 0; i <= 20; i++)
{
box_list.Add(new List<GameObject>());
for(int j = 0; j <= 20; j++)
{
GameObject ListObject = GameObject.Instantiate(box_prefab) as GameObject;
box_list[i].Add(ListObject);
boxScript[i,j] = box_list[i][j].GetComponent<BoxScript>();
boxScript[i,j].mangerScript = this;
boxScript[i,j].SetPosition(i, j);
if ((H_bottom <= i && i <= H_Upper) && (W_bottom <= j && j <= W_Upper))
{
boxScript[i, j].ChangeState(1);
if (i == 10 && j == 10) boxScript[i, j].ChangePieceState(1);
else if (i == 11 && j == 11) boxScript[i, j].ChangePieceState(1);
else if (i == 10 && j == 11) boxScript[i, j].ChangePieceState(2);
else if (i == 11 && j == 10) boxScript[i, j].ChangePieceState(2);
else boxScript[i, j].ChangePieceState(0);
}
else
{
boxScript[i, j].ChangeState(0);
boxScript[i, j].ChangePieceState(0);
}
}
}
UpdateText();
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.Escape))
{
Application.Quit();
}
}
bool Search_U(int h,int w,int count)
{
if (h > H_Upper) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if(boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
if (set_player == 1)
{
black_num += count;
white_num -= count;
black_point += count;
}
else
{
black_num -= count;
white_num += count;
white_point += count;
}
return true;
}
else return false;
}
else
{
if (Search_U(h + 1, w, count + 1) == true)
{
boxScript[h, w].ChangePieceState(set_player);
return true;
}
else return false;
}
}
bool Search_D(int h, int w, int count)
{
if (h < H_bottom) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
if (set_player == 1)
{
black_num += count;
white_num -= count;
black_point += count;
}
else
{
black_num -= count;
white_num += count;
white_point += count;
}
return true;
}
else return false;
}
else
{
if (Search_D(h - 1, w, count + 1) == true)
{
boxScript[h, w].ChangePieceState(set_player);
return true;
}
else return false;
}
}
bool Search_R(int h, int w, int count)
{
if (w > W_Upper) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
if (set_player == 1)
{
black_num += count;
white_num -= count;
black_point += count;
}
else
{
black_num -= count;
white_num += count;
white_point += count;
}
return true;
}
else return false;
}
else
{
if (Search_R( h, w + 1, count + 1) == true)
{
boxScript[h, w].ChangePieceState(set_player);
return true;
}
else return false;
}
}
bool Search_L(int h, int w, int count)
{
if (w < W_bottom) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
if (set_player == 1)
{
black_num += count;
white_num -= count;
black_point += count;
}
else
{
black_num -= count;
white_num += count;
white_point += count;
}
return true;
}
else return false;
}
else
{
if (Search_L( h, w - 1, count + 1) == true)
{
boxScript[h, w].ChangePieceState(set_player);
return true;
}
else return false;
}
}
bool Search_UR(int h, int w, int count)
{
if (h > H_Upper) return false;
if (w > W_Upper) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
if (set_player == 1)
{
black_num += count;
white_num -= count;
black_point += count;
}
else
{
black_num -= count;
white_num += count;
white_point += count;
}
return true;
}
else return false;
}
else
{
if (Search_UR(h + 1, w + 1, count + 1) == true)
{
boxScript[h, w].ChangePieceState(set_player);
return true;
}
else return false;
}
}
bool Search_UL(int h, int w, int count)
{
if (h > H_Upper) return false;
if (w < W_bottom) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
if (set_player == 1)
{
black_num += count;
white_num -= count;
black_point += count;
}
else
{
black_num -= count;
white_num += count;
white_point += count;
}
return true;
}
else return false;
}
else
{
if (Search_UL(h + 1, w - 1, count + 1) == true)
{
boxScript[h, w].ChangePieceState(set_player);
return true;
}
else return false;
}
}
bool Search_DR(int h, int w, int count)
{
if (h < H_bottom) return false;
if (w > W_Upper) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
if (set_player == 1)
{
black_num += count;
white_num -= count;
black_point += count;
}
else
{
black_num -= count;
white_num += count;
white_point += count;
}
return true;
}
else return false;
}
else
{
if (Search_DR(h - 1, w + 1, count + 1) == true)
{
boxScript[h, w].ChangePieceState(set_player);
return true;
}
else return false;
}
}
bool Search_DL(int h, int w, int count)
{
if (h < H_bottom) return false;
if (w < W_bottom) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
if (set_player == 1)
{
black_num += count;
white_num -= count;
black_point += count;
}
else
{
black_num -= count;
white_num += count;
white_point += count;
}
return true;
}
else return false;
}
else
{
if (Search_DL(h - 1, w - 1, count + 1) == true)
{
boxScript[h, w].ChangePieceState(set_player);
return true;
}
else return false;
}
}
public int SetPiece(int h,int w)
{
if(set_player==3)return -1;
if(set_player==4)return -1;
if(set_player==0)return -1;
bool CanSetF = false;
if (Search_U(h + 1, w, 0) == true) CanSetF = true;
if (Search_D(h - 1, w, 0) == true) CanSetF = true;
if (Search_R(h, w + 1, 0) == true) CanSetF = true;
if (Search_L(h, w - 1, 0) == true) CanSetF = true;
if (Search_UR(h + 1, w + 1, 0) == true) CanSetF = true;
if (Search_UL(h + 1, w - 1, 0) == true) CanSetF = true;
if (Search_DR(h - 1, w + 1, 0) == true) CanSetF = true;
if (Search_DL(h - 1, w - 1, 0) == true) CanSetF = true;
if (CanSetF == true)
{
audioSource.PlayOneShot(sound1);
boxScript[h, w].ChangePieceState(set_player);
if (set_player == 1)
{
black_num++;
black_point++;
if (black_point >= need_change_point)
{
set_player = 3;
canvas.SetActive(true);
order_text.text = "Player1の人はどう拡張するかを選択して下さい。";
UpdateText();
return 2;
}
else
{
set_player = 2;
order_text.text = "Player2のターンです。";
}
}
else
{
white_num++;
white_point++;
if (white_point >= need_change_point)
{
set_player = 4;
canvas.SetActive(true);
order_text.text = "Player2の人はどう拡張するかを選択して下さい。";
UpdateText();
return 2;
}
else
{
set_player = 1;
order_text.text = "Player1のターンです。";
}
}
UpdateText();
if (CheckCanSet() == false)
{
if (set_player == 1)
{
order_text.text = "Player2のターンです。(Player1の置く場所がありませんでした。)";
set_player = 2;
}
else if (set_player == 2)
{
order_text.text = "Player1のターンです。(Player2の置く場所がありませんでした。)";
set_player = 1;
}
if (CheckCanSet() == false)
{
order_text.text = "両Playerとも置く場所がなくなりました。";
EndMassage();
}
else
{
//Debug.Log("Skip");
}
UpdateText();
}
if((H_Upper-H_bottom+1)*(W_Upper - W_bottom + 1) == white_num + black_num)
{
EndMassage();
}
UpdateText();
return 1;
}
else
{
//Debug.Log(h);
//Debug.Log(w);
}
return 0;
}
bool Check_U(int h, int w, int count)
{
if (h > H_Upper) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
return true;
}
else return false;
}
else
{
if (Check_U(h + 1, w, count + 1) == true)
{
return true;
}
else return false;
}
}
bool Check_D(int h, int w, int count)
{
if (h < H_bottom) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
return true;
}
else return false;
}
else
{
if (Check_D(h - 1, w, count + 1) == true)
{
return true;
}
else return false;
}
}
bool Check_R(int h, int w, int count)
{
if (w > W_Upper) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
return true;
}
else return false;
}
else
{
if (Check_R(h, w + 1, count + 1) == true)
{
return true;
}
else return false;
}
}
bool Check_L(int h, int w, int count)
{
if (w < W_bottom) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
return true;
}
else return false;
}
else
{
if (Check_L(h, w - 1, count + 1) == true)
{
return true;
}
else return false;
}
}
bool Check_UR(int h, int w, int count)
{
if (h > H_Upper) return false;
if (w > W_Upper) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
return true;
}
else return false;
}
else
{
if (Check_UR(h + 1, w + 1, count + 1) == true)
{
return true;
}
else return false;
}
}
bool Check_UL(int h, int w, int count)
{
if (h > H_Upper) return false;
if (w < W_bottom) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
return true;
}
else return false;
}
else
{
if (Check_UL(h + 1, w - 1, count + 1) == true)
{
return true;
}
else return false;
}
}
bool Check_DR(int h, int w, int count)
{
if (h < H_bottom) return false;
if (w > W_Upper) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
return true;
}
else return false;
}
else
{
if (Check_DR(h - 1, w + 1, count + 1) == true)
{
return true;
}
else return false;
}
}
bool Check_DL(int h, int w, int count)
{
if (h < H_bottom) return false;
if (w < W_bottom) return false;
if (boxScript[h, w].GetPieceState() == 0)
{
return false;
}
else if (boxScript[h, w].GetPieceState() == set_player)
{
if (count > 0)
{
return true;
}
else return false;
}
else
{
if (Check_DL(h - 1, w - 1, count + 1) == true)
{
return true;
}
else return false;
}
}
bool CheckCanSet()
{
for (int h = H_bottom; h <= H_Upper; h++)
{
for (int w = W_bottom; w <= W_Upper; w++)
{
if (boxScript[h, w].GetPieceState() == 0)
{
if (Check_U(h + 1, w, 0) == true) return true;
if (Check_D(h - 1, w, 0) == true) return true;
if (Check_R(h, w + 1, 0) == true) return true;
if (Check_L(h, w - 1, 0) == true) return true;
if (Check_UR(h + 1, w + 1, 0) == true) return true;
if (Check_UL(h + 1, w - 1, 0) == true) return true;
if (Check_DR(h - 1, w + 1, 0) == true) return true;
if (Check_DL(h - 1, w - 1, 0) == true) return true;
}
}
}
return false;
}
void UpdateText()
{
black_num_tx.text = black_num.ToString();
white_num_tx.text = white_num.ToString();
black_point_tx.text = black_point.ToString() + "/" + need_change_point.ToString();
white_point_tx.text = white_point.ToString() + "/" + need_change_point.ToString();
}
public void ExpansionU()
{
H_Upper++;
for(int i = W_bottom; i <= W_Upper; i++)
{
box_list[H_Upper][i].SetActive(true);
}
cameraMove.ShrinkBoard();
ExpansionNext(2);
}
public void ExpansionD()
{
H_bottom--;
for (int i = W_bottom; i <= W_Upper; i++)
{
box_list[H_bottom][i].SetActive(true);
}
cameraMove.ShrinkBoard();
ExpansionNext(2);
}
public void ExpansionR()
{
W_Upper++;
for (int i = H_bottom; i <= H_Upper; i++)
{
box_list[i][W_Upper].gameObject.SetActive(true);
}
cameraMove.ShrinkBoard();
ExpansionNext(2);
}
public void ExpansionL()
{
W_bottom--;
for (int i = H_bottom; i <= H_Upper; i++)
{
box_list[i][W_bottom].SetActive(true);
}
cameraMove.ShrinkBoard();
ExpansionNext(2);
}
public int ExpansionNext(int sound)
{
if(sound==2)audioSource.PlayOneShot(sound2);
if(sound==3)audioSource.PlayOneShot(sound3);
canvas.SetActive(false);
need_change_point *= 2;
if (set_player == 3)
{
black_point = 0;
set_player = 2;
order_text.text = "Player2のターンです。";
}
else
{
white_point = 0;
set_player = 1;
order_text.text = "Player1のターンです。";
}
UpdateText();
if (CheckCanSet() == false)
{
if (set_player == 1)
{
order_text.text = "Player2のターンです。(Player1の置く場所がありませんでした。)";
set_player = 2;
}
else if (set_player == 2)
{
order_text.text = "Player1のターンです。(Player2の置く場所がありませんでした。)";
set_player = 1;
}
if (CheckCanSet() == false)
{
order_text.text = "両Playerとも置く場所がなくなりました。";
EndMassage();
}
else
{
//Debug.Log("Skip");
}
UpdateText();
}
return 0;
}
public void EndMassage()
{
go_to_title_obj.SetActive(true);
end_canvas.SetActive(true);
set_player = -1;
end_massage_text.text = "Black:";
end_massage_text.text += black_num.ToString();
end_massage_text.text += " White:";
end_massage_text.text += white_num;
if (black_num > white_num) end_massage_text.text += " Player1 Win!";
else if (black_num < white_num) end_massage_text.text += " Player2Win";
else end_massage_text.text += " Draw!";
}
}
再帰とか実装系は競技プログラミングで練習するのがおすすめです!(布教)
最後に
やっぱりオンライン機能を実装できなかったのが心残りなので、次の作品ではオンライン機能に再挑戦します。 最後までご閲覧ありがとうございました。