美文网首页
JavaScript 实现击鼓传花游戏

JavaScript 实现击鼓传花游戏

作者: 贵在随心 | 来源:发表于2019-04-12 13:51 被阅读0次

    大家小时候应该都玩过击鼓传花(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: 张三
    

    输出的结果依次为被淘汰的选手和最后的胜利者,这个方法有个弊病:每次淘汰选手敲得鼓声都是一样,导致淘汰的选手和胜利者能预测到。一般我们游戏的时候敲的鼓声都是不确定的,那如何做到不确定,达到一定的游戏氛围呢?大家集思广益吧!

    相关文章

      网友评论

          本文标题:JavaScript 实现击鼓传花游戏

          本文链接:https://www.haomeiwen.com/subject/ujwqwqtx.html