如何将Node.js命令行三人扑克游戏改造为网页版?
把Node.js扑克游戏转为网页版实现方案
你的核心手牌计算逻辑(Hand和Card类)完全可以复用,只需要把命令行交互替换成网页DOM交互,以下是具体实现步骤:
1. 编写HTML页面结构
创建一个index.html,包含玩家数量输入、动态生成的手牌输入区、计算按钮和结果展示区:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>三人扑克游戏</title> <style> .player-hand { margin: 10px 0; } #result { margin-top: 20px; font-size: 1.2em; font-weight: bold; } </style> </head> <body> <div> <label>玩家数量:</label> <input type="number" id="player-count" min="2" max="10" value="3"> <button onclick="generateHandInputs()">确认数量</button> </div> <div id="hands-container"></div> <button onclick="determineWinner()">判定赢家</button> <div id="result"></div> <script type="module" src="app.js"></script> </body> </html>
2. 调整JS代码适配浏览器环境
保留原有的手牌计算逻辑,修改交互逻辑适配网页环境:
首先创建hand.js(核心逻辑复用,仅保留必要代码)
const SUITS = ["h", "s", "d", "c"]; const RANKS = ["2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"]; const RANK_TO_VALUE = { 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, T: 10, J: 10, Q: 10, K: 10, A: 11, }; export default class Hand { constructor(cards = "", order = 0) { this.cards = cards.split(" ").map((c) => new Card(c)); this.value = this.getHandValue(); this.order = order; } hasStraightFlush() { return 100000 * (this.hasStraight() && this.hasFlush()); } hasThreeOfKind() { return ( 10000 * (this.cards[0].rank == this.cards[1].rank && this.cards[2].rank == this.cards[1].rank) ); } hasStraight() { let ranks = this.cards.map((c) => c.order); ranks.sort(); return 1000 * (ranks[0] + 2 == ranks[1] + 1 && ranks[1] + 1 == ranks[2]); } hasFlush() { return ( 100 * (this.cards[0].suit == this.cards[1].suit && this.cards[2].suit == this.cards[1].suit) ); } hasPair() { return ( 20 * ((this.cards[0].rank == this.cards[1].rank || this.cards[2].rank == this.cards[1].rank) && !( this.cards[0].rank == this.cards[1].rank && this.cards[2].rank == this.cards[1].rank )) ); } hasHighCard() { const vals = this.cards.map((c) => c.value); vals.sort((a, b) => a - b); return vals[vals.length - 1]; } getHandValue() { return Math.max( this.hasStraightFlush(), this.hasThreeOfKind(), this.hasFlush(), this.hasStraight(), this.hasPair(), this.hasHighCard() ); } } class Card { constructor(input) { this.suit = input.charAt(1); this.rank = input.charAt(0); this.value = RANK_TO_VALUE[this.rank]; this.order = RANKS.indexOf(this.rank); } }
然后创建app.js(处理网页交互逻辑)
import Hand from './hand.js'; // 生成玩家手牌输入框 function generateHandInputs() { const count = parseInt(document.getElementById('player-count').value); const container = document.getElementById('hands-container'); container.innerHTML = ''; // 清空之前的输入框 for (let i = 0; i < count; i++) { const div = document.createElement('div'); div.className = 'player-hand'; div.innerHTML = `<label>玩家${i+1}手牌(格式示例:Ah Ks Qd):</label> <input type="text" class="hand-input" placeholder="输入三张牌,空格分隔">`; container.appendChild(div); } } // 判定赢家逻辑 function determineWinner() { const handInputs = document.querySelectorAll('.hand-input'); const userInput = Array.from(handInputs).map(input => input.value.trim()); // 验证输入格式有效性 const validInputs = userInput.every(input => /^([2-9TJQKA][hsdc]\s?){3}$/.test(input.trim())); if (!validInputs) { document.getElementById('result').textContent = '输入格式错误!请按示例格式输入三张牌(如Ah Ks Qd)'; return; } // 复用原有的核心计算逻辑 let hands = userInput.map((val, i) => new Hand(val, i+1)); // 玩家序号从1开始更直观 hands.sort((a, b) => b.value - a.value); let winners = [hands[0].order]; let winningValue = hands[0].value; for (let i = 1; i < hands.length; i++) { if (hands[i].value == winningValue) { winners.push(hands[i].order); } else { break; } } // 在网页展示结果 if (winners.length === 1) { document.getElementById('result').textContent = `赢家:玩家${winners[0]}`; } else { document.getElementById('result').textContent = `平局,赢家:玩家${winners.join('、')}`; } } // 页面加载时默认生成3个玩家的输入框 window.onload = () => { generateHandInputs(); };
关键改动说明
- 移除
prompt-sync模块,改用网页输入框获取用户输入 - 使用浏览器支持的ES模块(
type="module")导入Hand类 - 增加输入格式验证,避免无效输入导致逻辑出错
- 将原
console.log输出改为网页DOM元素展示结果 - 调整玩家序号为从1开始,符合用户直观认知
内容的提问来源于stack exchange,提问作者ScottieTee
相关产品推荐
相关产品推荐

