paint-brush
अल्पाइन.जेएस और डेक ऑफ कार्ड्स एपीआई के साथ ब्लैकजैक गेम कैसे बनाएंद्वारा@raymondcamden
1,176 रीडिंग
1,176 रीडिंग

अल्पाइन.जेएस और डेक ऑफ कार्ड्स एपीआई के साथ ब्लैकजैक गेम कैसे बनाएं

द्वारा Raymond Camden6m2023/07/20
Read on Terminal Reader

बहुत लंबा; पढ़ने के लिए

डेक ऑफ कार्ड्स एपीआई कार्डों के डेक के साथ काम करने से संबंधित हर कल्पना को संभालता है। यह कार्डों का एक फेरबदल किया हुआ सेट (एक या अधिक डेक वाले) बनाने, एक कार्ड (या कार्ड) को निपटाने और यहां तक कि फेरबदल करने का काम भी संभालता है। यह एक अविश्वसनीय रूप से सुविधाओं से भरपूर एपीआई है, और सबसे अच्छी बात यह है कि यह पूरी तरह से मुफ़्त है।
featured image - अल्पाइन.जेएस और डेक ऑफ कार्ड्स एपीआई के साथ ब्लैकजैक गेम कैसे बनाएं
Raymond Camden HackerNoon profile picture

कुछ समय पहले, मेरी नज़र एक बहुत ही आकर्षक सेवा, डेक ऑफ़ कार्ड्स एपीआई पर पड़ी। यह एपीआई कार्ड के डेक के साथ काम करने से संबंधित हर कल्पना को संभालता है। यह कार्डों का एक फेरबदल किया हुआ सेट (एक या अधिक डेक वाले) बनाने, एक कार्ड (या कार्ड) को निपटाने और यहां तक कि फेरबदल करने का काम भी संभालता है।


इससे भी बेहतर, इसमें कार्ड छवियां शामिल हैं जिनका उपयोग आप कर सकते हैं यदि आप अपना खुद का नहीं ढूंढना चाहते हैं:


यह एक अविश्वसनीय रूप से सुविधाओं से भरपूर एपीआई है, और सबसे अच्छी बात यह है कि यह पूरी तरह से मुफ़्त है। चाबी की भी जरूरत नहीं. मैं इस एपीआई के बारे में कुछ समय से जानता हूं और मैंने इसके साथ एक कार्ड गेम बनाने पर विचार किया है, लेकिन मुझे एहसास हुआ कि गेम जल्दी ही सरल से काफी जटिल तक जा सकते हैं।


वास्तव में, मेरे दोस्तों ने मुझसे दृढ़तापूर्वक इस पर समय बर्बाद न करने का आग्रह किया, और ईमानदारी से कहूं तो, वे शायद सही थे, लेकिन मेरे पास बिल्डिंग कोड डेमो का एक लंबा इतिहास है जिसका कोई मतलब नहीं है। ;)


अपने डेमो के लिए, मैं निम्नलिखित नियमों के साथ गया:


  • जाहिर है, बुनियादी ब्लैकजैक नियम, बिना आगे बढ़े 21 के करीब पहुंचने का प्रयास करें।


  • कोई सट्टेबाजी नहीं, एक समय में सिर्फ एक हाथ।


  • कोई दोहरीकरण या विभाजन नहीं।


  • डीलर के पास "सॉफ्ट 17" नियम है। (मुझे पूरा यकीन है कि मैंने यह सही किया है।)


  • खेल छह डेक का उपयोग करता है (मैंने कहीं पढ़ा था कि यह मानक था)।

गेम सेटअप

प्रारंभ में, प्लेयर और कंप्यूटर दोनों के पास उनके हाथों का प्रतिनिधित्व करने वाली एक सरणी होती है।


 playerCards:[], pcCards:[],


deal पद्धति दोनों खिलाड़ियों के लिए हाथ सेट करने को संभालती है:


 async deal() { // first to player, then PC, then player, then PC this.playerCards.push(await this.drawCard()); // for the dealer, the first card is turned over let newcard = await this.drawCard(); newcard.showback = true; this.pcCards.push(newcard); this.playerCards.push(await this.drawCard()); this.pcCards.push(await this.drawCard()); },


दो बातें इंगित करने योग्य हैं। सबसे पहले, मैं खिलाड़ी से डील करता हूं, फिर पीसी से (या डीलर से, नाम के हिसाब से मैं आगे-पीछे जाता हूं), और फिर वापस आता हूं। मैं showback सेट के लिए कार्ड परिणाम ऑब्जेक्ट को भी संशोधित करता हूं ताकि मैं डीलर के लिए कार्ड का पिछला भाग प्रस्तुत कर सकूं।


HTML में यह इस प्रकार किया जाता है:


 <div id="pcArea" class="cardArea"> <h3>Dealer</h3> <template x-for="card in pcCards"> <!-- todo: don't like the logic in template --> <img :src="card.showback?BACK_CARD:card.image" :title="card.showback?'':card.title"> </template> </div> <div id="playerArea" class="cardArea"> <h3>Player</h3> <template x-for="card in playerCards"> <img :src="card.image" :title="card.title"> </template> </div>


BACK_CARD बस एक स्थिरांक है:


 const BACK_CARD = "https://deckofcardsapi.com/static/img/back.png";

खेल तर्क

तो, इस बिंदु पर, मैं ऐप पर क्लिक कर सकता हूं और ब्लैकजैक हाथ प्राप्त कर सकता हूं:


कार्डों का डेमो प्रदर्शित किया गया


नीचे, मैंने वर्तमान स्थिति प्रदर्शित करने के लिए एक div का उपयोग किया:


सफ़ेद स्टेटस बॉक्स खिलाड़ी से पूछता है कि वे क्या करना चाहते हैं।


मेरा तर्क इस प्रकार था:


  • खिलाड़ी से शुरुआत करें और उन्हें हिट करने दें या खड़े रहने दें।


  • यदि वे हिट होते हैं, तो एक नया कार्ड जोड़ें और देखें कि क्या वे विफल हो गए हैं।


  • यदि वे खड़े हैं, तो डीलर को खिलाड़ी बनने दें।


आइए पहले खिलाड़ी पर ध्यान दें। हिट करने के लिए, हम बस एक कार्ड जोड़ते हैं:


 async hitMe() { this.hitMeDisabled = true; this.playerCards.push(await this.drawCard()); let count = this.getCount(this.playerCards); if(count.lowCount >= 22) { this.playerTurn = false; this.playerBusted = true; } this.hitMeDisabled = false; },


बस्ट जाँच करना थोड़ा जटिल था। मैंने हाथ की 'गिनती' प्राप्त करने के लिए एक फ़ंक्शन बनाया, लेकिन ब्लैकजैक में, इक्के 1 या 11 हो सकते हैं।


मुझे पता चला (और आशा है कि मैं सही हूं), कि आपके पास कभी भी दो 'उच्च' इक्के नहीं हो सकते हैं, इसलिए मेरा फ़ंक्शन एक lowCount और highCount मान लौटाता है, जहां उच्च संस्करण के लिए, यदि एक ऐस मौजूद है, तो इसे 11 के रूप में गिना जाता है, लेकिन केवल एक। यहाँ वह तर्क है:


 getCount(hand) { /* For a hand, I return 2 values, a low value, where aces are considered 1s, and a high value, where aces are 11. Note that this fails to properly handle a case where I have 3 aces and could have a mix... although thinking about it, you can only have ONE ace at 11, so maybe the logic is: low == all aces at 1. high = ONE ace at 11. fixed! */ let result = {}; // first we will do low, all 1s let lowCount = 0; for(card of hand) { if(card.value === 'JACK' || card.value === 'KING' || card.value === 'QUEEN') lowCount+=10; else if(card.value === 'ACE') lowCount += 1; else lowCount += Number(card.value); //console.log(card); } //console.log('lowCount', lowCount); let highCount = 0; let oneAce = false; for(card of hand) { if(card.value === 'JACK' || card.value === 'KING' || card.value === 'QUEEN') highCount+=10; else if(card.value === 'ACE') { if(oneAce) highCount += 1; else { highCount += 10; oneAce = true; } } else highCount += Number(card.value); } //console.log('highCount', highCount); return { lowCount, highCount }; },


यदि खिलाड़ी विफल हो जाता है, तो हम खेल समाप्त कर देते हैं और उपयोगकर्ता को फिर से शुरू करने देते हैं। यदि वे खड़े रहते हैं, तो डीलर के लिए कार्यभार संभालने का समय आ गया है। वह तर्क सरल था - 17 से नीचे हिट करें और या तो बस्ट करें या खड़े रहें।


इसे थोड़ा और रोमांचक बनाने के लिए, मैंने डीलर के कार्यों को धीमा करने के लिए एक वेरिएबल और एसिंक फ़ंक्शन, delay उपयोग किया, ताकि आप उन्हें (थोड़े) वास्तविक समय में खेलते हुए देख सकें। यहाँ डीलर का तर्क है:


 async startDealer() { /* Idea is - I take a card everytime I'm < 17. so i check my hand, and do it, see if im going to stay or hit. if hit, i do a delay though so the game isn't instant. */ // really first, initial text this.pcText = 'The dealer begins their turn...'; await delay(DEALER_PAUSE); // first, a pause while we talk this.pcText = 'Let me show my hand...'; await delay(DEALER_PAUSE); // reveal my second card this.pcCards[0].showback = false; // what does the player have, we need the best under 22 let playerCount = this.getCount(this.playerCards); let playerScore = playerCount.lowCount; if(playerCount.highCount < 22) playerScore = playerCount.highCount; //console.log('dealer needs to beat', playerScore); // ok, now we're going to loop until i bust/win let dealerLoop = true; while(dealerLoop) { let count = this.getCount(this.pcCards); /* We are NOT doing 'soft 17', so 1 ace always count as 11 */ if(count.highCount <= 16) { this.pcText = 'Dealer draws a card...'; await delay(DEALER_PAUSE); this.pcCards.push(await this.drawCard()); } else if(count.highCount <= 21) { this.pcText = 'Dealer stays...'; await delay(DEALER_PAUSE); dealerLoop = false; this.pcTurn = false; if(count.highCount >= playerScore) this.pcWon = true; else this.playerWon = true; } else { dealerLoop = false; this.pcTurn = false; this.pcBusted = true; } } }


आपकी जानकारी के लिए, गेम संदेशों को सेट करने के तरीके के रूप में pcText उपयोग सफेद स्थिति क्षेत्र में किया जाता है।


और मूलतः - बस इतना ही. यदि आप इसे स्वयं खेलना चाहते हैं, तो नीचे दिए गए कोडपेन को देखें, और बेझिझक इसे फोर्क करें और सुधार जोड़ें: