using System; using Unity.MLAgents.Actuators; using UnityEngine; using UnityEngine.Serialization; namespace Unity.MLAgents.Integrations.Match3 { /// /// Actuator component for a Match3 game. Generates a Match3Actuator at runtime. /// [AddComponentMenu("ML Agents/Match 3 Actuator", (int)MenuGroup.Actuators)] public class Match3ActuatorComponent : ActuatorComponent { [HideInInspector, SerializeField, FormerlySerializedAs("ActuatorName")] string m_ActuatorName = "Match3 Actuator"; /// /// Name of the generated Match3Actuator object. /// Note that changing this at runtime does not affect how the Agent sorts the actuators. /// public string ActuatorName { get => m_ActuatorName; set => m_ActuatorName = value; } [HideInInspector, SerializeField, FormerlySerializedAs("RandomSeed")] int m_RandomSeed = -1; /// /// A random seed used in the actuator's heuristic, if needed. /// public int RandomSeed { get => m_RandomSeed; set => m_RandomSeed = value; } [HideInInspector, SerializeField, FormerlySerializedAs("ForceHeuristic")] [Tooltip("Force using the Agent's Heuristic() method to decide the action. This should only be used in testing.")] bool m_ForceHeuristic; /// /// Force using the Agent's Heuristic() method to decide the action. This should only be used in testing. /// public bool ForceHeuristic { get => m_ForceHeuristic; set => m_ForceHeuristic = value; } /// public override IActuator[] CreateActuators() { var board = GetComponent(); if (!board) { return Array.Empty(); } var seed = m_RandomSeed == -1 ? gameObject.GetInstanceID() : m_RandomSeed + 1; return new IActuator[] { new Match3Actuator(board, m_ForceHeuristic, seed, m_ActuatorName) }; } /// public override ActionSpec ActionSpec { get { var board = GetComponent(); if (board == null) { return ActionSpec.MakeContinuous(0); } var numMoves = Move.NumPotentialMoves(board.GetMaxBoardSize()); return ActionSpec.MakeDiscrete(numMoves); } } } }