[소스코드] BLACKJACK 게임 소스코드 및 설명(주석으로 대체)

스크린샷 2018-03-29 오후 4.01.48.png

@capcoms 님께서 위에서 처럼 코드리뷰를 부탁하셔서 html 소스로 만든 blackjack 을 공개 합니다.

부족한 점이나 궁금한 점이 있다면 댓글로 부탁 드립니다.

참고로 실제 steemit에서는 nodejs 기반으로 작성 되었고 아래 소스를 이해하시고 있다면, steem-js 를 활용하여 충분히 게임을 만들어 보실 수 있을 것입니다.

<script>

// format 함수를 생성
// printf 와 유사하다 생각하면 됨
if (!String.prototype.format) {
    String.prototype.format = function() {
        var args = arguments;
        return this.replace(/{(\d+)}/g, function(match, number) {
            return typeof args[number] != 'undefined' ?
                args[number] :
                match;
        });
    };
}

// 카드를 생성한다
// 4 x 12 = 총 48 장의 카드를 생성하여 배열에 담아 놓는다.
function genDeck(){
  var arr = [];
  for(var i=0;i<CARD_T.length;i++){
    for(var j=0;j<CARD_N.length;j++){
      arr.push(CARD_T[i]+" "+CARD_N[j]);
    }
  }
  return arr;
}

// 카드를 섞는다
// arr : 카드 목록
function doShuffle(arr){

  const CARD_COUNT = CARD_T.length * CARD_N.length;
  const TIMES = 10;

  for(var i=0;i<CARD_COUNT*TIMES;i++){
    // 맨 앞 카드를 뽑아 랜덤한 위치에 다시 집어 넣는다.
    arr.splice(getRandomInt(CARD_COUNT),0,arr.shift());
  }
  
  return arr;
}

// 덱에서 카드를 cnt 장 만큼 뽑아낸다.
// deck : 카드목록
// curr : 뽑아낸 카드목록 
// cnt : 뽑을 카드 숫자
function drawCards(deck, curr, cnt){
  if(curr==undefined){
    curr = [];
  }

  if(cnt==undefined){
    cnt = 2;
  }

  for(var i=0;i<cnt;i++){
    curr.push(deck.shift());  
  }

  return curr;
}

// 카드 카운팅을 위해 숫자정보로 반환 ( 영문 : 10 , A카드는 1또는 11)
// str : 카드숫자(또는 기호)
function getCardNum(str){
  var n = str.split(' ')[1];
  if(isNaN(n)){
    if(n=='A'){
      return 11;
    }
    return 10;
  }
  return Number(n);
}

// 획득한 카드의 카운팅 값을 알려준다
// arr : 카드 목록
function sumCardNum(arr){
  
  // 카드 값을 정렬한다
  var t = [];
  arr.forEach(n=>{
    t.push(getCardNum(n));
  });
  t.sort((a, b)=>a-b);

  // 카드의 값에서 11을 포함한지 여부를 파악하면서 더한다.
  var sum = 0;
  var acard = 0;
  for(var i=0;i<t.length;i++){
    var c = t[i];
    if(c==11){
      sum+=1;
      acard++;
    }else{
      sum+=t[i];  
    }
  }

  // A카드를 포함한 경우 21을 초과하지 않는 경우에 한정하여 10을 더한다.
  if(sum<=11 && acard>=1){
    sum+=10;
  }

  // console.log( "sorted ", t ) ;

  return sum;
}

// 0 부터 max-1 까지의 랜덤한 정수를 반환한다
// max : 최대 숫자 
function getRandomInt(max) {
    return Math.floor(Math.random() * Math.floor(max));
}

// 게임 결과를 출력한다
// res : 플레이어 정보
function printGameResult(res){
  const contentLayout = "{3} [{0}] | 합 : {1} {2}";
  var message = contentLayout.format(
    res.cards.join(", ")
    , res.sum
    , res.isBust?"( BUST !! )":""
    , res.name
  );
  return message;
}

// 댁 정보를 기반으로 게임을 시작한다
// deck : 초기 댁
// name : 플레이어 명
function makeGame(deck, name){

  var hitCount = 0;
  var isBust = false;
  var cards = drawCards(deck, null, DRAW_FIRST );

  // 카드 자동 hit 처리
  while( sumCardNum(cards)<=STOP_CARD ){
    cards = drawCards(deck, cards, DRAW_MORE);
    hitCount++;
    if(hitCount>=MAX_HIT_COUNT){
      break;
    }
  }
  // 버스트 여부 판단
  if( sumCardNum(cards)>BLACKJACK ){
    isBust = true;
  }

  return { 
      "hit":hitCount, "deck":deck, "isBust":isBust, "sum":sumCardNum(cards)
      , "cards":cards, "name":name
   };
}

//////////////////////////////////////////////////////
//
//  설정 
//

const CARD_T = ["◇", "♡", "♠", "♣"];
const CARD_N = [2,3,4,5,6,7,8,9,'J','Q','K','A'];
const DRAW_FIRST = 2;     // 처음에 뽑는 카드 숫자
const DRAW_MORE = 1;      // HIT 시 더 뽑을 카드 숫자 
const STOP_CARD = 16;     // 룰 16 이상이면 무조건 멈춤(HIT를 하지 않음) 
const BLACKJACK = 21;     // 버스트(21) 여부를 판단할 때 사용
const MAX_HIT_COUNT = 3;  // 카드를 받을 수 있는 최대 제한 : (3인 경우)2+3 = 총 5장 

const deck = doShuffle(genDeck());

const player = makeGame(deck, "player");
const bot1 = makeGame(player.deck, "bot1");
const bot2 = makeGame(bot1.deck, "bot2");
const bot3 = makeGame(bot2.deck, "bot3");
const bot4 = makeGame(bot3.deck, "bot4");

const bots = [bot1, bot2, bot3, bot4];

var isWin = true;
var isDraw = false;

//////////////////////////////////////////////////////
//
//  게임 진행  
//

// 승리여부 검증 
bots.forEach(bot=>{
  if(player.isBust || ( !bot.isBust && player.sum<bot.sum )){
    isWin = false;
  }
});

// 동점여부 검증
if(isWin && !player.isBust){
  bots.forEach(bot=>{
    if(player.sum==bot.sum){
      isDraw = true;
    }
  });
}

//////////////////////////////////////////////////////
//
//  결과 출력   
//

var html = [];

html.push( printGameResult(player) );
html.push("");
html.push( printGameResult(bot1) );
html.push( printGameResult(bot2) );
html.push( printGameResult(bot3) );
html.push( printGameResult(bot4) );
html.push("");

if(isDraw){
  html.push( "DRAW" );
}else if(isWin){
  html.push( "YOU WIN" );
}else{
  html.push( "YOU LOSE" );
}

document.write(html.join("
"
)); </script>
H2
H3
H4
3 columns
2 columns
1 column
Join the conversation now