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 }