Example #1
0
        static Move V4Strategy(
            MoveMessage message,
            SolverState solverState)
        {
            var startTime = DateTime.UtcNow;

            var deadLine = startTime.AddMilliseconds(900);

            var myId = solverState.initialState.punter.Value;

            var initialMap = solverState.initialState.map;

            var takenRivers = Utils.ConvertMovesToRivers(initialMap, solverState.moves, (id) => true)
                              .ToLookup(river => river, river => true);

            var availableRivers = initialMap.rivers
                                  .Where(river => !takenRivers.Contains(river))
                                  .ToList();

            var canUseOptions =
                solverState.initialState.settings.options &&
                solverState.moves.Count(move => move.option != null && move.option.punter == myId) < initialMap.mines.Count;

            var adjacencyMap = new AdjacencyMap(initialMap.rivers);

            var mineDistances = new MineDistances(initialMap, adjacencyMap);

            var setupDoneTime = DateTime.UtcNow;

            // if we see a choke, take it
            var chokeFindTask = Task.Run(() =>
            {
                var punters = new List <int>()
                {
                    myId
                };
                if (solverState.initialState.punters.Value == 2)
                {
                    punters.Add(1 - myId);
                }

                foreach (var punter in punters)
                {
                    var availableOptions = new List <River>();
                    if (canUseOptions && punter == myId)
                    {
                        var takenOptions = Utils.ConvertMovesToRivers(initialMap, solverState.moves.Where(move => move.option != null), (id) => true)
                                           .ToLookup(river => river, river => true);

                        availableOptions =
                            Utils.ConvertMovesToRivers(initialMap, solverState.moves, (id) => id != myId)
                            .Where(river => !takenOptions.Contains(river))
                            .ToList();
                    }

                    var chokes = FindChokes(
                        initialMap.mines,
                        Utils.ConvertMovesToRivers(initialMap, solverState.moves, (id) => id == punter).ToList(),
                        availableRivers.Concat(availableOptions).ToList(),
                        deadLine.AddMilliseconds(-100));

                    if (chokes.Any())
                    {
                        var river = chokes[0][0];

                        var chokeAnalysisDoneTime = DateTime.UtcNow;

                        Log(myId, string.Format("[{0}] [{1}] [{2}/{3}]",
                                                punter == myId ? "TakeChoke " : "BlockChoke",
                                                (int)(chokeAnalysisDoneTime - startTime).TotalMilliseconds,
                                                (int)(setupDoneTime - startTime).TotalMilliseconds,
                                                (int)(chokeAnalysisDoneTime - setupDoneTime).TotalMilliseconds));

                        return(availableOptions.Contains(river) ? CreateOptionMove(myId, river) : CreateClaimMove(myId, river));
                    }
                }

                return(null);
            });

            // otherwise just play a move that joins two trees, increases liberty, or increases score
            var trees = new TreeSet(
                Utils.ConvertMovesToRivers(initialMap, solverState.moves, (id) => id == myId),
                initialMap.mines);

            var riversToConsider = availableRivers
                                   .Where(river => trees.Contains(river.source) || trees.Contains(river.target))
                                   .DefaultIfEmpty(availableRivers.First());

            var riversConsidered =
                from river in riversToConsider
                where DateTime.UtcNow < deadLine
                let newTrees = trees.AddRiver(river)
                               let treeCount = newTrees.Trees.Count
                                               let liberty                         = newTrees.ComputeLiberty(availableRivers, adjacencyMap)
                                                                         let score = newTrees.ComputeScore(mineDistances)
                                                                                     select new { river = river, liberty = liberty, score = score, treeCount = treeCount };

            var rankedRivers = riversConsidered
                               .ToList()
                               .OrderBy(i => i.treeCount)
                               .ThenByDescending(i => i.liberty)
                               .ThenByDescending(i => i.score);

            var ans = CreateClaimMove(myId, rankedRivers.First().river);

            var analysisDoneTime = DateTime.UtcNow;

            var zero     = TimeSpan.FromTicks(0);
            var waitTime = deadLine - DateTime.UtcNow;

            waitTime = waitTime < zero ? zero : waitTime;
            chokeFindTask.Wait(waitTime);

            if (chokeFindTask.IsCompleted && chokeFindTask.Result != null)
            {
                return(chokeFindTask.Result);
            }

            var doneTime = DateTime.UtcNow;

            Log(myId, string.Format("[NormalMove] [{0}] [{1}/{2}/{3}] [Trees:{4}] [Liberties:{5}] [Score:{6}]",
                                    (int)(doneTime - startTime).TotalMilliseconds,
                                    (int)(setupDoneTime - startTime).TotalMilliseconds,
                                    (int)(analysisDoneTime - setupDoneTime).TotalMilliseconds,
                                    (int)(doneTime - analysisDoneTime).TotalMilliseconds,
                                    rankedRivers.First().treeCount,
                                    rankedRivers.First().liberty,
                                    rankedRivers.First().score));

            return(ans);
        }
Example #2
0
 TreeSet(TreeSet other)
 {
     Trees = other.Trees.Select(i => new HashSet <int>(i)).ToList();
 }