예제 #1
0
        private static Path GetBestPathFrom(Board b, Options o, int y, int x)
        {
            Path bestPath = new Path();
            Stack<Tuple<Board, Path>> paths = new Stack<Tuple<Board, Path>>();
            paths.Push(new Tuple<Board, Path>(b, new Path
            {
                Start = new Tuple<int, int>(y, x),
                Current = new Tuple<int, int>(y, x),
                Depth = 1,
                Score = b.Score(BoardScorer.Options.Horus)
            }));
            while (paths.Any())
            {
                var cur = paths.Pop();
                var curPath = cur.Item2;
                var curBoard = cur.Item1;
                if (curPath.Score > bestPath.Score)
                    bestPath = curPath;
                if (curPath.Depth == o.MaxDepth)
                    continue;
                //if (paths.Count() > o.WhenToPrune)
                //{
                //    var newPaths = new Stack<Tuple<Board, Path>>();
                //    foreach (var path in paths.OrderByDescending(p => p.Item2.Score).Take(o.NumToKeep).Reverse())
                //        newPaths.Push(path);
                //    paths = newPaths;
                //}

                foreach (var direction in Board.MoveDirections)
                {
                    if (curPath.Length != 0 &&
                        curPath.Actions.Last()[0] == -direction[0] &&
                        curPath.Actions.Last()[1] == -direction[1])
                        continue;
                    var newY = curPath.Current.Item1 + direction[0];
                    var newX = curPath.Current.Item2 + direction[1];
                    if (newY < 0 || newY >= b.Height ||
                        newX < 0 || newX >= b.Width)
                        continue;
                    Board newBoard = new Board(curBoard);
                    Orb tempOrb = newBoard.Orbs[newY, newX];
                    newBoard.Orbs[newY, newX] = newBoard.Orbs[curPath.Current.Item1, curPath.Current.Item2];
                    newBoard.Orbs[curPath.Current.Item1, curPath.Current.Item2] = tempOrb;
                    var newPath = new List<int[]>(curPath.Actions);
                    newPath.Add(direction);
                    paths.Push(new Tuple<Board, Path>(newBoard, new Path
                    {
                        Start = curPath.Start,
                        Current = new Tuple<int, int>(newY, newX),
                        Depth = curPath.Depth + 1,
                        Score = newBoard.Score(BoardScorer.Options.Horus) - curPath.Depth / 100,
                        Actions = newPath
                    }));
                }
            }
            return bestPath;
        }
예제 #2
0
        public static Path GetBestPath(Board b, Options o)
        {
            Path bestPath = new Path();
            object pathLock = new Object();

            Parallel.For(0, b.Height, i =>
            {
                //for (int i = 0; i < b.Height; i++)
                Parallel.For(0, b.Width, j =>
                {
                    //for (int j = 0; j < b.Width; j++)
                    var curPath = GetBestPathFrom(b, o, i, j);
                    lock (pathLock)
                    {
                        if (curPath.Score > bestPath.Score)
                            bestPath = curPath;
                    }
                    var c = b.GetBoardsAfterPath(curPath.Start.Item1, curPath.Start.Item2, curPath.Actions);
                    var curPath2 = GetBestPathFrom(c.Item1, o, curPath.Current.Item1, curPath.Current.Item2);
                    var actions = new List<int[]>(curPath.Actions);
                    actions.AddRange(curPath2.Actions);
                    curPath2.Actions = actions;
                    lock (pathLock)
                    {
                        if (curPath2.Score > bestPath.Score)
                            curPath = bestPath = new Path
                            {
                                Start = curPath.Start,
                                Current = curPath2.Current,
                                Depth = curPath.Depth + curPath2.Depth,
                                Score = curPath2.Score,
                                Actions = curPath2.Actions
                            };
                    }
                });
            });

            var cc = b.GetBoardsAfterPath(bestPath.Start.Item1, bestPath.Start.Item2, bestPath.Actions);
            var bestPath2 = GetBestPathFrom(cc.Item1, o, bestPath.Current.Item1, bestPath.Current.Item2);
            var actions2 = new List<int[]>(bestPath.Actions);
            actions2.AddRange(bestPath2.Actions);
            bestPath2.Actions = actions2;
            lock (pathLock)
            {
                if (bestPath2.Score > bestPath.Score)
                    bestPath = new Path
                    {
                        Start = bestPath.Start,
                        Current = bestPath2.Current,
                        Depth = bestPath.Depth + bestPath2.Depth,
                        Score = bestPath2.Score,
                        Actions = bestPath2.Actions
                    };
            }
            return bestPath;
        }
예제 #3
0
 public static Board BoardFromBitmap(int rows, int columns, int height, int width, int h_off, int w_off, Bitmap bmp)
 {
     PadImage pi = new PadImage(bmp, rows, columns, height, width, h_off, w_off);
     Board b = new Board(rows, columns);
     for (int i = 0; i < rows; i++)
         for (int j = 0; j < columns; j++)
         {
             b.Orbs[i, j] = pi.GetOrb(i, j);
         }
     Console.WriteLine(b.ToString());
     return b;
 }
예제 #4
0
 public void Configure(IApplicationBuilder app)
 {
     app.UseMvc();
     return;
     app.Run(async (context) =>
     {
         try {
             Board b = new Board(4, 4);
             Array vals = Enum.GetValues(typeof(Orb));
             for (int i = 0; i < b.Height; i++)
                 for (int j = 0; j < b.Width; j++)
                 {
                     b.Orbs[i, j] = (i + j) % 2 == 0 ? Orb.Red : Orb.Blue;
                     b.Orbs[i, j] = (Orb) vals.GetValue(1 + (i + j) % 5);
                 }
             var p = DfsSolver.GetBestPath(b);
             var b2 = b.GetBoardsAfterPath(p.Start.Item1, p.Start.Item2, p.Actions);
             Board opt = SAASSolver.GetOptimalBoards(b, SAASSolver.Options.Default, BoardScorer.Options.Horus).First();
             var b3 = new Board(opt);
             b3.GetCombos(false);
             var p2 = SAASSolver.GetBestPath(b, SAASSolver.Options.Default, BoardScorer.Options.Horus);
             var b4 = b.GetBoardsAfterPath(p2.Start.Item1, p2.Start.Item2, p2.Actions);
             //await context.Response.WriteAsync(JsonConvert.SerializeObject(p));
             //return;
             await context.Response.WriteAsync(""
                 //+ JsonConvert.SerializeObject(p)
                 //+ "\n\n\n"
                 //+ JsonConvert.SerializeObject(b)
                 //+ "\n\n\n"
                 //+ JsonConvert.SerializeObject(b2)
                 + b.ToString()
                 + b2.Item1.ToString()
                 + b2.Item2.ToString()
                 + "\n\n"
                 + b2.Item1.Score(BoardScorer.Options.Horus)
                 + "\n\nSAAS optimal:"
                 + opt.ToString()
                 + b3.ToString()
                 + "\n\n"
                 + opt.Score(BoardScorer.Options.Horus)
                 + "\n\n"
                 + JsonConvert.SerializeObject(p2)
                 + b4.Item1.ToString()
                 + b4.Item2.ToString()
             );
         }
         catch (Exception ex)
         {
             await context.Response.WriteAsync(ex.ToString());
         }
     });
 }
예제 #5
0
 public string SolveBoardOne(string path, int rows, int cols, int width, int height, int w_off, int h_off)
 {
     Board b = new Board(5, 6);
     b.Orbs = new Orb[,]
     {
         { Orb.Green, Orb.Heal, Orb.Light, Orb.Green, Orb.Green, Orb.Red },
         { Orb.Dark, Orb.Blue, Orb.Red, Orb.Red, Orb.Blue, Orb.Light },
         { Orb.Heal, Orb.Red, Orb.Heal, Orb.Dark, Orb.Blue, Orb.Blue},
         { Orb.Green, Orb.Green, Orb.Dark, Orb.Light, Orb.Dark, Orb.Dark},
         { Orb.Dark, Orb.Green, Orb.Dark, Orb.Light, Orb.Red, Orb.Green}
     };
     return JsonConvert.SerializeObject(BeamDfs.GetBestPath(b, BoardScorer.Options.Horus));
 }
예제 #6
0
파일: Board.cs 프로젝트: toraora/PadPlayer
 public bool EqualsBoard(Board b, bool ignoreNone = false)
 {
     for (int i = 0; i < Height; i++)
         for (int j = 0; j < Width; j++)
         {
             if (ignoreNone && (Orbs[i, j] == Orb.None || b.Orbs[i, j] == Orb.None))
                 continue;
             if (Orbs[i, j] != b.Orbs[i, j]
                 || Enhancements[i, j] != b.Enhancements[i, j])
                 return false;
         }
     return true;
 }
예제 #7
0
 public bool TestBoardEq()
 {
     Board b = new Board(4, 4);
     Board b2 = new Board(b);
     Array vals = Enum.GetValues(typeof(Orb));
     for (int i = 0; i < b.Height; i++)
         for (int j = 0; j < b.Width; j++)
         {
             b.Orbs[i, j] = (i + j) % 2 == 0 ? Orb.Red : Orb.Blue;
             b.Orbs[i, j] = (Orb)vals.GetValue(1 + (i + j) % 5);
             if (i == 0)
                 b2.Orbs[i, j] = b.Orbs[i, j];
         }
     return b2.EqualsBoard(b, false);
 }
예제 #8
0
파일: Board.cs 프로젝트: toraora/PadPlayer
 public Tuple<Board, Board, List<Combo>> GetBoardsAfterPath(int y, int x, List<int[]> path)
 {
     Board b = new Board(this);
     foreach (var direction in path)
     {
         var newY = y + direction[0];
         var newX = x + direction[1];
         Orb temp = b.Orbs[newY, newX];
         b.Orbs[newY, newX] = b.Orbs[y, x];
         b.Orbs[y, x] = temp;
         y = newY;
         x = newX;
     }
     Board clear = new Board(b);
     var combos = clear.GetCombos(false);
     return new Tuple<Board, Board, List<Combo>>(b, clear, combos);
 }
예제 #9
0
        public string TestHeuristic()
        {
            Board b = new Board(6, 6);
            Array vals = Enum.GetValues(typeof(Orb));
            for (int i = 0; i < b.Height; i++)
                for (int j = 0; j < b.Width; j++)
                    b.Orbs[i, j] = Orb.Red;

            Board b2 = new Board(b);
            b.Orbs[0, 0] = Orb.Blue;
            b.Orbs[3, 3] = Orb.Blue;
            b2.Orbs[1, 1] = Orb.Blue;
            b2.Orbs[2, 2] = Orb.Blue;
            b.Orbs[3, 0] = Orb.Green;
            b.Orbs[0, 3] = Orb.Green;
            b2.Orbs[1, 2] = Orb.Green;
            b2.Orbs[2, 1] = Orb.Green;

            SAASSolver.Heuristic h = SAASSolver.Options.Default.HeuristicGen(b);
            return h(b2).ToString();
        }
예제 #10
0
        public static Path GetBestPath(Board b, Options o, BoardScorer.Options bso)
        {
            Path bestPath = new Path();
            object pathLock = new object();

            Parallel.For(0, b.Height, i =>
            {
                //for (int i = 0; i < b.Height; i++)
                Parallel.For(0, b.Width, j =>
                {
                    //for (int j = 0; j < b.Width; j++)
                    var curPath = GetBestPathFrom(b, o, i, j, bso);
                    lock (pathLock)
                    {
                        if (curPath.Score > bestPath.Score)
                            bestPath = curPath;
                    }
                });
            });

            return bestPath;
        }
예제 #11
0
 public string TestSAAS(string path, int rows, int cols, int width, int height, int w_off, int h_off)
 {
     path = Uri.UnescapeDataString(path);
     Console.WriteLine(path);
     Bitmap bmp = new Bitmap(path);
     Board b = PadImage.BoardFromBitmap(rows, cols, height, width, h_off, w_off, bmp);
     Board opt = SAASSolver.GetOptimalBoards(b, SAASSolver.Options.Default, BoardScorer.Options.Horus).First();
     var b3 = new Board(opt);
     b3.GetCombos(false);
     //var p2 = SAASSolver.GetBestPathSA(b, SAASSolver.Options.Default, BoardScorer.Options.Horus);
     //var b4 = b.GetBoardsAfterPath(p2.Start.Item1, p2.Start.Item2, p2.Actions);
     return ""
         + b.ToString()
         + "\n\nSAAS optimal:"
         + opt.ToString()
         + b3.ToString()
         + "\n\n"
         + opt.Score(BoardScorer.Options.Horus)
         + "\n\n";
       //  + JsonConvert.SerializeObject(p2)
       //  + b4.Item1.ToString()
       //  + b4.Item2.ToString();
 }
예제 #12
0
        private static Path GetBestPathFrom(Board b, Options o, int y, int x, BoardScorer.Options bso)
        {
            Path bestPath = new Path();
            PriorityQueue<Tuple<Board, Path>, double> paths = new PriorityQueue<Tuple<Board, Path>, double>();
            paths.Enqueue(new Tuple<Board, Path>(b, new Path
            {
                Start = new Tuple<int, int>(y, x),
                Current = new Tuple<int, int>(y, x),
                Depth = 1,
                Score = b.Score(bso)
            }));
            int depth = 0;
            while (depth++ < o.MaxDepth)
            {
               // Console.WriteLine("currently at depth {0}...", depth);
                PriorityQueue<Tuple<Board, Path>, double> newPaths = new PriorityQueue<Tuple<Board, Path>, double>();
                while (paths.Count != 0)
                {
                    var cur = paths.Dequeue();
                    var curPath = cur.Item2;
                    var curBoard = cur.Item1;
                    if (curPath.Score > bestPath.Score)
                        bestPath = curPath;

                    //if (paths.Count() > o.WhenToPrune)
                    //{
                    //    var newPaths = new Stack<Tuple<Board, Path>>();
                    //    foreach (var path in paths.OrderByDescending(p => p.Item2.Score).Take(o.NumToKeep).Reverse())
                    //        newPaths.Push(path);
                    //    paths = newPaths;
                    //}

                    foreach (var direction in Board.MoveDirections)
                    {
                        if (curPath.Length != 0 &&
                            curPath.Actions.Last()[0] == -direction[0] &&
                            curPath.Actions.Last()[1] == -direction[1])
                            continue;
                        var newY = curPath.Current.Item1 + direction[0];
                        var newX = curPath.Current.Item2 + direction[1];
                        if (newY < 0 || newY >= b.Height ||
                            newX < 0 || newX >= b.Width)
                            continue;
                        Board newBoard = new Board(curBoard);
                        Orb tempOrb = newBoard.Orbs[newY, newX];
                        newBoard.Orbs[newY, newX] = newBoard.Orbs[curPath.Current.Item1, curPath.Current.Item2];
                        newBoard.Orbs[curPath.Current.Item1, curPath.Current.Item2] = tempOrb;
                        var newPath = new List<int[]>(curPath.Actions);
                        newPath.Add(direction);
                        double score = newBoard.Score(bso) - curPath.Depth / 100;
                        newPaths.Enqueue(new Tuple<Board, Path>(newBoard, new Path
                        {
                            Start = curPath.Start,
                            Current = new Tuple<int, int>(newY, newX),
                            Depth = curPath.Depth + 1,
                            Score = score,
                            Actions = newPath
                        }), score);
                    }
                }
                paths = newPaths.TrimToSize(o.BeamWidth);
            }
            return bestPath;
        }
예제 #13
0
파일: Board.cs 프로젝트: toraora/PadPlayer
 public Board(Board b)
     : this(b.Height, b.Width)
 {
     Array.Copy(b.Orbs, Orbs, b.Height * b.Width);
     Array.Copy(b.Enhancements, Enhancements, b.Height * b.Width);
 }
예제 #14
0
 public static Path GetBestPath(Board b)
 {
     return GetBestPath(b, Options.Default);
 }
예제 #15
0
파일: Board.cs 프로젝트: toraora/PadPlayer
 public List<Combo> GetCombos(bool copy = true)
 {
     Board copyBoard = new Board(this);
     if (!copy)
         copyBoard = this;
     List<Combo> combos = new List<Combo>();
     List<Combo> lastComboSet = new List<Combo>();
     do
     {
         lastComboSet = copyBoard.GetCombosWithoutGravity();
         combos.AddRange(lastComboSet);
         copyBoard.GravityFill();
     } while (lastComboSet.Any());
     return combos;
 }
예제 #16
0
 public static Path GetBestPath(Board b, BoardScorer.Options bso)
 {
     return GetBestPath(b, Options.Default, bso);
 }
예제 #17
0
파일: Board.cs 프로젝트: toraora/PadPlayer
        // this function changes the board! make a copy before calling it
        private List<Combo> GetCombosWithoutGravity()
        {
            List<Combo> combos = new List<Combo>();
            Board comboBoard = new Board(Height, Width);
            for (int i = 0; i < Height; i++)
                for (int j = 1; j < Width - 1; j++)
                {
                    if (Orbs[i, j] == Orb.None)
                        continue;
                    if (Orbs[i, j - 1] == Orbs[i, j] && Orbs[i, j] == Orbs[i, j + 1])
                    {
                        comboBoard.Orbs[i, j - 1] = Orbs[i, j];
                        comboBoard.Orbs[i, j] = Orbs[i, j];
                        comboBoard.Orbs[i, j + 1] = Orbs[i, j];
                    }
                }
            for (int i = 1; i < Height - 1; i++)
                for (int j = 0; j < Width; j++)
                {
                    if (Orbs[i, j] == Orb.None)
                        continue;
                    if (Orbs[i - 1, j] == Orbs[i, j] && Orbs[i, j] == Orbs[i + 1, j])
                    {
                        comboBoard.Orbs[i - 1, j] = Orbs[i, j];
                        comboBoard.Orbs[i, j] = Orbs[i, j];
                        comboBoard.Orbs[i + 1, j] = Orbs[i, j];
                    }
                }
            // row check
            bool[] isRows = new bool[Height];
            for (int i = 0; i < isRows.Length; i++)
                isRows[i] = true;
            for (int i = 0; i < Height; i++)
                for (int j = 1; j < Width; j++)
                    isRows[i] = isRows[i] ? Orbs[i, j] == Orbs[i, 0] : false;

            Stack<Tuple<int, int>> orbStack = new Stack<Tuple<int, int>>();
            HashSet<Tuple<int, int>> visited = new HashSet<Tuple<int, int>>();
            for (int i = 0; i < Height; i++)
                for (int j = 0; j < Width; j++)
                {
                    int comboNumOrbs = 0;
                    int comboNumEnhances = 0;
                    bool isRow = true;
                    Orb orbType = Orbs[i, j];

                    if (comboBoard.Orbs[i, j] == Orb.None)
                        continue;

                    orbStack.Clear();
                    orbStack.Push(new Tuple<int, int>(i, j));
                    while (orbStack.Any())
                    {
                        var curLoc = orbStack.Pop();
                        if (visited.Contains(new Tuple<int, int>(curLoc.Item1, curLoc.Item2)))
                            continue;
                        comboBoard.Orbs[curLoc.Item1, curLoc.Item2] = Orb.None;
                        Orbs[curLoc.Item1, curLoc.Item2] = Orb.None;
                        comboNumOrbs++;
                        if (Enhancements[curLoc.Item1, curLoc.Item2])
                            comboNumEnhances++;
                        isRow = isRow ? isRows[curLoc.Item1] : false;
                        visited.Add(curLoc);
                        foreach (var direction in MatchDirections)
                        {
                            var newY = curLoc.Item1 + direction[0];
                            var newX = curLoc.Item2 + direction[1];
                            if (newY < 0 || newY >= Height ||
                                newX < 0 || newX >= Width ||
                                visited.Contains(new Tuple<int, int>(newY, newX)) ||
                                orbType != comboBoard.Orbs[newY, newX])
                                continue;
                            orbStack.Push(new Tuple<int, int>(newY, newX));
                        }
                    }

                    combos.Add(new Combo
                    {
                        OrbType = orbType,
                        NumOrbs = comboNumOrbs,
                        NumEnahcements = comboNumEnhances,
                        IsRow = isRow
                    });
                }

            return combos;
        }