private static void WriteGridToConsole(Grid grid, bool isGameOver = false)
        {
            for (int r = grid.NumberOfRows; r > 0; r--)
            {
                Console.Write("|");

                for (int c = 1; c <= grid.NumberOfColumns; c++)
                {
                    if (grid.Counters.Any(counter => counter.PlayerType == PlayerType.Human && counter.Row == r && counter.Column == c))
                    {
                        Console.Write(" O |");
                    }
                    else if (grid.Counters.Any(counter => counter.PlayerType == PlayerType.Computer && counter.Row == r && counter.Column == c))
                    {
                        Console.Write(" X |");
                    }
                    else
                    {
                        Console.Write("   |");
                    }
                }

                Console.Write(Environment.NewLine);
            }

            if (!isGameOver)
            {
                Console.WriteLine("Please enter a column number. (1-6)" + Environment.NewLine);
            }
        }
        static void Main(string[] args)
        {
            while (true)
            {
                Grid grid = new Grid(6, 7);
                GameService gameService = new GameService();

                grid.CounterAdded += gameService.OnCounterAdded;

                while (gameService.GameStatus == GameStatus.NoWinner)
                {
                    if (!grid.IsComputersTurn)
                    {
                        WriteGridToConsole(grid);

                        string column = Console.ReadLine();

                        if (!grid.IsValidUserInput(column))
                        {
                            Console.WriteLine("Please enter a valid column number.");

                            continue;
                        }

                        if (!grid.IsColumnFull(Convert.ToInt32(column)))
                        {
                            grid.AddCounter(new Counter
                            {
                                Column = Convert.ToInt32(column),
                                PlayerType = PlayerType.Human
                            });

                            grid.IsComputersTurn = true;
                        }
                        else
                        {
                            Console.WriteLine("That column is full please select another.");
                        }
                    }
                    else
                    {
                        grid.TakeComputersTurn();

                        grid.IsComputersTurn = false;
                    }
                }

                WriteGridToConsole(grid, true);

                WriteGameResultToConsole(gameService);
            }
        }
        public void Human_Can_Not_Win_Game_Horizontally_With_Three_Connecting_Counters()
        {
            //Arrange
            Grid grid = new Grid(6, 7);
            GameService gameService = new GameService();

            grid.Counters.SingleOrDefault(c => c.Column == 1 && c.Row == 1).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 2 && c.Row == 1).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 3 && c.Row == 1).PlayerType = PlayerType.Human;

            //Act
            gameService.Horizontal(grid);

            //Assert
            Assert.AreEqual(GameStatus.NoWinner, gameService.GameStatus);
        }
        public void Human_Can_Not_Win_Game_Horizontally_If_There_Is_Gap_Inbetween_Four_Counters()
        {
            //Arrange
            Grid grid = new Grid(6, 7);
            GameService gameService = new GameService();

            grid.Counters.SingleOrDefault(c => c.Column == 1 && c.Row == 1).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 2 && c.Row == 1).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 4 && c.Row == 1).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 5 && c.Row == 1).PlayerType = PlayerType.Human;

            //Act
            gameService.Horizontal(grid);

            //Assert
            Assert.AreEqual(GameStatus.NoWinner, gameService.GameStatus);
        }
        public void Vertical(Grid grid)
        {
            for (int columnLoop = 0; columnLoop <= grid.NumberOfColumns; columnLoop++)
            {
                int connectingHumanCounters = 0;
                int connectingComputerCounters = 0;

                foreach (Counter counter in grid.Counters.Where(c => c.Column == columnLoop))
                {
                    switch (counter.PlayerType)
                    {
                        case PlayerType.Human:
                            connectingHumanCounters += 1;
                            connectingComputerCounters = 0;
                            break;
                        case PlayerType.Computer:
                            connectingComputerCounters += 1;
                            connectingHumanCounters = 0;
                            break;
                        case PlayerType.NotAssigned:
                            connectingHumanCounters = 0;
                            connectingComputerCounters = 0;
                            break;
                    }

                    if (connectingHumanCounters == 4)
                    {
                        this.GameStatus = GameStatus.HumanWon;
                    }

                    if (connectingComputerCounters == 4)
                    {
                        this.GameStatus = GameStatus.ComputerWon;
                    }
                }
            }
        }
        public void Horizontal(Grid grid)
        {
            for (int rowLoop = 1; rowLoop < grid.NumberOfRows; rowLoop++)
            {
                int connectingHumanCounters = 0;
                int connectingComputerCounters = 0;

                foreach (Counter counter in grid.Counters.Where(c => c.Row == rowLoop))
                {
                    switch (counter.PlayerType)
                    {
                        case PlayerType.Human:
                            connectingHumanCounters += 1;
                            connectingComputerCounters = 0;
                            break;
                        case PlayerType.Computer:
                            connectingComputerCounters += 1;
                            connectingHumanCounters = 0;
                            break;
                        case PlayerType.NotAssigned:
                            connectingHumanCounters = 0;
                            connectingComputerCounters = 0;
                            break;
                    }

                    if (connectingHumanCounters == 4)
                    {
                        this.GameStatus = GameStatus.HumanWon;
                    }

                    if (connectingComputerCounters == 4)
                    {
                        this.GameStatus = GameStatus.ComputerWon;
                    }
                }
            }
        }
        public void Human_Can_Win_Game_Horizontally_In_The_Middle_Of_The_Grid()
        {
            //Arrange
            Grid grid = new Grid(6, 7);
            GameService gameService = new GameService();

            grid.Counters.SingleOrDefault(c => c.Column == 1 && c.Row == 1).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 2 && c.Row == 1).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 3 && c.Row == 1).PlayerType = PlayerType.Computer;
            grid.Counters.SingleOrDefault(c => c.Column == 4 && c.Row == 1).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 5 && c.Row == 1).PlayerType = PlayerType.Human;

            //Winning moves
            grid.Counters.SingleOrDefault(c => c.Column == 2 && c.Row == 2).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 3 && c.Row == 2).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 4 && c.Row == 2).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 5 && c.Row == 2).PlayerType = PlayerType.Human;

            //Act
            gameService.Horizontal(grid);

            //Assert
            Assert.AreEqual(GameStatus.HumanWon, gameService.GameStatus);
        }
        public void Human_Can_Win_Game_Vertically()
        {
            //Arrange
            Grid grid = new Grid(6, 7);
            GameService gameService = new GameService();

            grid.Counters.SingleOrDefault(c => c.Column == 1 && c.Row == 1).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 1 && c.Row == 2).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 1 && c.Row == 3).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 1 && c.Row == 4).PlayerType = PlayerType.Human;

            //Act
            gameService.Vertical(grid);

            //Assert
            Assert.AreEqual(GameStatus.HumanWon, gameService.GameStatus);
        }
        public void Human_Can_Not_Win_Game_Diagonally_With_Computer_Counter_Inbetween_Four_Connecting_Counters()
        {
            //Arrange
            Grid grid = new Grid(6, 7);
            GameService gameService = new GameService();

            //Act
            grid.Counters.SingleOrDefault(c => c.Column == 1 && c.Row == 1).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 2 && c.Row == 2).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 3 && c.Row == 3).PlayerType = PlayerType.Computer;
            grid.Counters.SingleOrDefault(c => c.Column == 4 && c.Row == 4).PlayerType = PlayerType.Human;

            gameService.Diagonal(grid);

            //Assert
            Assert.AreEqual(GameStatus.NoWinner, gameService.GameStatus);
        }
        public void Human_Can_Win_Game_Diagonally_To_The_Left()
        {
            //Arrange
            Grid grid = new Grid(6, 7);
            GameService gameService = new GameService();

            //Act
            grid.Counters.SingleOrDefault(c => c.Column == 6 && c.Row == 1).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 5 && c.Row == 2).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 4 && c.Row == 3).PlayerType = PlayerType.Human;
            grid.Counters.SingleOrDefault(c => c.Column == 3 && c.Row == 4).PlayerType = PlayerType.Human;

            gameService.Diagonal(grid);

            //Assert
            Assert.AreEqual(GameStatus.HumanWon, gameService.GameStatus);
        }
        public void Diagonal(Grid grid)
        {
            List<Counter> humanCounters = grid.Counters.Where(c => c.PlayerType == PlayerType.Human).ToList();
            List<Counter> computerCounters = grid.Counters.Where(c => c.PlayerType == PlayerType.Computer).ToList();

            foreach (Counter counter in humanCounters)
            {
                if (humanCounters.Any(c => c.Column == (counter.Column + 1) && c.Row == (counter.Row + 1)) &&
                    humanCounters.Any(c => c.Column == (counter.Column + 2) && c.Row == (counter.Row + 2)) &&
                    humanCounters.Any(c => c.Column == (counter.Column + 3) && c.Row == (counter.Row + 3)))
                {
                    this.GameStatus = GameStatus.HumanWon;
                }

                if (humanCounters.Any(c => c.Column == (counter.Column - 1) && c.Row == (counter.Row + 1)) &&
                    humanCounters.Any(c => c.Column == (counter.Column - 2) && c.Row == (counter.Row + 2)) &&
                    humanCounters.Any(c => c.Column == (counter.Column - 3) && c.Row == (counter.Row + 3)))
                {
                    this.GameStatus = GameStatus.HumanWon;
                }
            }

            foreach (Counter counter in computerCounters)
            {
                if (computerCounters.Any(c => c.Column == (counter.Column + 1) && c.Row == (counter.Row + 1)) &&
                    computerCounters.Any(c => c.Column == (counter.Column + 2) && c.Row == (counter.Row + 2)) &&
                    computerCounters.Any(c => c.Column == (counter.Column + 3) && c.Row == (counter.Row + 3)))
                {
                    this.GameStatus = GameStatus.ComputerWon;
                }

                if (computerCounters.Any(c => c.Column == (counter.Column - 1) && c.Row == (counter.Row + 1)) &&
                    computerCounters.Any(c => c.Column == (counter.Column - 2) && c.Row == (counter.Row + 2)) &&
                    computerCounters.Any(c => c.Column == (counter.Column - 3) && c.Row == (counter.Row + 3)))
                {
                    this.GameStatus = GameStatus.ComputerWon;
                }
            }
        }