Step 7

You can clone the solution:

git clone https://github.com/cs280fa21/tic-tac-toe

Please take some time and read through the solution. The code for any application, even as simple as the Tic-Tac-Toe game, can quickly get out of hand unless we take a modular approach and break the problem down into smaller tasks, each of which can be coded with one or more functions. Here's a modular structure chart for the provided solution:

Exercise The implementation of checkRow, checkColumn, checkMajorDiagonal and checkMinorDiagonal are fairly similar. Can you refactor the code and extract a function that contains the common behavior?

Solution

It is possible to do this, in particular for checkRow and checkColumn:

  • Add the following function
    function checkCells(rowFirst, rowLast, colFirst, colLast) {
      for (let row = rowFirst; row < rowLast; row++) {
        for (let col = colFirst; col < colLast; col++) {
          let index = toLinearIndex(row, col);
          if (board[index] !== markers[player]) return false;
        }
      }
      return true;
    }
    
  • Update checkRow
    function checkRow(row) {
      return checkCells(row, row + 1, 0, numCols);
    }
    
  • Update checkCol
    function checkColumn(col) {
      return checkCells(0, numRows, col, col + 1);
    }
    

To use checkCells for checking major/minor diagonal, we need to employ a more complex (and convoluted) logic.

The changes already make for a less readable code; a more complex and convoluted checkCells will worsen this situation. So my preference would be to keep the code as is (without using checkCells at all).