如何使用JavaScript实现快艇骰子(Yahtzee)的三轮投掷系统?
快艇骰子(Yahtzee)三轮投掷系统实现方案
嘿,我来帮你搞定这个Yahtzee的三轮投掷功能!先看看你现有代码里的几个小问题,然后咱们一步步把完整的逻辑补全~
现有代码的核心问题
turns、firstroll这些游戏状态变量放在die构造函数里不合适——每个骰子实例都会有自己的计数,这显然不对,应该让所有骰子共享全局的投掷次数- 点击骰子切换选中状态时,作用域出问题了:点击事件里的
selected并不是当前骰子实例的属性,而是构造函数里的局部变量,导致状态切换失效 - 缺少触发投掷的交互逻辑(比如按钮),也没有对三轮投掷次数的限制
完整实现代码
下面是重构后的完整代码,包含三轮投掷控制、骰子选中切换、重置游戏和基础得分计算逻辑:
HTML结构(先搭好页面骨架)
<div id="dice-container"></div> <div class="controls"> <button id="roll-button">投掷 (剩余3次)</button> <button id="reset-button">重置游戏</button> </div> <style> .die { margin: 10px; cursor: pointer; border-radius: 8px; } .selected-die { border: 3px solid #e74c3c; box-shadow: 0 0 10px rgba(231, 76, 60, 0.5); } .controls button { padding: 10px 20px; margin: 10px; font-size: 16px; cursor: pointer; border: none; border-radius: 4px; background-color: #3498db; color: white; } .controls button:disabled { background-color: #bdc3c7; cursor: not-allowed; } </style>
JavaScript逻辑(用jQuery实现)
$(document).ready(function() { // 游戏全局状态 let remainingRolls = 3; // 初始3次投掷机会 const diceImg = ["", "Die1.png", "Die2.png", "Die3.png", "Die4.png", "Die5.png", "Die6.png"]; let dice = []; // 存储5个骰子实例 // 骰子构造函数 function Die() { this.value = 0; this.selected = false; // 每个骰子自己的选中状态 this.dom = $('<img class="die" height="150px" width="150px">'); // 点击切换选中状态,用箭头函数绑定当前骰子实例的this this.dom.click(() => { this.selected = !this.selected; this.dom.toggleClass('selected-die'); // 用样式直观展示选中状态 }); // 掷骰子方法:未选中的骰子才会重新生成点数 this.roll = function() { if (!this.selected) { this.value = Math.floor(Math.random() * 6) + 1; this.dom.attr('src', diceImg[this.value]); } }; } // 初始化5个Yahtzee骰子 function initDice() { for (let i = 0; i < 5; i++) { const die = new Die(); dice.push(die); $('#dice-container').append(die.dom); } // 第一次加载时先掷一次骰子 dice.forEach(die => die.roll()); } // 投掷按钮逻辑 $('#roll-button').click(() => { if (remainingRolls > 0) { // 遍历所有骰子执行掷骰 dice.forEach(die => die.roll()); remainingRolls--; // 更新按钮文本提示剩余次数 $('#roll-button').text(`投掷 (剩余${remainingRolls}次)`); // 次数用完后禁用按钮,触发得分计算 if (remainingRolls === 0) { $('#roll-button').prop('disabled', true).text('投掷次数用完'); calculateScore(); } } }); // 重置游戏逻辑 $('#reset-button').click(() => { remainingRolls = 3; $('#roll-button').text('投掷 (剩余3次)').prop('disabled', false); // 重置所有骰子:取消选中,重新掷骰 dice.forEach(die => { die.selected = false; die.dom.removeClass('selected-die'); die.roll(); }); }); // 示例得分计算函数(可根据Yahtzee规则扩展) function calculateScore() { const diceValues = dice.map(die => die.value); console.log('当前骰子点数:', diceValues); // 统计每个点数出现的次数 const countMap = diceValues.reduce((map, val) => { map[val] = (map[val] || 0) + 1; return map; }, {}); // 示例:判断是否凑成Yahtzee(5个相同点数) const isYahtzee = Object.values(countMap).includes(5); if (isYahtzee) { alert('恭喜!凑成Yahtzee啦!'); } } // 初始化游戏 initDice(); });
关键功能说明
- 三轮投掷控制:用全局变量
remainingRolls跟踪剩余次数,每次点击投掷按钮后减少,次数为0时禁用按钮 - 骰子选中状态:每个骰子实例维护自己的
selected属性,点击时切换并通过样式反馈给用户,未选中的骰子才会在投掷时更新点数 - 重置功能:一键恢复投掷次数,重置所有骰子状态,方便重新开始游戏
- 基础得分逻辑:示例中实现了Yahtzee的判断,你可以根据规则扩展其他得分项(比如顺子、三个相同、满堂红等)
内容的提问来源于stack exchange,提问作者EzraIsReal
相关产品推荐
相关产品推荐

