You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

二十一点(Blackjack)游戏开发:数组求和与分数显示技术咨询

Hey there! Let’s break down how to implement the core mechanics you need for your Blackjack game—random card drawing, hand score calculation, and button-triggered score displays—with a flexible, reusable approach.

通用实现思路与代码示例

We’ll use vanilla JavaScript for this example (easily adaptable to other languages like Python if you’re building a desktop/console game) since it’s straightforward for UI interactions.

1. Define Card Data & Random Draw Function

First, we need a deck of cards and a way to randomly draw cards without repeats (simulating real-world dealing):

// Full deck of cards: name for display, base value (A starts as 11 for scoring logic)
const cardDeck = [
  { name: '2', value: 2 }, { name: '3', value: 3 }, { name: '4', value: 4 },
  { name: '5', value: 5 }, { name: '6', value: 6 }, { name: '7', value: 7 },
  { name: '8', value: 8 }, { name: '9', value: 9 }, { name: '10', value: 10 },
  { name: 'J', value: 10 }, { name: 'Q', value: 10 }, { name: 'K', value: 10 },
  { name: 'A', value: 11 }
];

// Track player and dealer hands (arrays to hold drawn cards)
let playerHand = [];
let dealerHand = [];

// Draw a random card from the deck (removes it to avoid re-drawing)
function drawRandomCard() {
  const randomIndex = Math.floor(Math.random() * cardDeck.length);
  return cardDeck.splice(randomIndex, 1)[0];
}

2. Calculate Hand Score (Critical for Blackjack Rules)

The trickiest part is handling Aces (they can count as 1 or 11, whichever keeps the hand under/equal to 21). Here’s a reusable function to compute the valid score:

function calculateHandScore(hand) {
  let totalScore = 0;
  let aceCount = 0;

  // First pass: sum base values, count how many Aces are in the hand
  hand.forEach(card => {
    totalScore += card.value;
    if (card.name === 'A') aceCount++;
  });

  // Adjust for Aces if total exceeds 21: convert 11 to 1 one at a time
  while (totalScore > 21 && aceCount > 0) {
    totalScore -= 10;
    aceCount--;
  }

  return totalScore;
}

Pro tip: This function works for both player and dealer hands—no need to duplicate code!

3. Button Interactions & UI Updates

Now tie everything to buttons and display the hands/scores in your UI. Here’s a simple HTML setup paired with JavaScript event handlers:

HTML (UI Structure)

<div class="game-area">
  <div class="player-section">
    <h3>Your Hand</h3>
    <div id="player-cards"></div>
    <p>Your Score: <span id="player-score">0</span></p>
  </div>

  <div class="dealer-section">
    <h3>Dealer's Hand</h3>
    <div id="dealer-cards"></div>
    <p>Dealer Score: <span id="dealer-score">0</span></p>
  </div>

  <div class="buttons">
    <button id="player-hit">Hit Me</button>
    <button id="dealer-hit">Dealer Hits</button>
    <button id="reset-game">Reset Game</button>
  </div>
</div>

JavaScript (Event Handlers)

// Helper: Render cards to the UI
function renderHand(elementId, hand) {
  const element = document.getElementById(elementId);
  element.innerHTML = hand.map(card => `<span class="card">${card.name}</span>`).join(' ');
}

// Helper: Update score display
function updateScore(elementId, score) {
  document.getElementById(elementId).textContent = score;
}

// Player "Hit" button: draw card, update hand/score
document.getElementById('player-hit').addEventListener('click', () => {
  playerHand.push(drawRandomCard());
  renderHand('player-cards', playerHand);
  const playerScore = calculateHandScore(playerHand);
  updateScore('player-score', playerScore);
  
  // Optional: Check if player busts (score >21)
  if (playerScore > 21) {
    alert("You bust! Dealer wins.");
  }
});

// Dealer "Hit" button: same logic, but for dealer
document.getElementById('dealer-hit').addEventListener('click', () => {
  dealerHand.push(drawRandomCard());
  renderHand('dealer-cards', dealerHand);
  const dealerScore = calculateHandScore(dealerHand);
  updateScore('dealer-score', dealerScore);
});

// Reset game button: reset hands and deck
document.getElementById('reset-game').addEventListener('click', () => {
  // Recreate the full deck
  cardDeck = [
    { name: '2', value: 2 }, { name: '3', value: 3 }, { name: '4', value: 4 },
    { name: '5', value: 5 }, { name: '6', value: 6 }, { name: '7', value: 7 },
    { name: '8', value: 8 }, { name: '9', value: 9 }, { name: '10', value: 10 },
    { name: 'J', value: 10 }, { name: 'Q', value: 10 }, { name: 'K', value: 10 },
    { name: 'A', value: 11 }
  ];
  playerHand = [];
  dealerHand = [];
  renderHand('player-cards', playerHand);
  renderHand('dealer-cards', dealerHand);
  updateScore('player-score', 0);
  updateScore('dealer-score', 0);
});

Key Takeaways

  • Reusability: The calculateHandScore and drawRandomCard functions work for any hand (player, dealer, even multiple players if you expand the game).
  • Flexibility: You can easily add more features (like "Stand" button, automatic dealer play rules) by building on this core structure.
  • UI Clarity: Separating rendering, score calculation, and event logic keeps your code clean and easy to debug.

内容的提问来源于stack exchange,提问作者DrinoCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:20:28