https://github.com/Bonnate/BlackJack
package Main;
import java.util.Scanner;
import java.util.Queue;
import java.util.LinkedList;
import java.util.Vector;
import java.util.Random;
public class BlackJack
{
FinishCode mCode;
//게임에 사용할 카드 개수 (기본은 13)
static public Integer MAX_CARD_COUNT = 13;
//게임 중 사용할 카드를 집어넣는 큐
private Queue<Integer> mCards;
//게임 중 각 참가자의 카드를 저장하는 벡터
private Vector<Integer> mPlayerCard;
private Vector<Integer> mDealerCard;
//생성자
public BlackJack()
{
mCards = new LinkedList<>();
mPlayerCard = new Vector<>();
mDealerCard = new Vector<>();
mCode = FinishCode.NONE;
InitGame();
}
//사용할 멤버변수들을 초기화한다
public void InitGame()
{
//임시로 카드들을 보관할 벡터 변수를 만든다
Vector<Integer> CardsTemp = new Vector<>();
//벡터 변수에 연속되는 수를 삽입한다.
for(int i = 1; i <= MAX_CARD_COUNT; ++i)
{
CardsTemp.add(i);
}
//랜덤 함수를 사용하기 위한 클래스를 생성한다.
Random random = new Random();
//MAX_CARD_COUNT 까지의 랜덤수 두개를 받아 각 랜덤수의 위치에 해당하는 원소를 서로 바꾼다(swap)
for(int i = 0; i < 100; ++i)
{
int randPos1 = random.nextInt(MAX_CARD_COUNT);
int randPos2 = random.nextInt(MAX_CARD_COUNT);
if(randPos1 == randPos2)
{
continue;
}
int tempVal = CardsTemp.get(randPos1);
CardsTemp.set(randPos1, CardsTemp.get(randPos2));
CardsTemp.set(randPos2, tempVal);
}
//무작위로 섞은 MAX_CARD_COUNT개의 카드를 Queue에 삽입한다.
//함수가 끝나면 CardsTemp는 사라진다.
for(int i = 0; i < MAX_CARD_COUNT; ++i)
{
mCards.add(CardsTemp.get(i));
}
//딜러와 플레이어에게 중복되지 않은 카드를 각 두장씩 나눠준다.
//Queue의 Poll함수로 선두에있는 원소를 리턴하며 제거한다.
for(int i = 0; i < 2; ++i)
{
mPlayerCard.add(mCards.poll());
mDealerCard.add(mCards.poll());
}
}
//게임 실행
public void RunGame()
{
//매 턴마다 현재 카드들을 출력하고 시용자 입력을 받는다
do
{
DisplayInfo();
InputPlayer();
}
while (mCode == FinishCode.NONE); //mCode가 NONE(승부가 안난 상태)가 아니라면 빠져나와 결과를 출력한다.
//누가 승리했는지 출력
DisplayResult();
//현재 카드들을 한번 더 출력
DisplayInfo();
}
//현재 카드들을 출력하는 함수
public void DisplayInfo()
{
System.out.println("------------- Jack's BlackJack Game -------------");
System.out.print(" # Dealer: ");
//0은 A로, 11이상은 각 J Q K로 출력한다 그 외는 정수 그대로
for(int i = 0; i < mDealerCard.size() - 1; ++i)
{
int tempVal = mDealerCard.get(i);
if(tempVal > 1 && tempVal < 11)
{
System.out.printf("%-3d", tempVal);
}
else if(tempVal == 1)
{
System.out.print("A ");
}
else if(tempVal == 11)
{
System.out.print("J ");
}
else if(tempVal == 12)
{
System.out.print("Q ");
}
else if(tempVal == 13)
{
System.out.print("K ");
}
}
if(mCode == FinishCode.NONE)
{
System.out.print('X');
}
else
{
int tempVal = mDealerCard.get(mDealerCard.size() - 1);
if(tempVal > 1 && tempVal < 11)
{
System.out.printf("%-3d", tempVal);
}
else if(tempVal == 1)
{
System.out.print("A ");
}
else if(tempVal == 11)
{
System.out.print("J ");
}
else if(tempVal == 12)
{
System.out.print("Q ");
}
else if(tempVal == 13)
{
System.out.print("K ");
}
}
System.out.println();
System.out.print(" # Player: ");
for(int i = 0; i < mPlayerCard.size(); ++i)
{
int tempVal = mPlayerCard.get(i);
if(tempVal > 1 && tempVal < 11)
{
System.out.printf("%-3d", tempVal);
}
else if(tempVal == 1)
{
System.out.print("A ");
}
else if(tempVal == 11)
{
System.out.print("J ");
}
else if(tempVal == 12)
{
System.out.print("Q ");
}
else if(tempVal == 13)
{
System.out.print("K ");
}
}
System.out.println();
System.out.println("-------------------------------------------------");
}
//사용자의 입력을 받는다, H / S
public void InputPlayer()
{
Scanner Scan = new Scanner(System.in);
System.out.print("Hit or Stand? (H/S): ");
String input = Scan.nextLine();
System.out.println();
//string - switch문에서 처리할때 사용자의 입력을 최대한 자연스럽게 받는다 (hit, Hit, h, H...)
switch(input)
{
case "h":
{
}
case "H":
{
}
case "Hit":
{
}
case "hit":
{
Hit();
break;
}
case "s":
{
}
case "S":
{
}
case "Stand":
{
}
case "stand":
{
Stand();
break;
}
default:
{
}
}
}
//Hit을 하면 플레이어의 카드벡터에 전체카드큐에서 poll하여 추가한다.
private void Hit()
{
mPlayerCard.add(mCards.poll());
//만약 추가했을 때 총 값이 21을 초과하면 플레이어는 BUSTED한다.
if(CalcPrice(true) > 21)
{
mCode = FinishCode.PLAYERBUSTED;
}
}
//Stand을 하면 딜러의 카드벡터에 전체카드 큐를 17이상이 될때까지 전체카드큐에서 poll한다.
private void Stand()
{
while(CalcPrice(false) < 17)
{
mDealerCard.add(mCards.poll());
}
//만약에 21보다 커지면 딜러는 BUSTED한다.
if(CalcPrice(false) > 21)
{
mCode = FinishCode.DEALERBUSTED;
}
//그것이 아니라면 플레이어와 딜러의 값을 비교할 필요가 있다.
else
{
mCode = FinishCode.NEEDCALC;
}
}
//플레이어 또는 딜러의 카드값을 계산한다. 매개변수가 true이면 플레이어, false이면 딜러.
//★ 두개를 flag할때 bool이 나은가 enum이 나은가 int형으로 받아올지 질문하기 ★
private int CalcPrice(boolean isPlayer)
{
int sumRes = 0;
int tempValue;
if(isPlayer)
{
for(int i = 0; i < mPlayerCard.size(); ++i)
{
tempValue = mPlayerCard.get(i);
//받아온 값이 10보다 크면 그 값은 10으로한다 (J Q K는 10으로 간주함)
if(tempValue > 10) tempValue = 10;
sumRes += tempValue;
}
}
else
{
for(int i = 0; i < mDealerCard.size(); ++i)
{
tempValue = mDealerCard.get(i);
if(tempValue > 10) tempValue = 10;
sumRes += tempValue;
}
}
return sumRes;
}
//게임이 끝나면 누가 이겼는지 계산한다.
private void CalcWinner()
{
int playerVal = CalcPrice(true);
int dealerVal = CalcPrice(false);
if(playerVal > 21 && dealerVal > 21)
{
mCode = FinishCode.DRAW;
}
else if(playerVal == dealerVal)
{
mCode = FinishCode.DRAW;
}
else if(playerVal > dealerVal)
{
mCode = FinishCode.PLAYER;
}
else
{
mCode = FinishCode.DEALER;
}
}
//enum타입의 FinishCode에 따라 알맞은 결과를 출력한다.
@SuppressWarnings("incomplete-switch")
private void DisplayResult()
{
switch(mCode)
{
case NEEDCALC:
{
CalcWinner();
DisplayResult();
return;
}
case DRAW:
{
System.out.print("Equal points...");
break;
}
case PLAYER:
{
System.out.print("Player Wins...");
break;
}
case PLAYERBUSTED:
{
System.out.print("Player Busted...");
break;
}
case DEALER:
{
System.out.print("Dealer Wins...");
break;
}
case DEALERBUSTED:
{
System.out.print("Dealer Busted...");
break;
}
}
//사용자가 쉽게 결과를 파악하기 위해 플레이어와 딜러의 각 합계를 출력해준다
System.out.println("\t [Player:" + CalcPrice(true) + " : Dealer:" + CalcPrice(false) + ']');
}
}
'기타 > univ. projects' 카테고리의 다른 글
[유니티] 게임엔진응용실습 Unit2 프로젝트 - 장애물 코스 피하기 게임 (0) | 2022.09.13 |
---|---|
[유니티] 게임엔진응용실습 Unit1 프로젝트 (Unity 기초) (0) | 2022.09.13 |
[자바] 멀티미디어자바프로젝트II ch.03 연습문제 (0) | 2022.09.13 |
[자바] 멀티미디어자바프로젝트II ch.02 연습문제 (0) | 2022.09.06 |
[자바] JFrame 블랙잭(BlackJack) 게임 구현 (0) | 2022.07.15 |