블랙잭(BLACKJACK) 게임
in Diary
자바로 만드는 블랙잭(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);
}
}
}