/// <summary> /// Called when the start button is pressed <para/> /// Initialises the <see cref="mcts"/> tree search object and instantiates the root node <para/> /// Also creates as many starting nodes as the user specified /// </summary> public void StartButtonPressed() { //Create an empty board instance, which will have whatever game the user chooses assigned to it Board board; //Assign whatever game board the user has chosen to the board instance switch (HashUIController.GetGameChoice) { case 0: board = new TTTBoard(); displayBoardModel = false; break; case 1: board = new C4Board(); displayBoardModel = true; //Create a C4 Board GameObject and obtain a reference to its BoardModelController Component GameObject boardModel = Instantiate(Resources.Load("C4 Board", typeof(GameObject))) as GameObject; boardModelController = boardModel.GetComponent <BoardModelController>(); boardModelController.Initialise(); break; case 2: board = new OthelloBoard(); displayBoardModel = false; break; default: throw new System.Exception("Unknown game type index has been input"); } mcts = new TreeSearch <Node>(board); //Calculate the position of the root node and add an object for it to the scene Vector3 rootNodePosition = BoardToPosition(mcts.Root.GameBoard); GameObject rootNode = Instantiate(Resources.Load("HashNode"), rootNodePosition, Quaternion.identity) as GameObject; rootNode.transform.parent = transform; rootNode.GetComponent <HashNode>().AddNode(null, mcts.Root, false); rootNode.GetComponent <HashNode>().Initialise(rootNodePosition); //Add the root node to the position and object map nodePositionMap.Add(rootNodePosition, rootNode); nodeObjectMap.Add(mcts.Root, rootNode); //Create the amount of starting nodes specified by the user for (int i = 0; i < HashUIController.GetStartingNodeInput(); i++) { PerformStep(true); } //Swap out the current menu panels HashUIController.SetMenuPanelActive(false); HashUIController.SetNavigationPanelActive(true); }
/// <summary> /// Assigns the singleton reference when the scene is loaded, throwing an exception if one already exists /// </summary> public void Start() { //If the singleton reference is not null, throw an exception if (controller != null) { throw new System.Exception("Singleton reference already exists!"); } //Assign the singleton reference controller = this; }
/// <summary> /// Performs a step of MCTS and creates a gameobject for the new <see cref="Node"/>'s board state if required <para/> /// Also creates any relevant links between related nodes /// </summary> /// <param name="fromMenu">Flag used to indicate whether this step is being performed from the menu or not. Used to prevent the spawning animation if a node is not being added when the visualisation has already been started</param> public void PerformStep(bool fromMenu) { //Perform an iteration of MCTS mcts.Step(); //Get a reference to the newest node Node newestNode = mcts.AllNodes[mcts.AllNodes.Count - 1]; //Hash the board contents of the newest node to obtain a positon Vector3 newNodePosition = BoardToPosition(newestNode.GameBoard); //Decrease the visibility of every node in the scene foreach (HashNode n in AllNodes) { n.SetVisibility(n.Visibility - 0.01f); } //If the current board state already exists, then don't create a new node, but create a line to the existing node if (nodePositionMap.ContainsKey(newNodePosition)) { //Map the newest node to the existing node object if it does not already exist in the dicitonary if (!nodeObjectMap.ContainsKey(newestNode)) { nodeObjectMap.Add(newestNode, nodePositionMap[newNodePosition]); } } else { //Instantiate the new node object at the hashed position GameObject newNodeObject = Instantiate(Resources.Load("HashNode"), fromMenu ? newNodePosition : nodeObjectMap[newestNode.Parent].transform.position, Quaternion.identity) as GameObject; //Set the parent of the new node object to be this controller object newNodeObject.transform.parent = transform; //Map the newest node to the new node object nodeObjectMap.Add(newestNode, newNodeObject); //Map the hashed position of the newest node to the new node object nodePositionMap.Add(newNodePosition, newNodeObject); AllNodes.Add(newNodeObject.GetComponent <HashNode>()); } //Initialise the newest hash node and add a mcts Node to it nodeObjectMap[newestNode].GetComponent <HashNode>().Initialise(newNodePosition); nodeObjectMap[newestNode].GetComponent <HashNode>().AddNode(nodeObjectMap[newestNode.Parent], newestNode, !fromMenu); HashUIController.SetTotalNodeText(nodeObjectMap.Count); }
/// <summary> /// Called when the pause button is pressed <para/> /// Pauses the animation of nodes beng created and sets the play button to active again /// </summary> public void PauseButtonPressed() { playing = false; HashUIController.PauseButtonPressed(); }
/// <summary> /// Called when the play button is pressed <para/> /// Starts the animation of ndoes being creates and sets the pause button to be active /// </summary> public void PlayButtonPressed() { playing = true; HashUIController.PlayButtonPressed(); }
void Update() { if (Forwards()) { transform.Translate(Vector3.forward * 0.1f * Speed); } if (Backwards()) { transform.Translate(Vector3.forward * -0.1f * Speed); } if (StrafeLeft()) { transform.Translate(Vector3.right * -0.1f * Speed); } if (StrafeRight()) { transform.Translate(Vector3.right * 0.1f * Speed); } if (Upwards()) { transform.Translate(Vector3.up * 0.1f * Speed); } if (Downwards()) { transform.Translate(Vector3.up * -0.1f * Speed); } if (PivotLeft()) { transform.Rotate(new Vector3(0, -Speed, 0)); } if (PivotRight()) { transform.Rotate(new Vector3(0, Speed, 0)); } if (PivotUpwards()) { transform.Rotate(new Vector3(-Speed, 0, 0)); } if (PivotDownwards()) { transform.Rotate(new Vector3(Speed, 0, 0)); } if (currentHighlighted != null && NextNode() && currentHighlighted.NodeCount > currentSelectedNodeIndex + 1) { currentSelectedNodeIndex++; HashUIController.DisplayNodeInfo(currentHighlighted.GetNode(currentSelectedNodeIndex), currentSelectedNodeIndex, currentHighlighted.NodeCount); } if (currentHighlighted != null && PreviousNode() && currentSelectedNodeIndex > 0) { currentSelectedNodeIndex--; HashUIController.DisplayNodeInfo(currentHighlighted.GetNode(currentSelectedNodeIndex), currentSelectedNodeIndex, currentHighlighted.NodeCount); } //See if there are any Hashnodes in front of the camera RaycastHit hit; Ray ray = GetComponent <Camera>().ScreenPointToRay(Input.mousePosition); //If the mouse is hovered over a HashNode object, highlight it if (Physics.Raycast(ray, out hit) && hit.transform.GetComponent <HashNode>() != null) { //Get a reference to the HashNode that was hit HashNode hitNode = hit.transform.GetComponent <HashNode>(); //If the node being looked at is not the current highlighted node, make it the highlighted node if (currentHighlighted != hitNode) { //Reset the color of the old highlighted node, if there is one if (currentHighlighted != null) { currentHighlighted.SetColor(); } //Make the node being hovered over the current highlighted node and set its color to yellow currentHighlighted = hitNode; Color highlightedColor = Color.yellow; highlightedColor.a = currentHighlighted.Visibility; hitNode.GetComponent <Renderer>().material.color = highlightedColor; //Display information about the current node HashUIController.DisplayBoardInfo(hitNode.BoardState); currentSelectedNodeIndex = 0; HashUIController.DisplayNodeInfo(hitNode.GetNode(currentSelectedNodeIndex), currentSelectedNodeIndex, hitNode.NodeCount); } } else if (currentHighlighted != null) { //If the camera is not looking at a HashNode object, reset the previously highlighted node and hide the node information panel currentHighlighted.SetColor(); currentHighlighted = null; HashUIController.HideBoardInfo(); currentSelectedNodeIndex = 0; } }