如何使用我当前的设置实现tic tac toe win条件?

时间:2017-08-14 23:38:54

标签: javascript node.js mongoose

我目前正在开发一款内置Node.js的tic tac toe多人游戏。

我的主要问题是弄清楚如何检查胜利条件。我知道如何使用数组,但我想以这种方式编程我的游戏....

var mongoose = require('mongoose');

var gameSchema = new mongoose.Schema({

    player1: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "User"
    },

    player2: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "User"
    },

    // This would be an array of selected spaces for 'x' or 'o'
    placements: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: "Placement"
    }],

    // This would be the username of the current player.
    currentPlayer: String
});

module.export = mongoose.model('Game', gameSchema);

展示位置架构:

var mongoose = require('mongoose');

var placementSchema = new mongoose.Schema({
    marker: String, //x or o

    selectedSpace: Number // 0-8
});

module.export = mongoose.model('Placement', placementSchema);

我想将展示位置用作模型对象的数组....

以这种方式检查胜利条件的最佳方法是什么?

或者我应该重新考虑这个模型的设置方式吗?

1 个答案:

答案 0 :(得分:0)

如果我理解您的设置正确,那么每当您添加展示位置时,您都需要检查是否有赢家。

// req.params.game = ID of board game
// req.body = { marker: 'x' or 'o', selectedSpace: 0 to 8 }

app.post('/game/:game/placement', (req, res, next) => {
    // find the board game
    Game.findById(req.params.game, (err, game) => {
        if (err) return next(err);

        // create placement (!)
        Placement.create(req.body, (err, placement) => {
            if (err) return next(err);

            // add placement to game
            game.placements.push(placement._id);

            // you might want to swap game.currentPlayer at this point too; i'll leave that to you

            game.save(err => {
                if (err) return next(err);

                // get placements b/c we'll need to check all of them
                game.populate('placements').execPopulate().then(() => {
                    let winner = game.getWinner();  
                    if (winner) {
                        // send response to declare winner and stop game
                    } else {
                        // send response to do nothing
                    }
                });
            });
        });
    });
});

在您的架构中,您将拥有

// this is where you would add the logic to check if there is a winner or not;

// a winner is someone who has 0 1 2 (horizontal 1st row), 3 4 5 (horizontal 2nd row), 6 7 8 (horizontal 3rd row),
// 0 3 6 (vertical 1st column), 1 4 7 (vertical 2nd column), 2 5 8 (vertical 3rd column), 0 4 8 (diagonal), 2 4 6 (diagonal);

// this has not been tested but should give you some pointers at least;
// there might be even a simpler logic
gameSchema.methods.getWinner = function () {
    let strikes = [[0,1,2], [3,4,5], [6,7,8], [0,3,6], [1,4,7], [2,5,8], [0,4,8], [2,4,6]];
    let dict = {
        x: [],
        o: []
    };
    // group placements by marker (!)
    let winningPlacement = this.placements.find(placement => {
        dict[placement.marker].push(placement.selectedSpace);
        // check if any of the strikes is contained in the marker's list of selected spaces
        return strikes.some(strike => isSuper(dict[placement.marker], strike));
    });
    // assuming player1 is always 'x'
    if (winningPlacement) {
        return winningPlacement.marker == 'x' ? this.player1 : this.player2;
    }
    return false;
};

在这个问题的范围之外,请参阅isSuper()逻辑的答案。

IMO虽然我认为你应该重新考虑你的设计。例如,使用引用数组有点不必要。它可以帮助你避免做(!)而且无法区分哪个玩家是X或O(除非你假设玩家1总是首先用X开始)。