Othello valid move algorithm doesn't work javascript

156 Views Asked by At

I'm trying to code an Othello game, and now I'm trying to code the algorithm that does return the valid positions. I started by retrieving the directions of the empty squares where there's a black or white stone right next to it, but my code doesn't run. I don't know if I did something wrong but it seems that when I launch the program, the code runs slow because the algorithm is overkill. What can I do for that?

Here's my Code(By the way, I use React.js):

Here's the data structure of the square array:

history: [{
                squares: [
                    Array(8).fill(null),
                    Array(8).fill(null),
                    Array(8).fill(null),
                    [null,null,null,'black','white',null,null,null],
                    [null,null,null,'white','black',null,null,null],
                    Array(8).fill(null),
                    Array(8).fill(null),
                    Array(8).fill(null)
                ]
            }],

The Algorithm(for now, just returns the squares that have a stone right next to it(up, up & right , down, left, etc.)):

    checkMoveValidity(isBlack) {
        const history = this.state.history.slice(0, this.state.stepNumber + 1);
        const current = history[history.length - 1];
        const squares = current.squares.slice()

        // Get all the empty spaces
        const emptySpaces  = []
        for (var row=1;row<squares.length-1;row++) {
            for (var col=1;col<squares[row].length-1;col++) {
                if (!squares[row][col]) {
                    emptySpaces.push([row,col])
                }
            }
        }

        const cordAndDirs = []

        for (var sp=0;sp<emptySpaces.length;sp++) {
            const element = emptySpaces[sp]
            const elObject = {
                coordinates: element,
                directions: []
            }
            if (element === [0,0])
            {
                // Check down
                if (squares[1][0]) {
                    const downEls = []
                    for (var i=1;i<squares.length;i++) {
                        downEls.push([i,0])
                    }
                    elObject.directions.push(downEls)
                }
                // Check down right (diagonal)
                if (squares[1][1]) {
                    const drEls = []
                    for (var i=1;i<squares.length;i++) {
                        drEls.push([i,i])
                    }
                    elObject.directions.push(drEls)
                }
                // Check right
                if (squares[0][1]) {
                    const rightEls = []
                    for (var i=1;i<squares.length;i++) {
                        rightEls.push([0,i])
                    }
                    elObject.directions.push(rightEls)
                }
            }
            else if (emptySpaces[sp] === [0,7])
            {
                // Check down
                if (squares[1][7]) {
                    const downEls = []
                    for (var i=1;i<squares.length;i++) {
                        downEls.push([i,7])
                    }
                    elObject.directions.push(downEls)
                }
                // Check down left (diagonal)
                if (squares[1][6]) {
                    const drEls = []
                    for (var i=1;i<squares.length;i++) {
                        drEls.push([i,7 - i])
                    }
                    elObject.directions.push(drEls)
                }
                // Check left
                if (squares[0][6]) {
                    const leftEls = []
                    for (var i=1;i<squares.length;i++) {
                        leftEls.push([0,7 - i])
                    }
                    elObject.directions.push(leftEls)
                }
            }
            else if (emptySpaces[sp] === [7,0])
            {
                // Check up
                if (squares[6][0]) {
                    const upEls = []
                    for (var i=1;i<squares.length;i++) {
                        upEls.push([7 - i,0])
                    }
                    elObject.directions.push(upEls)
                }
                // Check up right
                if (squares[6][1]) {
                    const urEls = []
                    for (var i=1;i<squares.length;i++) {
                        urEls.push([7 - i,i])
                    }
                    elObject.directions.push(urEls)
                }
                // Check right
                if (squares[7][1]) {
                    const rightEls = []
                    for (var i=1;i<squares.length;i++) {
                        rightEls.push([7,i - 1])
                    }
                    elObject.directions.push(rightEls)
                }
            }
            else if (emptySpaces[sp] === [7,7])
            {
                //Check up
                if (squares[6][7]) {
                    const upEls = []
                    for (var i=1;i<squares.length;i++) {
                        upEls.push([7 - i,7])
                    }
                    elObject.directions.push(upEls)
                }
                // Check up left
                if (squares[6][6]) {
                    const ulEls = []
                    for (var i=1;i<squares.length;i++) {
                        ulEls.push([7 - i,7 - i])
                    }
                    elObject.directions.push(ulEls)
                }
                // Check left
                if (squares[7][6]) {
                    const leftEls = []
                    for (var i=1;i<squares.length;i++) {
                        leftEls.push([7,7 - i])
                    }
                    elObject.directions.push(leftEls)
                }
            }
            else
            {
                const crdsY = emptySpaces[sp][0]
                const crdsX = emptySpaces[sp][1]
                //Check up
                if (squares[crdsY - 1][crdsX]) {
                    const upEls = []
                    var i = 1
                    while (crdsY - i >= 0) {
                        upEls.push([crdsY - i,crdsX])
                        i++;
                    }
                    elObject.directions.push(upEls)
                }

                // Check up right
                if (squares[crdsY - 1][crdsX + 1]) {
                    const urEls = []
                    var i = 1
                    while (crdsY - i >= 0 && crdsX + i <= 7) {
                        urEls.push([crdsY - i,crdsX + i])
                        i++;
                    }
                    elObject.directions.push(urEls)
                }
                // Check right
                if (squares[crdsY][crdsX + 1]) {
                    const rightEls = []
                    var i = 1
                    while (crdsX + i <= 7) {
                        rightEls.push([crdsY,crdsX + i])
                        i++;
                    }
                    elObject.directions.push(rightEls)
                }
                // Check down right
                if (squares[crdsY + 1][crdsX + 1]) {
                    const rightEls = []
                    var i = 1
                    while (crdsY + i <= 7 && crdsX + i <= 7) {
                        rightEls.push([crdsY + i,crdsX + i])
                        i++;
                    }
                    elObject.directions.push(rightEls)
                }
                // Check down
                if (squares[crdsY + 1][crdsX]) {
                    const rightEls = []
                    var i = 1
                    while (crdsY + i <= 7) {
                        rightEls.push([crdsY + i,crdsX])
                        i++;
                    }
                    elObject.directions.push(rightEls)
                }
                // Check down left
                if (squares[crdsY + 1][crdsX - 1]) {
                    const rightEls = []
                    var i = 1
                    while (crdsY + i <= 7 && crdsX - i >= 0) {
                        rightEls.push([crdsY + i,crdsX - i])
                        i++;
                    }
                    elObject.directions.push(rightEls)
                }
                // Check left
                if (squares[crdsY][crdsX - 1]) {
                    const rightEls = []
                    var i = 1
                    while (crdsX - i >= 0) {
                        rightEls.push([crdsY,crdsX - i])
                        i++;
                    }
                    elObject.directions.push(rightEls)
                }
                // Check up left
                if (squares[crdsY  - 1][crdsX - 1]) {
                    const rightEls = []
                    var i = 1
                    while (crdsY - i >= 0 && crdsX - i >= 0) {
                        rightEls.push([crdsY - i,crdsX - i])
                    }
                    elObject.directions.push(rightEls)
                }
                
            }

            if (elObject.directions.length === 0) {
                continue
            } else {
                cordAndDirs.push(elObject)
            }
        }

        return cordAndDirs
    }

And this is where I'm trying to implement it:

render() {
        const history = this.state.history
        const current = history[this.state.stepNumber]

        // Return the game scene here
        return (
            <div className="master-container">
                <GameBoard squares={current.squares} onClick={(row,col) => {
                    const elems = this.checkMoveValidity(this.state.blackIsNext)
                    console.log(elems)
                }}/>
            </div>
        )
    }

By the way, I checked whether the command has reached to the elements inside the GameBoard component. It does not have any problem, the problem occurred when I implemented the algorithm.

1

There are 1 best solutions below

1
On BEST ANSWER

I did it. It was quite simple though, I even simplified the code a bit. I forgot to add i++; to the last while loop, I was stuck forever, and then I had to handle the borders so that I don't get an error. For example, I can't //Check up when the upper border squares have no squares beneath them.

This is how I changed the conditional statements:

for (var sp=0;sp<emptySpaces.length;sp++) {
            const element = emptySpaces[sp]
            const elObject = {
                coordinates: element,
                directions: []
            }
                
            // You apply the same methods for all the other squares here (can't use constant numbers in 'squares' now...)
            const crdsY = emptySpaces[sp][0]
            const crdsX = emptySpaces[sp][1]
            var i;
            //Check up
            if (crdsY !== 0 && squares[crdsY - 1][crdsX]) {
                const upEls = []
                i = 1
                while (crdsY - i >= 0) {
                    upEls.push([crdsY - i,crdsX])
                    i++;
                }
                elObject.directions.push(upEls)
            }

            // Check up right
            if (crdsX !== 7 && crdsY !== 0 && squares[crdsY - 1][crdsX + 1]) {
                const urEls = []
                i = 1
                while (crdsY - i >= 0 && crdsX + i <= 7) {
                    urEls.push([crdsY - i,crdsX + i])
                    i++;
                }
                elObject.directions.push(urEls)
            }
            // Check right
            if (crdsX !== 7 && squares[crdsY][crdsX + 1]) {
                const rightEls = []
                i = 1
                while (crdsX + i <= 7) {
                    rightEls.push([crdsY,crdsX + i])
                    i++;
                }
                    elObject.directions.push(rightEls)
            }
            // Check down right
            if (crdsX !== 7 && crdsY !== 7 && squares[crdsY + 1][crdsX + 1]) {
                const rightEls = []
                i = 1
                while (crdsY + i <= 7 && crdsX + i <= 7) {
                    rightEls.push([crdsY + i,crdsX + i])
                    i++;
                }
                elObject.directions.push(rightEls)
            }
            // Check down
            if (crdsY !== 7 && squares[crdsY + 1][crdsX]) {
                const rightEls = []
                i = 1
                while (crdsY + i <= 7) {
                    rightEls.push([crdsY + i,crdsX])
                    i++;
                }
                elObject.directions.push(rightEls)
            }
            // Check down left
            if (crdsY !== 7 && crdsX !== 0 && squares[crdsY + 1][crdsX - 1]) {
                const rightEls = []
                i = 1
                while (crdsY + i <= 7 && crdsX - i >= 0) {
                    rightEls.push([crdsY + i,crdsX - i])
                    i++;
                }
                elObject.directions.push(rightEls)
            }
            // Check left
            if (crdsX !== 0 && squares[crdsY][crdsX - 1]) {
                const rightEls = []
                i = 1
                while (crdsX - i >= 0) {
                    rightEls.push([crdsY,crdsX - i])
                    i++;
                }
                elObject.directions.push(rightEls)
            }
            // Check up left
            if (crdsX !== 0 && crdsY !== 0 && squares[crdsY  - 1][crdsX - 1]) {
                const rightEls = []
                i = 1
                while (crdsY - i >= 0 && crdsX - i >= 0) {
                    rightEls.push([crdsY - i,crdsX - i])
                    i++;
                }
                elObject.directions.push(rightEls)
            }
            

            if (elObject.directions.length !== 0) {
                cordAndDirs.push(elObject)
            }

And also I changed the the game board onClick property a bit like this:

return (
            <div className="master-container">
                <GameBoard squares={current.squares} onClick={(row,col) => {
                    const elems = this.checkElementsAround(this.checkMoveValidity(this.state.blackIsNext))
                    console.log(elems)
                    
                    for (let el=0;el<elems.length;el++) {
                        if (row === elems[el].coordinates[0] && col === elems[el].coordinates[1]) {
                            this.handleMove(row,col);
                            break
                        }
                    }
                }}/>
            </div>
        )