javascript

My JavaScript Scripts Collection
git clone https://fab.ddns.me.uk/stagit/javascript
Log | Files | Refs | README

blackjack.js (2693B)


      1 #!/usr/bin/env node
      2 
      3 const fs = require('fs');
      4 
      5 /**
      6  * OpenBSDなどの環境で外部ライブラリを使わずに
      7  * 標準入力から同期的に入力を取得する関数
      8  */
      9 function prompt(message) {
     10     process.stdout.write(message);
     11     const buffer = Buffer.alloc(1024);
     12     try {
     13         // 標準入力 (File Descriptor 0) から同期読み込み
     14         const bytesRead = fs.readSync(0, buffer, 0, 1024);
     15         return buffer.toString('utf8', 0, bytesRead).trim();
     16     } catch (err) {
     17         return "";
     18     }
     19 }
     20 
     21 // 1. 山札(デッキ)の作成
     22 const base = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'];
     23 let deck = [...base, ...base, ...base, ...base];
     24 
     25 // 2. 手札の合計を計算する関数
     26 function countScore(hand) {
     27     let total = 0;
     28     let aces = 0;
     29 
     30     for (const card of hand) {
     31         if (!isNaN(card)) {
     32             total += parseInt(card);
     33         } else if (card === 'A') {
     34             aces += 1;
     35             total += 11;
     36         } else {
     37             total += 10; // J, Q, K
     38         }
     39     }
     40 
     41     while (total > 21 && aces > 0) {
     42         total -= 10;
     43         aces -= 1;
     44     }
     45     return total;
     46 }
     47 
     48 // 3. ゲーム開始 (Fisher-Yates Shuffle)
     49 for (let i = deck.length - 1; i > 0; i--) {
     50     const j = Math.floor(Math.random() * (i + 1));
     51     [deck[i], deck[j]] = [deck[j], deck[i]];
     52 }
     53 
     54 let player = [deck.pop(), deck.pop()];
     55 let dealer = [deck.pop(), deck.pop()];
     56 
     57 // プレイヤーのターン
     58 while (true) {
     59     const pScore = countScore(player);
     60     console.log(`Your hand: ${player.join(', ')} (Score: ${pScore})`);
     61 
     62     if (pScore > 21) {
     63         console.log("Bust! You lose. 🇬🇧 Dreadful luck!");
     64         process.exit();
     65     }
     66     if (pScore === 21) {
     67         console.log("Blackjack! 🇬🇧 Top-hole!");
     68         break;
     69     }
     70 
     71     const choice = prompt("Do you want to (H)it or (S)tand? ");
     72     if (choice.toLowerCase().startsWith('h')) {
     73         player.push(deck.pop());
     74     } else {
     75         break;
     76     }
     77 }
     78 
     79 // 4. ディーラーのターン
     80 console.log(`\nDealer's hand: ${dealer.join(', ')}`);
     81 while (countScore(dealer) < 17) {
     82     dealer.push(deck.pop());
     83     console.log(`Dealer hits: ${dealer.join(', ')} (Score: ${countScore(dealer)})`);
     84 }
     85 
     86 // 5. 結果判定
     87 const pTotal = countScore(player);
     88 const dTotal = countScore(dealer);
     89 
     90 console.log(`\nFinal Scores - You: ${pTotal}, Dealer: ${dTotal}`);
     91 
     92 if (dTotal > 21) {
     93     console.log("Dealer busts! You win! 🇬🇧 Brilliant!");
     94 } else if (pTotal > dTotal) {
     95     console.log("You win! 🇬🇧 Jolly good!");
     96 } else if (pTotal < dTotal) {
     97     console.log("Dealer wins. 🇬🇧 Better luck next time!");
     98 } else {
     99     console.log("It's a push (Tie).");
    100 }