예제 #1
0
파일: AIV2.cs 프로젝트: Blecki/coerceo
        public static void ExpandMax(DataEntry Entry, int Depth, int DepthLimit)
        {
            CountOfConfigurationsScored += 1;
            var recurseLimit = DepthLimit;
            if (Depth >= DepthReached) DepthReached = Depth;

            if (Entry.Moves == null)
            {
                AI.Expand(Entry);
                recurseLimit = Depth + 1;
            }

            if (Entry.Moves.Count == 0)
            {
                Entry.ScoreAdjustment = 100000;
                WinConditionFound = true;
            }
            else
            {
                var baseMax = Entry.Moves.Max(m => m.Score);
                var index = Random.Next(0, Entry.Moves.Where(m => m.Score == baseMax).Count());
                foreach (var move in Entry.Moves)
                    move.Ignored = true;
                var bestMove = Entry.Moves.Where(m => m.Score == baseMax).ElementAt(index);
                if (Depth < DepthLimit) ExpandMax(bestMove.NextBoard, Depth + 1, recurseLimit);
                bestMove.Score = bestMove.NextBoard.CombinedScore;
                bestMove.Ignored = false;

                Entry.ScoreAdjustment = -(Entry.Moves.Max(m => m.Score) * 0.8f);
            }
        }
예제 #2
0
파일: AI.cs 프로젝트: Blecki/coerceo
        public static void Expand(DataEntry Entry)
        {

            if (Entry.Moves == null)
            {
                Entry.Moves = new List<MoveTransition>(Coerceo.EnumerateLegalMoves(Entry.Board).Select(move =>
                    {
                        var nextBoard = new DataEntry
                        {
                            ScoreAdjustment = 0,
                            Moves = null,
                            Board = Coerceo.ApplyMove(Entry.Board, move)
                        };

                        nextBoard.BaseScore = ScoreBoard(Entry.Board, nextBoard.Board);

                        return new MoveTransition
                            {
                                NextBoard = nextBoard,
                                Move = move,
                                Ignored = false,
                                Score = nextBoard.BaseScore
                            };
                                
                    }));
            }
        }
예제 #3
0
파일: AI.cs 프로젝트: Blecki/coerceo
        public static void CalculateAdjustedScore(DataEntry Entry, int Depth)
        {
            CountOfConfigurationsScored += 1;
            if (CountOfConfigurationsScored > 10000)
                return;

            if (Entry.Moves == null)
                Expand(Entry);

            if (Entry.Moves.Count == 0)
            {
                // This board is a dead end - the player lost. It gets a strong negative penalty, but not too strong
                // or it will wrap and the other player will think this move is really fantastic.
                Entry.ScoreAdjustment = -100000;
            }
            else
            {
                if (Depth < DepthReached) DepthReached = Depth;

                var max = float.MinValue;
                var baseAverage = Entry.Moves.Sum(m => m.Score) / Entry.Moves.Count;
                var baseMax = Entry.Moves.Max(m => m.Score);

                foreach (var move in Entry.Moves)
                {
                    if (move.Score >= baseMax)
                    {
                        if (Depth > 0) CalculateAdjustedScore(move.NextBoard, Depth - 1);
                        move.Score = move.NextBoard.CombinedScore;
                        if (move.Score > max) max = move.Score;
                        move.Ignored = false;
                    }
                    else
                        move.Ignored = true;
                }

                if (max < baseAverage) // The best moves turned out worse than average
                {
                    foreach (var move in Entry.Moves.Where(m => m.Ignored))
                    {
                        if (move.Score >= baseAverage)
                        {
                            if (Depth > 0) CalculateAdjustedScore(move.NextBoard, System.Math.Max(Depth - 2, 0)); // We can't afford to look very deeply, though.
                            move.Score = move.NextBoard.CombinedScore;
                            if (move.Score > max) max = move.Score;
                            move.Ignored = false;
                        }
                        else
                            move.Ignored = true;
                    }
                }

                if (max < baseAverage) // Well we tried the second best and they still sucked.
                {
                    foreach (var move in Entry.Moves.Where(m => m.Ignored))
                    {
                        if (Depth > 0) CalculateAdjustedScore(move.NextBoard, 0); // We can't afford to look very deeply, though.
                        move.Score = move.NextBoard.CombinedScore;
                        if (move.Score > max) max = move.Score;
                        move.Ignored = false;
                    }
                }

                Entry.ScoreAdjustment = -(int)(max * 0.8f);
            }
        }