블랙잭(BLACKJACK) 게임

블랙잭(BLACKJACK) 게임

자바로 만드는 블랙잭(BLACKJACK) 게임

 

📕 개발자가 반드시 정복해야 할 객체지향과 디자인 패턴 - 최범균 저

 

요즘 보고있는 책인데, 이 책을 보면서 정말 많은 것들을 깨닫고있다.

변화에 유연한 구조를 위한 OOP의 이론을 담기위해 연습하고있다.

그래서 블랙잭을 구현해보았다.

아직 미흡하지만 두더지 잡기 만들때에 비하면 많이 나아진 걸 느낀다.

 

public class Main {

    /* --------------------------------------------------------------
     * 첫 턴 카드 받을 때 딜러와 플레이어는 2장씩 받음
     * A는 기본적으로 1점으로 계산하되 두장의 합이 21점이 될 수 있을 경우 11점으로 계산함
     * 받은 2장의 카드합이 21이 될 경우(블랙잭) = A + 10 or J or Q or K : 11 + 10 = 21
     *
     * 딜러는 17점 이상이 될 경우 카드를 뽑지 않음
     * 플레이어는 21점 이상이 될 경우 패배함
     * 플레이어는 매 턴마다 게임을 멈추고 승패를 가릴지, 카드를 새로 뽑을지 추가할 수 있음
     * 플레이어의 점수가 딜러보다 높을 경우 승리
     *
     * 플레이어는 승리 할 경우 걸은 베팅액 만큼의 돈을 추가로 얻음
     * 플레이어는 패배 할 경우 걸은 베팅액 만큼의 돈을 잃음
     -------------------------------------------------------------- */
     
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Player player = new Player();
        Player dealer = new Player();
        Blackjack blackjack = new Blackjack();

        System.out.println("게임을 시작합니다.");
        System.out.println("지갑 잔액 : " + player.getWallet());
        System.out.println("배팅할 금액을 입력하세요.");
        int bet = sc.nextInt();
        player.setWallet(bet);
        sc.nextLine();

        System.out.println("카드를 2장씩 받습니다.");
        blackjack.firstGetCard(player, dealer);
        System.out.println("플레이어 카드 : " + player.playerScore());
        System.out.println("딜러 카드 : " + dealer.playerScore());

        //2장 받은 시점에서 플레이어의 카드 합이 21점이 넘을 경우 패배
        if(player.playerScore() > 21) {
            System.out.println("패배");
            System.out.println("지갑 잔액 : " + player.getWallet());
            System.out.println("게임 끝");
            sc.close();
            System.exit(0);
        }

        while(true) {
            //카드를 추가로 뽑을지 승패비교를 할지 선택
            System.out.println("카드를 받는다. = Y");
            System.out.println("멈춘다 = N");

            String select = sc.nextLine();

            //카드를 추가로 뽑을 경우
            if(select.equals("Y") || select.equals("y")) {
                blackjack.getCard(player);

                //딜러의 카드합이 17점이 넘을경우 딜러는 카드를 뽑지 않음
                if(dealer.playerScore() < 17) {
                    blackjack.getCard(dealer);
                    System.out.println("딜러 카드 : " + dealer.playerScore());
                }

                System.out.println("플레이어 카드 : " + player.playerScore());
                System.out.println("딜러 카드 : " + dealer.playerScore());

                //카드 합이 21점이 넘을 경우 패배
                if(player.playerScore() > 21) {
                    System.out.println("패배");
                    System.out.println("지갑 잔액 : " + player.getWallet());
                    break;
                }
            }

            //게임을 중단할 경우
            else if(select.equals("N") || select.equals("n")) {

                //딜러의 카드합이 17점이 넘을경우 딜러는 카드를 뽑지 않음
                if(dealer.playerScore() < 17) {
                    blackjack.getCard(dealer);
                    System.out.println("딜러 카드 : " + dealer.playerScore());
                }

                //플레이어와 딜러의 점수가 같을 경우 무승부, 베팅액은 돌려받음
                if(player.playerScore() == dealer.playerScore()) {
                    System.out.println("무승부");
                    player.resetWallet(bet);
                    System.out.println("지갑 잔액 : " + player.getWallet());
                    break;
                }

                //플레이어의 점수가 딜러의 점수보다 높을 경우 승리
                if(player.playerScore() > dealer.playerScore()) {
                    System.out.println("승리");
                    player.betting(bet);
                    System.out.println("지갑 잔액 : " + player.getWallet());
                    break;
                }

                //플레이어의 점수가 딜러의 점수보다 낮을 경우 패배
                else {
                    System.out.println("패배");
                    System.out.println("지갑 잔액 : " + player.getWallet());
                    break;
                }
            }
        } // while end
        System.out.println("게임 끝");
        sc.close();
    }
}

 

public class Player {
    private List<Integer> myCardPack = new ArrayList<>();
    private int wallet = 300000;

    //카드팩에서 카드를 받아 플레이어의 카드덱에 추가함
    public void addCard(int card) {
        myCardPack.add(card);
    }

    //플레이어의 카드덱의 점수 합계를 구하여 리턴
    public int playerScore() {
        int sum = 0;

        for(Integer e : myCardPack) {
            sum += e;
        }

        return sum;
    }

    //지갑 잔액을 리턴
    public int getWallet() {
        return wallet;
    }

    //베팅할 경우 지갑에서 베팅액을 차감
    public void setWallet(int bet) {
        this.wallet -= bet;
    }

    //무승부일 경우 지갑에 베팅액을 돌려줌
    public void resetWallet(int bet) {
        this.wallet += bet;
    }

    //베팅액의 2배를 지갑에 추가함
    public void betting(int bet) {
        this.wallet += bet * 2;
    }
}

 

public class Blackjack {
    //카드팩에 52장의 카드를 추가함
    private String[] cardPack = {
            "sA", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "sj", "sq", "sk",
            "dA", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "dj", "dq", "dk",
            "hA", "h2", "h3", "h4", "h5", "h6", "h7", "h8", "h9", "h10", "hj", "hq", "hk",
            "cA", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "cj", "cq", "ck"
    };
    
    //카드팩 HashMap
    private HashMap<String, Integer> cards;

    //카드팩을 shuffle메서드를 이용하여 섞음
    private String[] shuffleCardPack = shuffle(cardPack);

    //카드를 한장씩 뽑기 위한 카운터
    private int cnt = 0;

    //카드팩을 섞기 위한 shuffle 메서드
    public String[] shuffle(String[] cardPack) {
        for(int i = 0; i < cardPack.length; i++) {
            int x = (int) (Math.random() * cardPack.length);
            int y = (int) (Math.random() * cardPack.length);

            String temp = cardPack[x];
            cardPack[x] = cardPack[y];
            cardPack[y] = temp;

        }

        //카드팩의 HashMap을 생성
        cards = new HashMap<>();
        for(String str : cardPack) {
            String num = str.substring(1);
            try {
                int value = Integer.valueOf(num);
                cards.put(str, value);
            }
            catch(NumberFormatException e) {
                if(num.equals("A")) {
                    cards.put(str, 1);
                }
                else {
                    cards.put(str, 10);
                }
            }
        }
        //무작위로 섞인 카드팩을 리턴
        return cardPack;
    }

    //카드 한장 뽑기
    public void getCard(Player player) {
        player.addCard(compareCard(shuffleCardPack[cnt++]));
    }

    //String 타입으로 넘겨받은 카드를 점수로 환산하기 위한 메서드 ex) 스페이드2(s2) = 2점 
    public int compareCard(String card) {
        return cards.get(card);
    }

    //처음 2장받는 카드의 알고리즘, 두 카드의 합이 21이 될 수 있는 경우 A의 점수를 11로 환산하여 계산. 플레이어(player)와 딜러(dealer) 동일
    public void firstGetCard(Player player, Player dealer) {
        boolean condiOne = false, condiTwo = false, condiThree = false, condiFour = false, blackJackConditionOne = false;

        Integer firstCard = cards.get(shuffleCardPack[cnt++]);
        if(firstCard == 1) condiOne = true;
        if(firstCard == 10) condiTwo = true;

        Integer secondCard = cards.get(shuffleCardPack[cnt++]);
        if(secondCard == 1) condiThree = true;
        if(secondCard == 10) condiFour = true;

        if((condiOne == true || condiThree == true) && (condiTwo == true || condiFour == true)) {
            blackJackConditionOne = true;
        }

        if(blackJackConditionOne) {
            if(condiOne) {
                player.addCard(11);
            }
            else {
                player.addCard(firstCard);
            }

            if(condiThree) {
                player.addCard(11);
            }
            else {
                player.addCard(secondCard);
            }
        }

        else {
            player.addCard(firstCard);
            player.addCard(secondCard);
        }

        firstCard = cards.get(shuffleCardPack[cnt++]);
        if(firstCard == 1) condiOne = true;
        if(firstCard == 10) condiTwo = true;

        secondCard = cards.get(shuffleCardPack[cnt++]);
        if(secondCard == 1) condiThree = true;
        if(secondCard == 10) condiFour = true;

        if((condiOne == true || condiThree == true) && (condiTwo == true || condiFour == true)) {
            blackJackConditionOne = true;
        }

        if(blackJackConditionOne) {
            if(condiOne) {
                dealer.addCard(11);
            }
            else {
                dealer.addCard(firstCard);
            }
			
            if(condiThree) {
                dealer.addCard(11);
            }
            else {
                dealer.addCard(secondCard);
            }
        }

        else {
            dealer.addCard(firstCard);
            dealer.addCard(secondCard);
        }
    }
}

 


© 2022. All rights reserved.