public override void Solve(string filename)
        {
            this.LoadFiles(filename);

            int numTests = this.ReadInt();

            for (int i = 1; i <= numTests; i++)
            {
                Console.WriteLine("Solving Case {0}", i);

                var line = this.ReadIntArr();
                int numTurnActions = line[0];
                int numRows = line[1];
                int numCols = line[2];

                var turnActions = new Dictionary<int, bool>();
                for (int j = 0; j < numTurnActions; j++)
                {
                    var lineStr = this.ReadLine().Split(' ');
                    turnActions[int.Parse(lineStr[0])] = lineStr[1] == "L";
                }

                var eatenFood = new HashSet<Point>();

                int timeSinceLastEvent = 0;
                int timer = 1;
                var snake = new Snake(numRows, numCols);
                while (timer < 1e9)
                {
                    if (timeSinceLastEvent >= numRows*2 && timeSinceLastEvent >= numCols*2)
                    {
                        // nothing has happened in a long time, so end
                        break;
                    }

                    // try to move
                    var newHead = snake.CalculateNextMove();

                    // eat if there is food
                    bool hasFood = false;
                    if ((newHead.X + newHead.Y) % 2 == 1)
                    {
                        // note that we keep track of the food AFTER it has been eaten, rather than before - as it takes too long to populate a list of uneaten food on the large board
                        // large board = 1,000,000 * 1,000,000 cells = 1,000,000,000,000 cells / 2 = 500,000,000 food = TOO MUCH TO HANDLE
                        var headPoint = new Point(newHead.X, newHead.Y);
                        hasFood = !eatenFood.Contains(headPoint);
                        eatenFood.Add(headPoint);
                        if (hasFood)
                        {
                            timeSinceLastEvent = 0;
                        }
                    }
                    // move the snake
                    if (!snake.Step(newHead, hasFood))
                    {
                        // WE DEAD
                        break;
                    }

                    // do the input action if there is one for this second
                    if (turnActions.ContainsKey(timer))
                    {
                        bool turnLeft = turnActions[timer];
                        snake.DoTurn(turnLeft);
                        timeSinceLastEvent = 0;
                    }

                    timeSinceLastEvent++;
                    timer++;
                }
                this.Outfile.WriteLine("Case #{0}: {1}", i, snake.Length);
            }
        }