Tic Tac Toe-在React找到胜利者

时间:2017-11-15 16:03:56

标签: javascript arrays reactjs components

所以我在React中创建了一个Tic Tac Toe游戏。现在我试图找出我的应用程序组件中玩家获胜的逻辑。我已经有了他们可以赢得的可能的动作以及阵列。出于测试目的,我尝试使用 midWin 的if语句,但似乎无效。有人可以告诉我为什么它不起作用?由于一些奇怪的原因,我无法在JS小提琴上显示我的代码,但这是我的代码:

let data = {
    "box":[
        [ "", "", "" ],
        [ "", "", "" ],
        [ "", "", "" ]
    ],
    "players": ['X','O']
}
class DataStore {
    constructor(data, players) {
        //store that data in the object
        this.data = data;
        this.players = players;
        //empty array for our watchers
        //watchers are objects that want to be informed about when the data changes
        this.registeredWatchers = [];
    }
    //add a new watcher to the list
    register(watcher) {
        this.registeredWatchers.push(watcher);
    }
    setCrop(newDataState, row, col) {
        //update data
        this.data[row][col] = newDataState;
        //inform all watching objects..
        this.registeredWatchers.map((watcher) => {
            watcher.dataUpdated();
        })
    }
    reset() {
        // this.data = data;
    }
}
class Dispatcher {
    constructor() {
        this.registeredHandlers = []; //D:
    }
    register(callback) {
        this.registeredHandlers.push(callback);
    }
    dispatch(action) {
        //call every method in our registered handlers array
        //with this action as an input
        this.registeredHandlers.map((handler) => {
            //call that individual function in the array..
            handler(action);
        })
    }
    reset(val){

    }
}
class BoxComponent extends React.Component {
    render() {
        return (
            <div
                className="box"
                onClick={this.handleClick.bind(this)}>
                <span>{this.props.type}</span>
            </div>);
    }
    handleClick() {
        //try a test dispatch
        if(this.props.type.length > 0) {
            return false;
        } else {
            boxDispatcher.dispatch({ type: "pick", row: this.props.rowNum, col: this.props.colNum});
        }
    }
}
class GridComponent extends React.Component {
    render() {
        return(
            <div>
                <p>Player {this.props.turn} is next.</p>
                {
                    //loop through all the  rows...
                    this.props.box.map((row, rowNum) => {
                        //and write them out to the page..
                        return (<div className="row">
                            {
                                row.map((cropEntry, colNum) => {
                                    return <BoxComponent type={cropEntry}  rowNum={rowNum} colNum={colNum} turn={rowNum}/>
                                })
                            }
                        </div>);
                    })
                }
            </div>
        )
    }
}
class App extends React.Component {
    constructor(props) {
        //make sure this stays a react component
        super(props);
        this.state = {
            turn: boxDataStore.players[0],
            box: boxDataStore.data
        }
        //ensure we're listening to the data store
        boxDataStore.register(this);
    }
    dataUpdated() {
        this.setState(prevState => ({
            box: boxDataStore.data,
            // turn: cropDataStore.players,
            turn: prevState.turn === 'X'
                ? boxDataStore.players[1]
                : boxDataStore.players[0]
        }))
    }

    render() {
        return (
            // renders out the whole data on the board
            <div>
                <h1>Tic Tac Toe </h1>
                <button onClick={this.resetBoard.bind(this)}>Reset Board</button>
                <button onClick={this.checkWinner.bind(this)}>Check Winner</button>
                <GridComponent box={this.state.box} turn={this.state.turn} />
            </div>
        );
    }
    // rests the data back to the orginal state which is  from the let data
    resetBoard() {
        const newBoxData = [
            [ "", "", "" ],
            [ "", "", "" ],
            [ "", "", "" ]
        ]
        boxDataStore.data = newBoxData;
        this.setState({
            box: boxDataStore.data
        })

    }
    // end data that tells the update

    // events that help users find out who the winner or the losers
    checkWinner() {


        //vertical wins
        const topWin = [
            this.state.box["0"]["0"],
            this.state.box["0"]["1"],
            this.state.box["0"]["2"]
        ];

        const midWin = [
            this.state.box["1"]["0"],
            this.state.box["1"]["1"],
            this.state.box["1"]["2"]
        ];

        const bottom = [
            this.state.box["2"]["0"],
            this.state.box["2"]["1"],
            this.state.box["2"]["2"]
        ];
        // vertical wins end.

        //horizontal wins
        const horizMid = [
            this.state.box["0"]["1"],
            this.state.box["1"]["1"],
            this.state.box["2"]["1"]
        ];

        const horizleft = [
            this.state.box["0"]["2"],
            this.state.box["1"]["2"],
            this.state.box["2"]["2"]
        ];

        const horizright = [
            this.state.box["0"]["0"],
            this.state.box["1"]["1"],
            this.state.box["2"]["2"]
        ];
        //horiztanl end

        const diagonalright = [
            this.state.box["0"]["0"],
            this.state.box["1"]["1"],
            this.state.box["2"]["2"]
        ];

        function identical(array) {
            for(let i = 2; i < array.length; i++) {
                if(array[i] === array[i+1]) {
                    return true;

                }
            }
        };

        if(identical(midWin)) {
            alert('midWin')
        }

    }
}
//start of app
var boxDispatcher = new Dispatcher();
var boxDataStore = new DataStore(data.box, data.players);
boxDispatcher.register((action) => {
    if(boxDataStore.registeredWatchers["0"].state.turn == "X") {
        //actually waint to handle it
        boxDataStore.setCrop('X', action.row, action.col);
    } else {
        boxDataStore.setCrop('O', action.row, action.col);
    }
})
ReactDOM.render(<App data={boxDataStore.data} />, document.querySelector("#app"));
export default App; 

1 个答案:

答案 0 :(得分:0)

问题在于功能相同。我纠正了这个功能。

        function identical(array) {

        // Check if any of the box is blank. if yes then no need to check the win
        if(array.some(function(element){return element===""})){
            return false;
        }

        let winFlag = true;

        for(let i = 0; i < array.length-1; i++) {
            if(array[i] !== array[i+1]) {
                winFlag = false;
            }
        }
        return winFlag;
    }

请查看JS小提琴的详细信息 -
https://jsfiddle.net/abhijeet_srivastava/wx2tq713/11/