計算分數的分數有上千百種
筆者選擇了一個簡單的計分方式
兩位玩家互相等待的時間越短, 分數越高
所以我們需要額外得到互相等待的時間
原本的等待是這麼寫
Game.prototype.waitOtherPlayer = function() {
if ( this.isPlayerOneReady ) {
this.isPlayerTwoReady = true
}else {
this.isPlayerOneReady = true
}
return new Promise( (resolve, reject) => {
if ( this.waitingTimer === null ) {
this.waitingTimer = setInterval(() => {
console.log('keep waiting')
console.log('playerA: ' + this.isPlayerOneReady)
console.log('playerB: ' + this.isPlayerTwoReady)
if ( this.isPlayerOneReady && this.isPlayerTwoReady ) {
clearInterval(this.waitingTimer)
this.waitingTimer = null
this.isPlayerOneReady = this.isPlayerTwoReady = false
resolve(true)
}
}, 200)
}else {
resolve(false)
}
})
}
我們要新增一個回傳參數, 回傳等待的總毫秒
Game.prototype.waitOtherPlayer = function() {
if ( this.isPlayerOneReady ) {
this.isPlayerTwoReady = true
}else {
this.isPlayerOneReady = true
}
return new Promise( (resolve, reject) => {
if ( this.waitingTimer === null ) {
let delay = 200;
let times = 0;
let totalWaitingMs = 0;
this.waitingTimer = setInterval(() => {
times += 1
totalWaitingMs = delay * times
console.log('keep waiting, time goes: ' + totalWaitingMs)
console.log('playerA: ' + this.isPlayerOneReady)
console.log('playerB: ' + this.isPlayerTwoReady)
if ( this.isPlayerOneReady && this.isPlayerTwoReady ) {
clearInterval(this.waitingTimer)
this.waitingTimer = null
this.isPlayerOneReady = this.isPlayerTwoReady = false
resolve(true, totalWaitingMs)
}
}, delay)
}else {
resolve(false)
}
})
}
在接收玩家答案的地方計算並存入分數
answer (data) {
...
...
GAME.waitOtherPlayer().then((isAllReady, time) => {
...
//等待結束後, 把等待時間傳入getScore計算分數
if (isAllReady) {
let score = GAME.getScore(time);
GAME.countScore(score)
GAME.questionStep += 1
}
})
}
GAME.getScore
Game.prototype.getScore = function(time) {
// max time is 3000
return Math.floor(10000 / Math.sqrt(time))
}
GAME.countScore
Game.prototype.countScore = function(newScore = 0) {
let answerHis = this.answerList[this.questionStep];
let answer = Object.keys(answerHis).map(player => answerHis[player].anser)
if(answer[0] !== 'C' && answer[1] !== 'C') {
this.score = this.score + newScore
} //else 沒有分數
}
最後, 我們應該在 Game over 時回傳分數
getQuestion (data) {
try {
...
...
let res = {
id : data.id
};
if ( question ) {
res.type = 'question'
...
...
}else {
res.type = 'gameOver'
res.score = GAME.score
console.log(`GAME.score:${GAME.score}`)
}
connection.send(JSON.stringify(res))
} catch (error) {
connection.close()
throw error
}
}
現在的GAME物件
//Game建構式, 遊戲房間
function Game( connection, id ) {
this.connection = connection; //以各變數紀錄遊戲中各種狀態
this.id = id;
this.type = null; // 1. wait 2. play 3. over
this.playerA = '';
this.playerB = '';
this.score = 0;
this.isOver = false;
this.isPlayerOneReady = false;
this.isPlayerTwoReady = false;
this.waitingTimer = null;
this.questionStep = 0;
this.questionList = [];
this.answerList = [];
setTimeout(() => {
(this.type !== 'play') && delete Manager[this.id]
}, 10000); //GAME物件建立後, 一段時間沒開始遊戲就自我毀滅, 減少記憶體消耗
return this;
}
// 加入遊戲
Game.prototype.join = function ( userName ) {
return new Promise( (resolve, reject) => {
let timer = null;
if ( this.playerA !== '' ) {
this.playerB = userName
}else {
this.playerA = userName
}
timer = setInterval(() => {
if ( this.playerA !== '' && this.playerB !== '' ) {
this.questionList = generateQuestionList()
clearInterval(timer)
resolve({
id : this.id,
playerA : this.playerA,
playerB : this.playerB
})
}
}, 1000)
})
}
// 獲得題目
Game.prototype.getQuestion = function() {
return this.questionList[this.questionStep]
}
// 儲存玩家回答
Game.prototype.setAnswerHistory = function( answer ) {
let data = {
questionId : answer.questionId,
questionStep : answer.questionStep
}
data[answer.userName] = {
userName : answer.userName,
answer : answer.answer
}
if ( this.answerList.length !== answer.questionStep + 1 ) {
this.answerList.push(data)
}else {
this.answerList[answer.questionStep][answer.userName] = {
userName : answer.userName,
answer : answer.answer
}
}
}
//等待另一位玩家
// 這個應該是GAME物件中最重要的方法
// socket連線中會有需要兩位玩家同步的時候都會用到此方法
// 例如 同時開始計時,同時公布答案
Game.prototype.waitOtherPlayer = function() {
if ( this.isPlayerOneReady ) {
this.isPlayerTwoReady = true
}else {
this.isPlayerOneReady = true
}
return new Promise( (resolve, reject) => {
if ( this.waitingTimer === null ) {
let delay = 200;
let times = 0;
let totalWaitingMs = 0;
this.waitingTimer = setInterval(() => {
times += 1
totalWaitingMs = delay * times
console.log('keep waiting, time goes: ' + totalWaitingMs)
console.log('playerA: ' + this.isPlayerOneReady)
console.log('playerB: ' + this.isPlayerTwoReady)
if ( this.isPlayerOneReady && this.isPlayerTwoReady ) {
clearInterval(this.waitingTimer)
this.waitingTimer = null
this.isPlayerOneReady = this.isPlayerTwoReady = false
resolve({
isAllReady: true,
time: totalWaitingMs
})
}
}, delay)
}else {
resolve({
isAllReady: false
})
}
})
}
//計算分數
Game.prototype.getScore = function(time) {
// max time is 3000
return Math.floor(10000 / Math.sqrt(time))
}
Game.prototype.countScore = function(newScore = 0) {
let answerHis = this.answerList[this.questionStep];
console.log(this.answerList);
let answers = Object.keys(answerHis).map(player => answerHis[player].anser)
if(answers[0] !== 'C' && answers[1] !== 'C') {
this.score = this.score + newScore
} //else 沒有分數
}