public TileModel(TileModel tile1, TileModel tile2) { if (tile1.Value != tile2.Value) throw new Exception("Only tiles with same value can be merged"); Value = tile1.Value + 1; MergedFrom1 = tile1; MergedFrom2 = tile2; }
/// <summary> /// Adds a tile in a random position /// </summary> public void Move(GridModel grid) { var cells = grid.AvailableCells(); if (cells.Any()) { int value = _rand.NextDouble() < _percentageOfValue1 ? 1 : 2; var tile = new TileModel(value); var position = cells[_rand.Next(cells.Length)]; tile.Position = position; } }
public bool Move(GridModel grid, Direction direction, out int score) { score = 0; if (direction == Direction.None) return false; var vector = Vector.FromDirection(direction); var moved = false; var alreadyMerged = new List<TileModel>(); // Traverse the grid in the right direction and move tiles foreach (int x in grid.TraversalsX(direction)) { foreach (int y in grid.TraversalsY(direction)) { CellModel cell = grid[x, y]; if (cell.IsOccupied) { TileModel tile = cell.Tile; CellModel nextCell; CellModel farthestCell = grid.FindFarthestPosition(cell, vector, out nextCell); TileModel nextTile = (nextCell == null) ? null : nextCell.Tile; // Only one merger per row traversal? if (nextTile != null && nextTile.Value == tile.Value && !alreadyMerged.Contains(nextTile)) { var merged = new TileModel(tile, nextTile); alreadyMerged.Add(merged); tile.Position = null; nextTile.Position = null; merged.Position = nextCell; moved = true; // Update the score score += (int)Math.Pow(2, merged.Value); } else { var oldPosition = tile.Position; tile.Position = farthestCell; if ((oldPosition.PosX != tile.Position.PosX) || (oldPosition.PosY != tile.Position.PosY)) moved = true; } } } } return moved; }
public GridModel(int size) { LeanAndMeanModel = true; SizeX = size; SizeY = size; _cells = new List<CellModel>(SizeX * SizeY); for (int i = 0; i < SizeX * SizeY; i++) { var cell = new CellModel(i % SizeY, i / SizeX); var tile = new TileModel(1); tile.Position = cell; _cells.Add(cell); } //Reset(); }
/// <summary> /// Create a deep copy of a grid, history of moves and merges removed. /// </summary> /// <param name="grid"></param> public GridModel(GridModel grid) { SizeX = grid.SizeX; SizeY = grid.SizeY; _cells = new List<CellModel>(SizeX * SizeY); for (int i = 0; i < SizeX * SizeY; i++) { int x = i % SizeY; int y = i / SizeX; var cell = new CellModel(x, y); _cells.Add(cell); var sourceCell = grid[x,y]; if (sourceCell.IsOccupied) { var tileCopy = new TileModel(sourceCell.Tile); tileCopy.Position = cell; } } }
private double Minimizer(GridModel grid, int depth, double alpha, double beta) { // computer's turn, we'll do heavy pruning to keep the branching factor low var availableCells = grid.AvailableCells().ToList(); // try out all combinations possible foreach (var value in new int[] { 1, 2 }) { foreach (CellModel cell in availableCells) { var tile = new TileModel(value); tile.Position = cell; beta = Math.Min(beta, AlphaBetaSearch(grid, depth, true, alpha, beta)); tile.Position = null; if (beta < alpha) // pruning { return alpha; } } } /* // try a 2 and 4 in each cell and measure how annoying it is // with metrics from eval //var scores = { 2: [], 4: [] }; foreach (var value in new int[] { 1, 2 }) { foreach (CellModel cell in availableCells) { scores[value].push(null); var tile = new TileModel(value); tile.Position = cell; scores[value][i] = -grid.Smoothness() + grid.Islands(); tile.Position = null; } } // now just pick out the most annoying moves var candidates = new List<CellModel>(); var maxScore = Math.Max(Math.Max(null, scores[2]), Math.Max(null, scores[4])); foreach (var value in new int[] { 1, 2 }) { for (var i = 0; i < scores[value].length; i++) { if (scores[value][i] >= maxScore) { candidates.Add(cells[i]); } } } // search on each candidate foreach (CellModel position in candidates) { } */ return beta; }
internal void Reset() { Tile = null; }
public TileModel(TileModel source) { Value = source.Value; }
public TileViewModel(TileModel model) { Model = model; }