我目前正在开发一款内置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);
我想将展示位置用作模型对象的数组....
以这种方式检查胜利条件的最佳方法是什么?
或者我应该重新考虑这个模型的设置方式吗?
答案 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开始)。