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

in #wevent7 years ago

스크린샷 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("<br>"));

</script>
Sort:  

@블랙잭

이렇게 하면 되는건가요? :-)

DRAW

@frenzy27 ! 자 이제 게임을 시작하지
you [♡ Q, ♠ 6, ◇ 2] | 합 : 18

bot1 [♠ 4, ◇ 4, ♡ 5, ♣ Q] | 합 : 23 ( BUST !! )
bot2 [♠ 2, ◇ 6, ♡ J] | 합 : 18
bot3 [♡ 7, ♡ K] | 합 : 17
bot4 [♡ 6, ◇ J, ♡ A] | 합 : 17

YOU LOSE

@frenzy27 ! 자 이제 게임을 시작하지
you [♣ K, ♡ 9] | 합 : 19

bot1 [◇ K, ♠ Q] | 합 : 20
bot2 [♣ A, ◇ 8] | 합 : 19
bot3 [♡ 8, ◇ 9] | 합 : 17
bot4 [◇ A, ♡ A, ♡ 5] | 합 : 17

@블랙잭

YOU LOSE

@noctisk ! 자 이제 게임을 시작하지
you [♠ K, ♣ 6, ◇ 9] | 합 : 25 ( BUST !! )

bot1 [♠ A, ♠ 9] | 합 : 20
bot2 [♣ Q, ♠ 2, ♡ 3, ◇ 6] | 합 : 21
bot3 [♠ Q, ♣ 2, ◇ 2, ♡ 7] | 합 : 21
bot4 [♡ Q, ◇ 3, ♡ 5] | 합 : 18

재밌네요 ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ

와우~ 연구 해볼 가치가 있겠군요. 그런데 시간이 없다는 ㅠㅠ

나도 해봐야지
@블랙잭

YOU LOSE

@goodhello ! 자 이제 게임을 시작하지
you [♣ 7, ♠ J] | 합 : 17

bot1 [♠ 3, ♠ 2, ♣ 4, ♣ K] | 합 : 19
bot2 [♡ 9, ◇ 7, ♡ 4] | 합 : 20
bot3 [◇ Q, ♡ 5, ♣ J] | 합 : 25 ( BUST !! )
bot4 [♡ 3, ♠ Q, ♣ 3, ♡ 7] | 합 : 23 ( BUST !! )

우앗 감사합니다~~^^ 보고 따라 해보겠습니다~ 멋져~

@블랙잭 재밌네요 ㅎㅎ

YOU LOSE

@nhj12311 ! 자 이제 게임을 시작하지
you [♠ 3, ◇ J, ♣ J] | 합 : 23 ( BUST !! )

bot1 [♡ 4, ♣ 9, ♡ J] | 합 : 23 ( BUST !! )
bot2 [♣ 3, ♡ 8, ♠ K] | 합 : 21
bot3 [♣ 5, ◇ 4, ♠ J] | 합 : 19
bot4 [♡ 5, ♡ 6, ♡ K] | 합 : 21

YOU LOSE

@hellocrypto ! 자 이제 게임을 시작하지
you [◇ 8, ♠ 6, ♡ 8] | 합 : 22 ( BUST !! )

bot1 [♠ K, ◇ K] | 합 : 20
bot2 [◇ 6, ♣ K, ♣ 5] | 합 : 21
bot3 [♣ 2, ♣ 8, ♡ 7] | 합 : 17
bot4 [♣ A, ♣ 6] | 합 : 17

'@블랙잭'을 감지하는 스팀 blockchain stream하는 프로세스를 24시간 계속 켜두시나요? 구현 방법이 궁금하네요 :)

DRAW

@hellocrypto ! 자 이제 게임을 시작하지
you [♣ 7, ♠ 5, ♡ 9] | 합 : 21

bot1 [♡ 2, ◇ K, ♣ J] | 합 : 22 ( BUST !! )
bot2 [♠ A, ◇ A, ◇ 4, ♣ K, ♠ 6] | 합 : 22 ( BUST !! )
bot3 [♡ K, ◇ 5, ♠ 7] | 합 : 22 ( BUST !! )
bot4 [♣ 6, ♠ Q, ♡ 5] | 합 : 21

우분투가 설치된 맥미니를 24시간 기동중 입니다. ^^

외부 웹 호스팅이나 클라우드 서비스보다

직접 pc 켜두는 편이 속편해서요 ㅋ

오호 직접 가동하고 있었군요... 답변 감사합니다 :)

짱짱맨 부활!
호출감사합니다