首页 > 解决方案 > 奥赛罗有效移动算法不起作用javascript

问题描述

我正在尝试编写一个黑白棋游戏,现在我正在尝试编写返回有效位置的算法。我首先检索旁边有黑色或白色石头的空方块的方向,但我的代码没有运行。我不知道我是否做错了什么,但似乎当我启动程序时,代码运行缓慢,因为算法过于矫枉过正。我能为此做些什么?

这是我的代码(顺便说一下,我使用 React.js):

方阵的数据结构如下:

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)
                ]
            }],

算法(现在,只返回旁边有一块石头的方块(上、上和右、下、左等)):

    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
    }

这就是我试图实现它的地方:

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>
        )
    }

顺便说一句,我检查了该命令是否已到达 GameBoard 组件内的元素。它没有任何问题,问题发生在我实现算法时。

标签: javascriptreactjsalgorithmothello

解决方案


我做的。不过这很简单,我什至简化了代码。我忘了添加i++;到最后一个 while 循环,我被永远卡住了,然后我不得不处理边界,这样我就不会出错。例如,//Check up当上边框方块下方没有方块时,我不能。

这就是我更改条件语句的方式:

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)
            }

我也改变了游戏板onClick属性有点像这样:

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>
        )

推荐阅读