Assignment for RMIT Mixed Reality in 2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
5.0 KiB

  1. namespace Oculus.Platform.Samples.VrBoardGame
  2. {
  3. using System;
  4. using UnityEngine;
  5. //
  6. // This script describes the game board along with the game pieces that
  7. // are in play. The rules for the game board are:
  8. // 1) Player can place a normal GamePiece on any empty BoardPosition
  9. // 2) Player can place a power GamePiece on top of a normal piece
  10. // 3) The board is full when all positions have a normal piece
  11. // Player score is calculated as:
  12. // 1) +10 points for each normal piece on the board
  13. // 2) +10 points for each normal piece with 1 square of one of their power pieces
  14. // 3) -10 points for each opponent normal piece within 1 square of their power pieces
  15. //
  16. public class GameBoard : MonoBehaviour
  17. {
  18. public const int LENGTH_X = 3;
  19. public const int LENGTH_Y = 3;
  20. public const int MAX_PLAYERS = 2;
  21. // the placed-piece color for each player
  22. [SerializeField] private Color[] m_playerColors = new Color[MAX_PLAYERS];
  23. // color for pice the player is considering moving to
  24. [SerializeField] private Color m_proposedMoveColor = Color.white;
  25. // the player scores that are recalcuated after a pice is placed
  26. private int[] m_scores = new int[MAX_PLAYERS];
  27. // GameObjects that define each of the allowed piece positions
  28. [SerializeField] private BoardPosition[] m_positions = new BoardPosition[9];
  29. private struct PositionInfo
  30. {
  31. public GameObject piece;
  32. public int pieceOwner;
  33. public int powerPieceOwner;
  34. }
  35. // pieces in play for the current game
  36. private readonly PositionInfo[,] m_pieces = new PositionInfo[LENGTH_X, LENGTH_Y];
  37. // removes all game pieces from the board
  38. public void Reset()
  39. {
  40. for (int x = 0; x < LENGTH_X; x++)
  41. {
  42. for (int y = 0; y < LENGTH_Y; y++)
  43. {
  44. if (m_pieces[x,y].piece != null)
  45. {
  46. Destroy(m_pieces[x,y].piece);
  47. m_pieces[x,y].piece = null;
  48. m_pieces[x,y].pieceOwner = -1;
  49. m_pieces[x,y].powerPieceOwner = -1;
  50. }
  51. }
  52. }
  53. }
  54. #region Board status
  55. // returns true if all the board positions have a piece in them
  56. public bool IsFull()
  57. {
  58. for (int x = 0; x < LENGTH_X; x++)
  59. {
  60. for (int y = 0; y < LENGTH_Y; y++)
  61. {
  62. if (m_pieces[x,y].piece == null)
  63. {
  64. return false;
  65. }
  66. }
  67. }
  68. return true;
  69. }
  70. public bool CanPlayerMoveToPostion(int x, int y)
  71. {
  72. return m_pieces[x,y].piece == null;
  73. }
  74. public bool CanPlayerPowerUpPosition(int x, int y)
  75. {
  76. return m_pieces[x,y].piece != null;
  77. }
  78. #endregion
  79. #region creating game pieces
  80. public void AddPiece(int player, GameObject prefab, int x, int y)
  81. {
  82. var pos = m_positions[x * LENGTH_Y + y];
  83. var piece = Create(prefab, pos.gameObject, pos, Vector3.zero);
  84. piece.GetComponent<Renderer>().material.color = m_playerColors[player];
  85. m_pieces[x,y].piece = piece.gameObject;
  86. m_pieces[x,y].pieceOwner = player;
  87. m_pieces[x,y].powerPieceOwner = -1;
  88. UpdateScores();
  89. }
  90. public GamePiece AddProposedPiece(GameObject prefab, BoardPosition pos)
  91. {
  92. var piece = Create(prefab, pos.gameObject, pos, Vector3.zero);
  93. piece.GetComponent<Renderer>().material.color = m_proposedMoveColor;
  94. return piece;
  95. }
  96. public void AddPowerPiece(int player, GameObject prefab, int x, int y)
  97. {
  98. var piece = Create(prefab, m_pieces[x,y].piece, m_positions[x*LENGTH_Y+y], .2f*Vector3.up);
  99. piece.GetComponent<Renderer>().material.color = m_playerColors[player];
  100. m_pieces[x,y].powerPieceOwner = player;
  101. UpdateScores();
  102. }
  103. public GamePiece AddProposedPowerPiece(GameObject prefab, BoardPosition pos)
  104. {
  105. var piece = Create(prefab, m_pieces[pos.x, pos.y].piece, pos, .2f*Vector3.up);
  106. piece.GetComponent<Renderer>().material.color = m_proposedMoveColor;
  107. return piece;
  108. }
  109. private GamePiece Create(GameObject prefab, GameObject parent, BoardPosition pos, Vector3 off)
  110. {
  111. var go = Instantiate(prefab, parent.transform) as GameObject;
  112. go.transform.position = parent.transform.position + off;
  113. go.GetComponent<GamePiece>().Position = pos;
  114. return go.GetComponent<GamePiece>();
  115. }
  116. #endregion
  117. #region scores
  118. public int GetPlayerScore(int player)
  119. {
  120. return m_scores[player];
  121. }
  122. private void UpdateScores()
  123. {
  124. for (int i = 0; i < MAX_PLAYERS; i++)
  125. {
  126. m_scores[i] = 0;
  127. }
  128. for (int x = 0; x < LENGTH_X; x++)
  129. {
  130. for (int y = 0; y < LENGTH_Y; y++)
  131. {
  132. if (m_pieces[x,y].piece != null)
  133. {
  134. // for each piece on the board, the player gets 10 points
  135. m_scores[m_pieces[x,y].pieceOwner] += 10;
  136. // for each power piece, the player gains or loses 10 points
  137. // based on the ownership of nearby pieces
  138. if (m_pieces[x,y].powerPieceOwner >= 0)
  139. {
  140. for (int px = x-1; px <= x+1; px++)
  141. {
  142. for (int py = y-1; py <= y+1; py++)
  143. {
  144. if (px >= 0 && py >= 0 && px < LENGTH_X && py < LENGTH_Y)
  145. {
  146. var powerup =
  147. m_pieces[x,y].pieceOwner == m_pieces[x,y].powerPieceOwner ?
  148. +10 : -10;
  149. m_scores[m_pieces[x, y].powerPieceOwner] += powerup;
  150. }
  151. }
  152. }
  153. }
  154. }
  155. }
  156. }
  157. }
  158. #endregion
  159. }
  160. }