/// <summary> /// Puts down a specific disc /// </summary> /// /// <param name="p_pole">The pole where the disc will be placed</param> public void PutdownDisc(HanoiPole p_pole) { // Check if you are holding a disc if (_currentlyHeldDisc) { // The topmost disc of the p_pole HanoiDisc currentPoleTopDisc = p_pole.PeekTopDisc; // Checks if there is a stack on the current pole if (currentPoleTopDisc) { if (_currentlyHeldDisc.Rank <= currentPoleTopDisc.Rank) // Places the disc on the stack if it is smaller than the current top of the stack { PutDiscOnTopOfStack(currentPoleTopDisc, p_pole); } else { // if not, reset the position ResetDiscPosition(); // Raise the Error putdown disc Event _onDiscPutdownError.Raise(); } } else // If there is no stack, you can safely place the disc on the pole { PutDiscOnTopOfStack(currentPoleTopDisc, p_pole); } } }
/// <summary> /// Resets the original position of the currently held disc if the pole cannot be put any disc /// </summary> public void ResetDiscPosition() { if (_currentlyHeldDisc) { Vector3 originalDiscPosition = Vector3.zero; HanoiDisc originalTopStack = _currentDiscOriginalPole.PeekTopDisc; if (originalTopStack) // If stack is not empty, get the top of the stack to land on { originalDiscPosition = originalTopStack.transform.position; } else // If stack is empty, get the base of the board { originalDiscPosition = new Vector3(_currentDiscOriginalPole.transform.position.x, -_currentlyHeldDisc.YScale, _currentDiscOriginalPole.transform.position.z); } // Calculate Landing Position based on scale originalDiscPosition += Vector3.up * _currentlyHeldDisc.YScale * 2f; // Set position based on calculated position _currentlyHeldDisc.transform.position = originalDiscPosition; _currentlyHeldDisc.transform.SetParent(_currentDiscOriginalPole.transform); // Add it to the stack _currentDiscOriginalPole.AddDiscToStack(_currentlyHeldDisc); // Reset the Currently Held disc _currentlyHeldDisc = null; } }
// Initialize the values upon start of this object private void Start() { Time.timeScale = 1.0f; // List of all the current discs for the session List <HanoiDisc> discs = new List <HanoiDisc>(); // Loop starting from the biggest disc HanoiDisc disc = null; for (int i = _discQuantity.Value; i > 0; i--) { // First, instantiate the disc disc = Instantiate(_discPrefab); // Second, Get the order position this disc is instatiated int discOrderPosition = _discQuantity.Value - i; // Third, Calculate the current disc's Y position // The disc's Y position will be twice its scale multiplied by // it's order in position the offset it by the Y scale Vector3 discPosition = new Vector3( disc.transform.position.x, (2f * disc.YScale * discOrderPosition) + disc.YScale, disc.transform.position.z); // Fourth, Use the Disc position to Initialize the Disc disc.Initialize(i, discPosition); // Finally, Add the disc to the list discs.Add(disc); } // Calculate the pickup Location by getting the last disc placed and positioning it 5 stacks higher than that disc Vector3 pickupLocation = new Vector3( disc.transform.position.x, disc.transform.position.y + (disc.YScale * 10f), disc.transform.position.z); // Initialize the Pickup location _pickupController.Initialize(pickupLocation); // Initialize all poles for (int i = 0; i < _poles.Length; i++) { _poles[i].Initialize(_discQuantity.Value, disc.YScale); } // After Initializing the poles, Assign the Disc's Parent to the First pole then add the disc to the pole's stack for (int i = 0; i < discs.Count; i++) { discs[i].transform.SetParent(_poles[0].transform); _poles[0].AddDiscToStack(discs[i]); } // Calculate How much will the board rotate throughout the game _rotationOffset.SetVariableValue(360f / _poles.Length); }
/// <summary> /// Picks up a specific disc /// </summary> /// <param name="p_disc">The disc to be picked up</param> public void PickupDisc(HanoiDisc p_disc, HanoiPole p_currentPole) { // Cache the disc currently holding _currentlyHeldDisc = p_disc; // Hold it when it is not null if (_currentlyHeldDisc) { // Cache the original pole where the disc is from _currentDiscOriginalPole = p_currentPole; // Remove the current pole parent _currentlyHeldDisc.transform.SetParent(null); // Set new held Position _currentlyHeldDisc.transform.position = _pickUpLocation; // Raise Pickup event _onDiscPickup.Raise(); } }
/// <summary> /// Puts down the currently held disc on top of the current stack /// </summary> /// <param name="p_currentPoleTopDisc">The top of the current stack on the pole</param> /// <param name="p_pole">The pole where this disc will be placed</param> private void PutDiscOnTopOfStack(HanoiDisc p_currentPoleTopDisc, HanoiPole p_pole) { if (_currentlyHeldDisc) { // Raise the on put down event _onDiscPutdown.Raise(); Vector3 currentDiscPosition = Vector3.zero; if (p_currentPoleTopDisc) // If stack is not empty, get the top of the stack to land on { currentDiscPosition = p_currentPoleTopDisc.transform.position; } else // If stack is empty, get the base of the board { currentDiscPosition = new Vector3(p_pole.transform.position.x, -_currentlyHeldDisc.YScale, p_pole.transform.position.z); } // Calculate Landing Position based on scale currentDiscPosition += Vector3.up * _currentlyHeldDisc.YScale * 2f; // Set position based on calculated position _currentlyHeldDisc.transform.position = currentDiscPosition; _currentlyHeldDisc.transform.SetParent(p_pole.transform); // Update Movecount if you moved to another pole if (p_pole != _currentDiscOriginalPole) { _moveCount.SetVariableValue(_moveCount.Value + 1); } // Add it to the stack p_pole.AddDiscToStack(_currentlyHeldDisc); // Reset the Currently Held disc _currentlyHeldDisc = null; // Raise the disc stack event _onDiscStack.Raise(); } }
/// <summary> /// Adds a certain disc to the pole's stack /// </summary> /// <param name="p_disc">The disc to be added</param> public void AddDiscToStack(HanoiDisc p_disc) { _discStack.Push(p_disc); _onStackDisc.Invoke(); }