internal void BroadcastGameOver_StatusUpdate()
        {
            _gameOver = true; // after this moment all return calls will be ignored

            int    top = TopTotalStrength, bot = BotTotalStrength;
            string msg = top > bot
                ? $"Top wins {top} to {bot}"
                : top < bot
                    ? $"Bot wins {bot} to {top}"
                    : $"Draw {top} - {bot}";

            // broadcast game log last message
            GameLogicLogUpdateEventHandler?.Invoke(
                this,
                new GameLogicLogUpdateEventArgs(PlayerIndicator.Top, null, $"\n{msg}\n === GAME OVER ===", top, bot));

            if (GameLogicStatusChangedEventHandler == null)
            {
                ReturnControl(); // interface not attached - immediately return control
            }
            else
            {
                GameLogicStatusChangedEventHandler.Invoke(
                    this,
                    new GameLogicStatusChangedEventArgs(GameLogicMessageType.GameOver, CurrentPlayer)
                {
                    TopTotalStrength = TopTotalStrength,
                    BotTotalStrength = BotTotalStrength,
                });
            }
        }
 // late evaluation
 internal void BroadcastUpdateStrength_StatusUpdate()
 {
     if (GameLogicStatusChangedEventHandler == null)
     {
         ReturnControl(); // interface not attached - immediately return control
     }
     else
     {
         GameLogicStatusChangedEventHandler.Invoke(
             this,
             new GameLogicStatusChangedEventArgs(GameLogicMessageType.UpdateStrength, CurrentPlayer)
         {
             CardStrengths    = GetCardStrengths(),
             TopTotalStrength = TopTotalStrength,
             BotTotalStrength = BotTotalStrength,
         });
     }
 }
 internal void BroadcastMoveCard_StatusUpdate(MoveData move)
 {
     if (GameLogicStatusChangedEventHandler == null)
     {
         ReturnControl(); // interface not attached - immediately return control
     }
     else
     {
         GameLogicStatusChangedEventHandler.Invoke(
             this,
             new GameLogicStatusChangedEventArgs(GameLogicMessageType.MoveCard, CurrentPlayer)
         {
             LastMove         = move,
             TopTotalStrength = TopTotalStrength,
             BotTotalStrength = BotTotalStrength,
         });
     }
 }
        internal void BroadcastEndTurn_StatusUpdate()
        {
            CurrentPlayer = CurrentPlayer.Opposite();

            if (GameLogicStatusChangedEventHandler == null)
            {
                ReturnControl(); // interface not attached - immediately return control
            }
            else
            {
                GameLogicStatusChangedEventHandler.Invoke(
                    this,
                    new GameLogicStatusChangedEventArgs(GameLogicMessageType.EndTurn, CurrentPlayer)
                {
                    TopTotalStrength = TopTotalStrength,
                    BotTotalStrength = BotTotalStrength,
                });
            }
        }
 internal void BroadcastPlayVFX_StatusUpdate(List <SkillTargetData> targets, SkillVisualEffect visualEffect)
 {
     if (GameLogicStatusChangedEventHandler == null)
     {
         ReturnControl(); // interface not attached - immediately return control
     }
     else
     {
         GameLogicStatusChangedEventHandler.Invoke(
             this,
             new GameLogicStatusChangedEventArgs(GameLogicMessageType.PlaySkillVFX, CurrentPlayer)
         {
             Targets          = targets,
             VisualEffect     = visualEffect,
             TopTotalStrength = TopTotalStrength,
             BotTotalStrength = BotTotalStrength
         });
     }
 }