public bool TryGetPermutation(byte *output, out uint permutationHash) { for (; currentRow < 4; currentRow++) { for (; currentColumn < 4; currentColumn++) { if (grid[currentRow * 4 + currentColumn] == 0) { GridFunctions.CloneGrid(collapsedGrid, output); GridFunctions.CloneRow(grid + rowDelta * currentRow + offset, output + rowDelta * currentRow + offset, columnDelta); output[currentRow * 4 + currentColumn] = 1; GridFunctions.collapseRow(output + rowDelta * currentRow + offset, columnDelta); uint rowHash = GridFunctions.GetRowHash(output + rowDelta * currentRow + offset, columnDelta); rowHash <<= 2; rowHash |= (uint)currentRow; permutationHash = rowHash; currentColumn++; return(true); } } currentColumn = 0; } permutationHash = 0; return(false); }
private unsafe int FinalScoreForGrid(byte *grid) { //Console.WriteLine("\tEmpty: " + GridFunctions.CountEmptySquares(grid)); //Console.WriteLine("\tsum values: " + GridFunctions.SumValuesInGrid(grid)); //return (ulong)GridFunctions.CountEmptySquares(grid); //return (ulong)(GridFunctions.CountEmptySquares(grid) + GridFunctions.SumValuesInGrid(grid)); return(GridFunctions.SquareSum(grid)); //int[] snake = new int[] //{ // 0, 1, 2, 3, 7, 6, 5, 4, 8, 9, 10, 11 //}; //ulong score = 0; //for (int i = 0; i < snake.Length - 1; i++) //{ // if (grid[snake[i]] < grid[snake[i + 1]]) // { // return score; // } // score += (ulong)(1 << grid[snake[i]]) * (ulong)(1 << grid[snake[i]]); //} //return score; }
public unsafe Direction Solve(byte *grid) { byte *[] grids = new byte *[4]; for (int i = 0; i < 4; i++) { grids[i] = GridFunctions.CloneGrid(grid); } Dictionary <Direction, int> scores = new Dictionary <Direction, int>(); int j = 0; foreach (Direction direction in Enum.GetValues(typeof(Direction))) { if (GridFunctions.GridCanCollapse(grid, direction) == false) { scores[direction] = -1; continue; } GridFunctions.CollapseGridInPlace(grids[j], direction); scores[direction] = GridFunctions.CountEmptySquares(grids[j]); } return(scores.OrderByDescending(x => x.Value).First().Key); }
public unsafe Direction Solve(byte *grid) { GridStack stack = new GridStack(128); GridFunctions.CloneGrid(grid, stack.current); Dictionary <Direction, int> scores = new Dictionary <Direction, int>(); foreach (Direction direction in Enum.GetValues(typeof(Direction))) { //Console.WriteLine(direction); if (GridFunctions.GridCanCollapse(grid, direction) == false) { //Console.WriteLine("\tCant Collapse"); continue; } stack.pushCurrent(); GridFunctions.CollapseGridInPlace(stack.current, direction); scores[direction] = ScoreForGrid(stack, 1); stack.pop(); //Console.WriteLine("\tScore: " + scores[direction]); } return(scores.OrderByDescending(x => x.Value).First().Key); }
private unsafe int FinalScoreForGrid(byte *grid) { //Console.WriteLine("\tEmpty: " + GridFunctions.CountEmptySquares(grid)); //Console.WriteLine("\tsum values: " + GridFunctions.SumValuesInGrid(grid)); //return GridFunctions.CountEmptySquares(grid); //return GridFunctions.CountEmptySquares(grid) + GridFunctions.SumValuesInGrid(grid); return(GridFunctions.SquareSum(grid)); }
public unsafe Direction Solve(byte *grid) { this.current = data; int[] scores = new int[4]; byte *tempGrid = GridFunctions.CreateGrid(); for (int direction = 0; direction < 4; direction++) { //Console.WriteLine(direction); if (GridFunctions.GridCanCollapse(grid, (Direction)direction) == false) { //Console.WriteLine("\tCant Collapse"); //GridFunctions.printGrid(grid); scores[(int)direction] = 0; continue; } GridFunctions.CloneGrid(grid, tempGrid); GridFunctions.CollapseGridInPlace(tempGrid, (Direction)direction); int permutations = GridFunctions.CountEmptySquares(grid); const int depth = 2; if (permutations > 5) { scores[direction] = ScoreForGrid(tempGrid, depth); } else if (permutations < 3) { scores[direction] = ScoreForGrid(tempGrid, depth + 2); } else { scores[direction] = ScoreForGrid(tempGrid, depth + 1); } //Console.WriteLine("\tScore: " + scores[direction]); } GridFunctions.FreeGrid(tempGrid); int max = 0; Direction maxDir = Direction.left; for (int i = 0; i < 4; i++) { if (scores[i] > max) { max = scores[i]; maxDir = (Direction)i; } } return(maxDir); //return scores.OrderByDescending(x => x.Value).First().Key; }
private unsafe int ScoreForGrid(byte *grid, int depth) { if (GridFunctions.HasEmptySquares(grid) == false) { return(GridFunctions.SumValuesInGrid(grid)); } int permutations = GridFunctions.CountEmptySquares(grid); int[] scores = new int[permutations]; current += 16; foreach (var subDirection in new[] { (Direction.left, Direction.right), (Direction.up, Direction.down) })
private unsafe int ScoreForGrid(byte *grid, int depth) { if (GridFunctions.HasEmptySquares(grid) == false) { return(GridFunctions.SumValuesInGrid(grid)); } int permutations = GridFunctions.CountEmptySquares(grid); int[] scores = new int[permutations]; current += 16; foreach (Direction subDirection in Enum.GetValues(typeof(Direction))) { Permutator permutator = new Permutator(grid, subDirection); Dictionary <uint, int> scoreCache = new Dictionary <uint, int>(); int k = 0; while (permutator.TryGetPermutation(current, out uint permutationHash)) { int score; if (scoreCache.ContainsKey(permutationHash)) { score = scoreCache[permutationHash]; } else { if (depth == 1) { score = FinalScoreForGrid(current); } else { score = ScoreForGrid(current, depth - 1); } scoreCache.Add(permutationHash, score); } scores[k] = Math.Max(scores[k], score); k++; } } current -= 16; //GridFunctions.FreeGrid(tempGrid); return((int)scores.Average()); }
private unsafe int ScoreForGrid(GridStack stack, int depth) { int permutations = GridFunctions.CountEmptySquares(stack.current); if (permutations == 0) { return(0); } int startIndex = 0; int score = int.MaxValue; for (int i = 0; i < permutations; i++) { stack.pushCurrent(); GridFunctions.TryAddPermutation(stack.current, ref startIndex); //if(!success) //{ // //GridFunctions.printGrid(grid); // //GridFunctions.printGrid((grids + i * 16)); // //GridFunctions.TryAddPermutation((grids + i * 16), startIndex, out startIndex); // throw new Exception(); //} startIndex++; int subScore = -1; foreach (Direction subDirection in Enum.GetValues(typeof(Direction))) { stack.pushCurrent(); GridFunctions.CollapseGridInPlace(stack.current, subDirection); if (depth == 1) { subScore = Math.Max(subScore, FinalScoreForGrid(stack.current)); } else { subScore = Math.Max(subScore, ScoreForGrid(stack, depth - 1)); } stack.pop(); } stack.pop(); score = Math.Min(score, subScore); } return(score); }
public Permutator(byte *grid, Direction direction) { this.grid = GridFunctions.CreateGrid(); GridFunctions.CloneGrid(grid, this.grid); this.direction = direction; collapsedGrid = GridFunctions.CreateGrid(); GridFunctions.CloneGrid(grid, this.collapsedGrid); GridFunctions.CollapseGridInPlace(collapsedGrid, direction); currentRow = 0; currentColumn = 0; GridFunctions.GetDeltas(direction, out offset, out rowDelta, out columnDelta); }