public long evaluateMove(Grid state, Move move) { var newState = GameLogic.MakeMove(state, move); if (newState == state) return long.MinValue; return maxNodeValue(newState, 0); }
public Tuple<Grid, Grid> parse(string testCase) { var lines = testCase.Split('\n').Select(l => l.Trim()).ToArray(); var init = new Grid(lines.Skip(1).Take(4).ToArray()); var exp = new Grid(lines.Skip(6).Take(4).ToArray()); return Tuple.Create(init, exp); }
public Tuple<Grid, Move, Grid> parse(string testCase) { var lines = testCase.Split('\n').Select(l=>l.Trim()).ToArray(); var init = new Grid(lines.Skip(1).Take(4).ToArray()); var exp = new Grid(lines.Skip(7).Take(4).ToArray()); var move = (Move) Enum.Parse(typeof (Move), lines[6]); return Tuple.Create(init, move, exp); }
/// <summary> /// Rotates the grid clockwise /// </summary> public static Grid RotateCW(Grid grid) { var newGrid = new int[4, 4]; for (var x = 0; x < 4; x++) for (var y = 0; y < 4; y++) { newGrid[3 - y, x] = grid[x, y]; } return new Grid(newGrid); }
public static Grid MakeMove(Grid grid, Move move) { var newGrid = new int[4, 4]; switch (move) { case Move.Left: for (var y = 0; y < 4; y++) { var nonZeroes = merge(grid.GetRow(y).Where(n => n != 0).ToArray()); var l = nonZeroes.Length; for (var i = 0; i < l; i++) { newGrid[i, y] = nonZeroes[i]; } } break; case Move.Right: for (var y = 0; y < 4; y++) { var nonZeroes = merge(grid.GetRow(y).Where(n => n != 0).ToArray().Reverse().ToArray()).Reverse().ToArray(); var l = nonZeroes.Length; for (var i = 0; i < l; i++) { newGrid[i + (4-l), y] = nonZeroes[i]; } } break; case Move.Up: for (var x = 0; x < 4; x++) { var nonZeroes = merge(grid.GetColumn(x).Where(n => n != 0).ToArray()); var l = nonZeroes.Length; for (var i = 0; i < l; i++) { newGrid[x, i] = nonZeroes[i]; } } break; case Move.Down: for (var x = 0; x < 4; x++) { var nonZeroes = merge(grid.GetColumn(x).Where(n => n != 0).ToArray().Reverse().ToArray()).Reverse().ToArray(); var l = nonZeroes.Length; for (var i = 0; i < l; i++) { newGrid[x, i + (4-l)] = nonZeroes[i]; } } break; default: throw new ArgumentOutOfRangeException("move"); } return new Grid(newGrid); }
public override Move MakeDecision(Grid state) { var simulationResults = new Dictionary<Move, long>(); foreach (var move in MOVES) { simulationResults.Add(move, evaluateMove(state, move)); } var decision = simulationResults.OrderByDescending(p => p.Value).First(); //Console.WriteLine(String.Join(" ", simulationResults.Select(p => p.Value.ToString()).ToArray()) + ">" + decision.Value); return decision.Key; }
public long minNodeValue(Grid state, int currDepth) { var value = long.MaxValue; var nextStates = GameLogic.NextPossibleWorldStates(state); if (nextStates.Count == 0) return long.MinValue; foreach (var nextState in nextStates) { var newVal = maxNodeValue(nextState, currDepth + 1); value = Math.Min(value, newVal); } return value; }
public static List<Grid> NextPossibleWorldStates(Grid state) { var nextStates = new List<Grid>(); for (var x = 0; x < 4; x++) for (var y = 0; y < 4; y++) if (state[x, y] == 0) { var newState = state.CloneMatrix(); newState[x, y] = 2; nextStates.Add(new Grid(newState)); } return nextStates; }
public KeyValuePair<Move, long> makeDecision(Grid state) { var simulationResults = new Dictionary<Move, long>(); foreach (var move in MOVES) { var newState = GameLogic.MakeMove(state, move); if (newState == state) continue; // don't make unnecessary moves simulationResults.Add(move, _heuristic(newState)); } var decision = simulationResults.OrderByDescending(p => p.Value).First(); //Console.WriteLine(String.Join(" ", simulationResults.Select(p=>p.Value.ToString()).ToArray()) + ">" + decision.Value); return decision; }
public long maxNodeValue(Grid state, int currDepth) { if (currDepth >= MAX_DEPTH) return _heuristic(state); var value = long.MinValue; foreach (var move in MOVES) { var newState = GameLogic.MakeMove(state, move); if (newState == state) continue; long newVal; if (state.EmptyCellsNo > 3) newVal = randomNodeValue(newState, currDepth+1); else newVal = minNodeValue(newState, currDepth + 1); value = Math.Max(value, newVal); } return value; }
public long randomNodeValue(Grid state, int currDepth) { var value = 0L; var nextStates = GameLogic.NextPossibleWorldStates(state); if (nextStates.Count == 0) return long.MinValue; foreach (var nextState in nextStates) { var newVal = maxNodeValue(nextState, currDepth + 1); value += newVal/nextStates.Count; } return value; }
public abstract Move MakeDecision(Grid state);