using System; namespace BinxForge.CoinRoom { public enum RoundState { Playing, Won, Lost } // Engine-independent rules. Unity supplies input, rendering and collision. public sealed class RoundRules { public const int CoinCount = 3; public const double Duration = 60; public const double Speed = 4; private int collected; public int Score { get; private set; } public double Remaining { get; private set; } public bool Paused { get; private set; } public RoundState State { get; private set; } public bool Active { get { return State == RoundState.Playing && !Paused; } } public RoundRules() { Restart(); } public void Restart() { collected = 0; Score = 0; Remaining = Duration; Paused = false; State = RoundState.Playing; } public void Pause(bool paused) { if (State == RoundState.Playing) Paused = paused; } public bool Collect(int coin) { if (!Active || coin < 0 || coin >= CoinCount || (collected & (1 << coin)) != 0) return false; collected |= 1 << coin; Score++; if (Score == CoinCount) State = RoundState.Won; return true; } public void HitPatrol() { if (Active) State = RoundState.Lost; } public void Tick(double seconds) { if (!Active || double.IsNaN(seconds) || double.IsInfinity(seconds) || seconds <= 0) return; // Drop excess stall time; this is simulated active time, not wall-clock time. Remaining = Math.Max(0, Remaining - Math.Min(seconds, 0.1)); if (Remaining == 0) State = RoundState.Lost; } public static void Movement(double x, double y, out double vx, out double vy) { vx = vy = 0; if (double.IsNaN(x) || double.IsNaN(y) || double.IsInfinity(x) || double.IsInfinity(y)) return; x = Math.Max(-1, Math.Min(1, x)); y = Math.Max(-1, Math.Min(1, y)); double length = Math.Sqrt(x * x + y * y); if (length > 1) { x /= length; y /= length; } vx = x * Speed; vy = y * Speed; } } }