Command Prompt TicTacToe in C# I wrote a basic command prompt Tic Tac Toe Game. I want to know what can be improved in terms of modeling and what mistakes I've made (if any).

void Main()
{
    TicTacToeBoard board = new TicTacToeBoard();

    while(!board.GameOver())
    {
        var i = int.Parse(Console.ReadLine());
        board.MakeMove(i);
        Console.WriteLine(board.DrawBoard());
    }   
}

class TicTacToeBoard
{
    SquareType[] board = new SquareType[9];

    SquareType currentType = SquareType.X;

    public void MakeMove(int i)
    {
        if(board[i] != SquareType.Empty) return;
            board[i] = currentType;
            currentType = OppositeType(currentType);
    }

    SquareType OppositeType(SquareType squareType) =&gt; 
        squareType == SquareType.X ? SquareType.O : SquareType.X;

    public bool GameOver()
    {
        return WeHaveWinner() || WeHaveDraw();
    }

    bool WeHaveWinner()
    {
        var winningIndecies = new[]
        {
            new[]{1,2,3},
            new[]{4,5,6},
            new[]{7,8,9},
            new[]{1,5,9},
            new[]{3,5,7}
        };

        foreach(var indecies in winningIndecies)
        {
            var squares = indecies.Select(i =&gt; board[i - 1]);
            if(squares.Any(x =&gt; x == SquareType.Empty)) continue;
            else if(squares.Distinct().Count() == 1) return true;
        }
        return false;
    }

    bool WeHaveDraw() =&gt; !WeHaveWinner() &amp;&amp; board.All(x =&gt; x != SquareType.Empty);


    public string DrawBoard()
        =&gt; $@"|{board[0]},{board[1]},{board[2]}|
|{board[3]},{board[4]},{board[5]}|
|{board[6]},{board[7]},{board[8]}|".Replace("Empty","  ");
}

enum SquareType { Empty, X, O }
Overall it looks good to me.
A few points though:


int.Parse will throw if Console.ReadLine returns a non integer. Perhaps an int.TryParse and display some help (position: 0 - 8)
It's a small app but since for the whole lifetime of your application, in each iteration you'll call WeHaveWinner. I'd initialize that array as a field to that class on object construction.
On WeHaveWinner you'll (possibly) be enumerating the return of .Select() twice. Consider calling ToList() on it.
The main method, could be:



      do
        {
            var i = int.Parse(Console.ReadLine());
            board.MakeMove(i);
            Console.WriteLine(board.DrawBoard());
        } while (!board.GameOver());



This way you won't be checking for winnings before the first input


Your string replace at the end on Empty could lead to a issue if the Enum Empty was renamed. Consider replacing (SquareType.Empty, " ")
You could consider replacing the Enum with a class, that would give you ability to use polymorphism. There you could override ToString to display (X or Y or empty) which would help you get rid of that String.Replace altogether.
Something along the lines of: https://stackoverflow.com/questions/1376312/whats-the-equivalent-of-javas-enum-in-c


+1 for the verbatin + interpolation