Skip to content

Board Game - Tic Tac Toe ✅

Design a Tic-tac-toe game that is played between two players on a nxn grid.

You may assume the following rules:

  • A move is guaranteed to be valid and is placed on an empty block.
  • Once a winning condition is reached, no more moves is allowed.
  • A player who succeeds in placing n of their marks in a horizontal, vertical, or diagonal row wins the game.

C# Solution

namespace Algorithms.Hard
{
  interface IBoardGame
  {
    int move(int row, int col, int player);
    int validateBoard(int row, int col, int player);
    bool ValidateRow(int currentRow, int player);
    bool ValidateColum(int currentColumn, int player);
    bool checkForwardDiagonal(int player);
    bool checkBackwardDiagonal(int player);
  }

  public class BoardGame : IBoardGame
  {
    private int size;
    private int[,] board;

    public BoardGame(int n)
    {
      size = n;
      board = new int[n, n];
    }

    public int move(int row, int col, int player)
    {
      if (player == 1)
      {
        board[row, col] = 1;
      }
      else
      {
        board[row, col] = 2;
      }
      return validateBoard(row, col, player);
    }

    public int validateBoard(int row, int col, int player)
    {
      if (ValidateRow(row, player) || ValidateColum(col, player))
      {
        return player;
      }
      else if (row == col && checkForwardDiagonal(player))
      {
        return player;
      }
      else if (col == size - row - 1 && checkBackwardDiagonal(player))
      {
        return player;
      }
      return 0;
    }

    public bool ValidateRow(int currentRow, int player)
    {
      for (int column = 0; column < size; column++)
      {
        if (board[currentRow, column] != player)
        {
          return false;
        }
      }
      return true;
    }

    public bool ValidateColum(int currentColumn, int player)
    {
      for (int row = 0; row < size; row++)
      {
        if (board[row, currentColumn] != player)
        {
          return false;
        }
      }
      return true;
    }

    public bool checkForwardDiagonal(int player)
    {
      for (int x = 0; x < size; x++)
      {
        if (board[x, x] != player)
        {
          return false;
        }
      }
      return true;
    }

    public bool checkBackwardDiagonal(int player)
    {
      for (int x = 0; x < size; x++)
      {
        if (board[size - x - 1, x] != player)
        {
          return false;
        }
      }
      return true;
    }

  }
}

C# Tests

using Algorithms.Hard;
using Xunit;

namespace AlgorithmTests.Hard
{
  public class BoardGameTests
  {
    [Fact]
    public void TestTicTacToe_ValidWin_Size3()
    {
      //Given
      // 0 No win
      // 1 First Player win
      // 2 Second Player win
      BoardGame bg = new BoardGame(3);

      //When
      var m1 = bg.move(0, 0, 1);
      var m2 = bg.move(1, 1, 2);
      var m3 = bg.move(0, 1, 1);
      var m4 = bg.move(2, 2, 2);
      var m5 = bg.move(0, 2, 1);

      //Then
      Assert.Equal(0, m1);
      Assert.Equal(0, m2);
      Assert.Equal(0, m3);
      Assert.Equal(0, m4);
      Assert.Equal(1, m5);
    }

    [Fact]
    public void TestTicTacToe_ValidWin_Size2()
    {
      //Given
      // 0 No win
      // 1 First Player win
      // 2 Second Player win
      BoardGame bg = new BoardGame(2);

      //When
      var m1 = bg.move(0, 1, 1);
      var m2 = bg.move(1, 1, 2);
      var m3 = bg.move(1, 0, 1);

      //Then
      Assert.Equal(0, m1);
      Assert.Equal(0, m2);
      Assert.Equal(1, m3);
    }
  }
}

Companies

  • Microsoft 04/05/2021