2017-08-14 3 views
1

私は現在、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

ありがとうございます。 –

+0

@ジャロマンダX正しい。これは、各インデックスが選択されたスペースとプレーヤーマーカーを持つプレースメントであるオブジェクト配列です。 –

答えて

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

、あなたはisSuper()ロジックのためにこの回答を参照してください、この質問の範囲外

// 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; 
}; 

を持っているでしょう。

私はあなたがあなたのデザインを考え直すべきだと思いますが。たとえば、参照配列を使用するのは少し不必要です。 (!)また、player1が常に最初にXで始まると仮定しない限り、どのプレイヤーがXかOかを区別する方法はありません。

関連する問題