Ohhh boy… you’re gonna be studying my code for ages! I threw in a whole mix of different ways to do stuff.
public class CubeXOtest : MonoBehaviour
{
public List<PanelTest> allPanels = new List<PanelTest>();
public List<List<PanelTest>> sides = new List<List<PanelTest>>();
int player = 1; // debug one player for now
private void Awake()
{
Application.targetFrameRate = 30; // save CPU
allPanels.AddRange(GetComponentsInChildren<PanelTest>());
for (int i = 0; i < 6; i++) { sides.Add(new List<PanelTest>()); }
}
private void Update()
{
if (Input.GetMouseButtonDown(0)) { HandleClick(); }
}
void HandleClick()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit, 500f))
{
PanelTest panel = GetPanel(hit.collider);
if (panel != null && panel.stateValue == 0)
{
panel.stateValue = player;
CheckWin(player, panel.side);
}
}
}
PanelTest GetPanel(Collider collider)
{
for (int i = 0; i < allPanels.Count; i++)
{
if (allPanels[i].coll == collider)
{ return allPanels[i]; }
}
return null;
}
void CheckWin(int p, int s)
{
if (ConditionalWin(s, p, 0, 1, 2)) { WinGame(); return; }
if (ConditionalWin(s, p, 3, 4, 5)) { WinGame(); return; }
if (ConditionalWin(s, p, 6, 7, 8)) { WinGame(); return; }
if (ConditionalWin(s, p, 0, 3, 6)) { WinGame(); return; }
if (ConditionalWin(s, p, 1, 4, 7)) { WinGame(); return; }
if (ConditionalWin(s, p, 2, 5, 8)) { WinGame(); return; }
if (ConditionalWin(s, p, 0, 4, 8)) { WinGame(); return; }
if (ConditionalWin(s, p, 2, 4, 6)) { WinGame(); return; }
}
bool ConditionalWin(int side, int p, int a, int b, int c)
{
bool aa = false; bool bb = false; bool cc = false;
for (int i = 0; i < 9; i++)
{
PanelTest pp = sides[side][i];
if (pp.sideIndex == a && pp.stateValue == p) { aa = true; }
if (pp.sideIndex == b && pp.stateValue == p) { bb = true; }
if (pp.sideIndex == c && pp.stateValue == p) { cc = true; }
}
if (aa && bb && cc) { return true; }
return false;
}
void WinGame()
{
print("GAME WON!!!");
}
}
public class PanelTest : MonoBehaviour
{
public Collider coll;
public Renderer rend;
public CubeXOtest owner;
public int stateValue;
private int lastValue;
public int side;
public int sideIndex;
private void Awake()
{
coll = GetComponent<Collider>();
rend = GetComponent<Renderer>();
owner = transform.root.GetComponent<CubeXOtest>();
}
private void Start()
{
SetSide();
SetSideIndex();
}
private void Update()
{
if (stateValue != lastValue)
{
if (stateValue== 0) { rend.material.color = Color.white; }
if (stateValue== 1) { rend.material.color = Color.blue; }
if (stateValue== 2) { rend.material.color = Color.green; }
lastValue = stateValue;
}
}
void SetSide()
{
Vector3 sidePos = transform.forward;
if (sidePos == Vector3.back)
{ side = 0; owner.sides[side].Add(this); return; }
if (sidePos == Vector3.forward) { side = 1; return; }
if (sidePos == Vector3.up) { side = 2; return; }
if (sidePos == Vector3.down) { side = 3; return; }
if (sidePos == Vector3.left) { side = 4; return; }
if (sidePos == Vector3.right) { side = 5; return; }
}
void SetSideIndex()
{
if (string.Equals(name, "Panel BL")) { sideIndex = 0; }
if (string.Equals(name, "Panel BM")) { sideIndex = 1; }
if (string.Equals(name, "Panel BR")) { sideIndex = 2; }
if (string.Equals(name, "Panel ML")) { sideIndex = 3; }
if (string.Equals(name, "Panel Mid")) { sideIndex = 4; }
if (string.Equals(name, "Panel MR")) { sideIndex = 5; }
if (string.Equals(name, "Panel TL")) { sideIndex = 6; }
if (string.Equals(name, "Panel TM")) { sideIndex = 7; }
if (string.Equals(name, "Panel TR")) { sideIndex = 8; }
}
}
Since I only did one side, the SetSide()
method just needs filled in. And I only set one player for just testing. But I child-ed all adjacent panels to the middle panel, so just need to duplicate and rotate in the editor, for the remaining sides:
But I thought of testing several different ways of doing things, especially a list within a list, which I’ve never done before. But took it as a challenge, so I had fun with this.