[소스코드] BLACKJACK 게임 소스코드 및 설명(주석으로 대체)
@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>
@블랙잭
이렇게 하면 되는건가요? :-)
DRAW
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
you [♣ K, ♡ 9] | 합 : 19
bot1 [◇ K, ♠ Q] | 합 : 20
bot2 [♣ A, ◇ 8] | 합 : 19
bot3 [♡ 8, ◇ 9] | 합 : 17
bot4 [◇ A, ♡ A, ♡ 5] | 합 : 17
@블랙잭
YOU LOSE
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
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
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
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
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 켜두는 편이 속편해서요 ㅋ
오호 직접 가동하고 있었군요... 답변 감사합니다 :)
짱짱맨 부활!
호출감사합니다
@블랙잭