大家小時候應該都玩過擊鼓傳花(Hot Potato)的游戲吧!
一群小孩圍成一個圓圈,把花盡快的傳給旁邊的人。某一時刻傳花停止,這時花在誰手里,誰就退出圓圈結束游戲。重復此過程,直到剩下最后一個孩子,即為勝者。
如何用 JavaScript 代碼按此規則實現擊鼓傳花呢?
這里需要借助 JavaScript 中隊列的知識,利用循環隊列來實現。
隊列
首先,我們創建一個 queue.js 的文件存儲 Queue 類,代碼如下:
export default class Queue {
constructor() {
this.count = 0;
this.lowestCount = 0;
this.items = {};
}
enqueue(element) {
this.items[this.count] = element;
this.count++;
}
dequeue() {
if (this.isEmpty()) {
return undefined;
}
const result = this.items[this.lowestCount];
delete this.items[this.lowestCount];
this.lowestCount++;
return result;
}
isEmpty() {
return this.size() === 0;
}
clear() {
this.items = {};
this.count = 0;
this.lowestCount = 0;
}
size() {
return this.count - this.lowestCount;
}
toString() {
if (this.isEmpty()) {
return '';
}
let objString = `${this.items[this.lowestCount]}`;
for (let i = this.lowestCount + 1; i < this.count; i++) {
objString = `${objString},${this.items[i]}`;
}
return objString;
}
}
其次,根據擊鼓傳花的規則和循環隊列的知識,組織代碼:
/**
* @param {Array:參加游戲的人員} elementsList
* @param {number:每次擊鼓的次數} num
*/
function hotPotato(elementsList, num) {
// 引入 queue.js 創建 Queue 實例
const queue = new Queue();
const elimitatedList = [];
for (let i = 0; i < elementsList.length; i++) {
// 把參加的人列入隊列中
queue.enqueue(elementsList[i]);
}
while (queue.size() > 1) {
for (let i = 0; i < num; i++) {
// 把隊列的第一個人放入隊尾循環隊列
queue.enqueue(queue.dequeue());
}
// 把淘汰的人放入 elimitatedList 數組中
elimitatedList.push(queue.dequeue());
}
return {
eliminated: elimitatedList, // 淘汰的人
winner: queue.dequeue() // 勝利者
};
}
// test
const names = ['丁一', '龍二', '張三', '李四', '王五', '趙六'];
const result = hotPotato(names, 7);
result.eliminated.forEach(name => {
console.log(`${name} was eliminated from the Hot Potato game.`);
});
console.log(`The winner is: ${result.winner}`);
// 龍二 was eliminated from the Hot Potato game.
// 王五 was eliminated from the Hot Potato game.
// 李四 was eliminated from the Hot Potato game.
// 丁一 was eliminated from the Hot Potato game.
// 趙六 was eliminated from the Hot Potato game.
// The winner is: 張三
輸出的結果依次為被淘汰的選手和最后的勝利者,這個方法有個弊病:每次淘汰選手敲得鼓聲都是一樣,導致淘汰的選手和勝利者能預測到。一般我們游戲的時候敲的鼓聲都是不確定的,那如何做到不確定,達到一定的游戲氛圍呢?大家集思廣益吧!