static private void ResolveActions(int playerIndex, Game game, LinkedList <GameAction> moves, List <GameActionsBatch> allActions)
        {
            if (CgTimer.IsTimeout())
            {
                return;
            }

            CgTimer.Tick();

            game = new Game(game);

            if (moves != null)
            {
                Simulator.ApplyMove(playerIndex, moves.Last(), game);
            }
            else
            {
                moves = new LinkedList <GameAction>();
            }

            var availableMoves = MovesEnumerator.GetAvailableActions(game, playerIndex);

            if (!availableMoves.Any())
            {
                if (moves.Any())
                {
                    allActions.Add(new GameActionsBatch {
                        Game = game, Actions = moves.ToArray(), Score = CalcScore(game)
                    });
                }
            }
            else
            {
                foreach (var m in availableMoves)
                {
                    if (CgTimer.IsTimeout())
                    {
                        return;
                    }

                    moves.AddLast(m);
                    ResolveActions(playerIndex, game, moves, allActions);
                    moves.RemoveLast();
                }
            }
        }
        private static double CalcScoreWithOpponentAction(Game game)
        {
            var actions   = MovesEnumerator.GetAvailableActions(game, 1);
            var bestScore = double.MinValue;

            foreach (var a in actions)
            {
                if (CgTimer.IsTimeout())
                {
                    break;
                }

                var g = new Game(game);
                Simulator.ApplyMove(1, a, g);
                var score = CalcScore(g);
                if (score > bestScore)
                {
                    bestScore = score;
                }
            }

            return(bestScore);
        }
        public static IEnumerable <GameAction> GetBestActions(Game game)
        {
            IEnumerable <GameAction> bestActions = GameAction.PassActions;
            var bestScore    = double.MinValue;
            var batchActions = new LinkedList <GameAction>();

            while (!CgTimer.IsTimeout())
            {
                var g = new Game(game);
                batchActions.Clear();

                while (!CgTimer.IsTimeout())
                {
                    CgTimer.Tick();

                    var actions = MovesEnumerator.GetAvailableActions(g, 0).ToArray();
                    if (actions.Length == 0)
                    {
                        break;
                    }

                    var action = actions[rnd.Next(actions.Length)];
                    Simulator.ApplyMove(0, action, g);
                    batchActions.AddLast(action);
                }

                //var score = CalcScoreWithOpponentAction(g);
                var score = CalcScore(g);

                if (score > bestScore)
                {
                    bestScore   = score;
                    bestActions = batchActions.ToArray();
                }
            }
            return(bestActions);
        }