예제 #1
0
        public long evaluateMove(Grid state, Move move)
        {
            var newState = GameLogic.MakeMove(state, move);
            if (newState == state)
                return long.MinValue;

            return maxNodeValue(newState, 0);
        }
예제 #2
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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
 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);
 }
예제 #6
0
        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;
        }
예제 #7
0
        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;
        }
예제 #8
0
        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;
        }
예제 #9
0
        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;
        }
예제 #10
0
        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;
        }
예제 #11
0
        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;
        }
예제 #12
0
 public abstract Move MakeDecision(Grid state);