見出し画像

#9 【React.jsで、BlackJackを作る】:ディーラーがカードを引く処理を実装する

これまで

前回は、state の管理の方法を見直しました。

BlackJack アプリの sandbox

BlackJack アプリの sandbox は以下です。

この sandbox は、連載が進むのと同時に更新されていきます
「私も作りたい!」という方は、フォークして一緒に作り始めることができます。

はじめから作りたい方はこちら

関数 getRankNum(rank) を修正する

ディーラーがカードを引く処理を実装するためには、カードのランク(数字)を合計する必要があります。
ブラックジャックでは、絵札(J, Q, K)はすべて 10 と数えます。
なので、まずはランクを数値に変換する関数 getRankNum(rank) を修正しましょう。

function getRankNum(rank) {
 switch (rank) {
   case "A":
     return 1;
   case "J":
   case "Q":
   case "K":
     return 10;
   default:
     return Number(rank);
 }
}

A は 1 とも 11 とも解釈できますが、ここではひとまず 1 のままにしておきます。

ハンドのランクを合計する関数 getTotal() を定義する

ハンドを引数で受け取り、ランクを合計します。
forEach() などでもよいでしょう。

function getTotal(hand) {
 let total = 0;
 for (const card of hand) {
   total += getRankNum(card.rank);
 }
 return total;
}

ディーラーがカードを引く処理を実装する

ディーラーはハンドの合計が 17 以上になるまで引き続けます

function reducer(state, action) {
 switch (action.type) {
   省略
   case "open": {
     const [newDeck, newHand] = dealForDealer(state.deck, state.dealersHand);
     return { ...state, deck: newDeck, dealersHand: newHand };
   }
   default:
 }
}
function dealForDealer(deck, hand) {
 const newDeck = deck.slice();
 const newHand = hand.slice();
 while (getTotal(newHand) < 17) {
   const index = Math.floor(Math.random() * newDeck.length);
   newHand.push(newDeck[index]);
   newDeck.splice(index, 1);
 }
 return [newDeck, newHand];
}

繰り返し判定処理を抜き出す

現状、while文の繰り返し判定は単純に「17 より少なければ繰り返す」となっています。
でも実際には、ソフトハンドかどうかのチェックも必要です。
この判定処理を関数に抽出します。

function hasAce(hand){
 for(const card of hand){
   if(card.rank === "A")return true
 }
 return false
}
function checkDealersScore(hand){
 let total = getTotal(hand)
 // ソフトハンドのとき、Aceを 11 と数える
 if(hasAce(hand)){
   total += 10
 }
 if(total < 17){
   return true
 }
 return false
}

ハンドに A があるかを関数 hasAce(hand) に抽出しました。
そして、A があれば total を +10 するようにしています。

つまり、ディーラーの場合は A を必ず 11 と考えるようにしています。
「ソフト 17 のときにディーラーはどうするか」という情報はありますが、「ソフト 18 以上のとき A を 1 と考えるのか」についてはわかりませんでした。
ご存知の方は教えて下さい!

他のアプリの挙動も参考にしつつ、ここではひとまず「 ソフト 17 以上であれば STANDする」とします。

現在の画面

今回の修正で画面は以下のようになりました。
ディーラーがカードを引いてバーストしたところです。

画像1

詳しい変更はこちら

Codesandbox は GitHub連携ができます。
以下は今回のコミットによる差分です。

次回

ディーラーの動きはひとまずこれでよしとして、次回はプレイヤー側の処理に戻ります。
ヒットしてバーストした場合の処理や、現在のハンドのスコアを表示します。

この記事があなたのお役に立ちましたら、よろしければサポートをお願いいたします! より良い記事をお届けできるよう、活動費に充てさせていただきます。