Nithyashree B L
Nithyashree B L

Reputation: 99

How to return a winner in a ticTacToe game and stop the prompt from asking for input?

I'm not able to return the winner and stop the prompt from asking the input.

const prompt = require('prompt-sync')({ sigint: true });

const ticTacToe = {
    board: new Array(9).fill(null),
    person: '',
    winner: '',
    randomPlayer: function () {
        let number = Math.floor(Math.random() * 2);

        if (number === 0) {
            return this.person = 'X';
        }
        else {
            return this.person = 'O';
        }
    },

    start: function () {
        let firstPlayer = this.person;
        let count = 1;
        let winner = '';
        while (count <= 9) {

            let input;
            if (count === 1) {
                input = Number(prompt(firstPlayer + ":"));
                count += 1;
                this.moves(input);

            }
            else {
                this.person = this.nextPlayer();
                input = Number(prompt(this.person + ":"));
                count = count + 1;

                this.moves(input);
                this.winner = this.computerWinner(this.person);
                if (this.winner !== null) {
                    console.log("Winner is : " + this.winner);
                    return this.winner;
                }
            }


        }


    },
    nextPlayer: function () {

        if (this.person === 'X') {
            return this.person = 'O';

        }
        else {
            return this.person = 'X';
        }
    },
    moves: function (number) {

        for (let i = 0; i < this.board.length; i++) {

            this.board[number - 1] = this.person;
        }
    },

    computerWinner: function (player) {
        // check horizontal win
        for (var i = 0; i <= 2; i++) {
            if (this.board[i][0] === player &&
                this.board[i][1] === player &&
                this.board[i][2] === player) {
                return player;
            }
            else {
                return null;
            }
        }
        // check vertical win
        for (var i = 0; i <= 2; i++) {
            if (this.board[0][i] === player &&
                this.board[1][i] === player &&
                this.board[2][i] === player) {
                return player;
            }
            else {
                return null;
            }
        }
        // check diagonal win
        if ((this.board[0][0] === player &&
            this.board[1][1] === player &&
            this.board[2][2] === player) ||
            this.board[0][2] === player &&
            this.board[1][1] === player &&
            this.board[2][0] === player) {
            return player;
        }
        else {
            return null;
        }
    }



}



console.log(ticTacToe.randomPlayer());
console.log(ticTacToe.start());
console.log(ticTacToe.board);

It should return a winner name when the rows or columns or diagonals become equal. The prompt is keep on asking the input from the user even when the rows or columns or diagonals become equal. And it is not displaying the winner. Please help

The output looks like below

O
O:1
X:2
O:4
X:3
O:7
X:5
O:6
X:8
O:9
undefined
[
  'O', 'X', 'X',
  'O', 'X', 'O',
  'O', 'X', 'O'
]

Upvotes: 2

Views: 108

Answers (2)

trincot
trincot

Reputation: 350270

There are some issues:

  • Don't return before having done all tests in computerWinner

  • Your board is a one-dimensional array, not 2-dimensional, so all the tests you do in computerWinner are wrong. Convert them to be using a 1-dimensional array

  • There is a useless loop in moves. There should be only one assignment there, without a loop

    moves: function (number) {
        this.board[number - 1] = this.person; // No loop here!
    },

    computerWinner: function (player) {
        // Reference a 1-dimensional array!
        for (var i = 0; i < 9; i += 3) {
            if (this.board[i] === player &&
                this.board[i+1] === player &&
                this.board[i+2] === player) {
                return player;
            }
            // Don't return here yet
        }
        for (var i = 0; i <= 2; i++) {
            if (this.board[i] === player &&
                this.board[i+3] === player &&
                this.board[i+6] === player) {
                return player;
            }
        }
        if ((this.board[0] === player &&
            this.board[4] === player &&
            this.board[7] === player) ||
            this.board[2] === player &&
            this.board[4] === player &&
            this.board[6] === player) {
            return player;
        }
        // If execution gets here, there is no win. 
        // Just let the function return the default `undefined`
    }

Upvotes: 1

t.niese
t.niese

Reputation: 40842

You misunderstood how return works. A return will exit the function it belongs to, and no further code is executed.

If player does not have every field in the first row, you call return null and that will exit the function. So no further tests are done. Neither for the remaining rows nor for the columns or diagonals. So you effectively only test the first row.

You have to remove all return null; and only place one return null; at the end of the function.

You should learn how to use a debugger, and step tough each line of the code to see what is actually happening.

Upvotes: 0

Related Questions