본문 바로가기
공부

C++ 블랙잭(1:1) 코드 복습

by MY블로그 2022. 11. 14.

오늘 수업 풀이를 복습해봤다.

플레이어의 이름을 설정하고 딜러와 1:1의 대결의 단순한 구조이지만

손으로 다시 직접입력해보면서많이 어려웠다...

함수의 구조 자체도 아직 이해가 따라가지 않고있는느낌이다.

#include<iostream>
#include<time.h>
#include<string>
#include<vector>
#define SET 3

using namespace std;

enum Shape
{
	DIA,
	CLOVER,
	HEART,
	SPADE
};

enum Num
{
	A = 1,
	J = 11,
	Q,
	K
};

struct Card
{
	int num;
	string shape;

	void Print()
	{
		switch(num)
		{
			case A:
				cout << shape << "A" << "\t";
				break;
			case J:
				cout << shape << "J" << "\t";
				break;
			case Q:
				cout << shape << "Q" << "\t";
				break;
			case K:
				cout << shape << "K" << "\t";
				break;
			default:
				cout << shape << num << "\t";
				break;
		}
	}
};

struct Player //플레이어의 구조체(돈 이름 카드 점수)
{
	int money;
	string name;
	vector<Card>card;
	int jokbo = 0; // 카드의 합계산식
	bool win; //승패 판별용 

	void MakeJokbo()
	{
		jokbo = 0;
		for (int i = 0; i < card.size(); i++)
		{
			if (card[i].num > 10) jokbo += 10; //카드가 10이상인경우 최대 10까지만 더해지도록
			else jokbo += card[i].num; //그외에는 카드숫자 그대로 더하기.
		}
	}
	void Print(bool dealer = 0)
	{
		cout << name << "\t";
		for (int i = 0; i < card.size(); i++)
		{
			card[i].Print();
		}

		cout << "점수 : " << jokbo << "\t";

		if (!dealer)
		{
			cout << "소지금 : " << money << "\t";
		}
		cout << endl;
	}
};

Card MakeDeck(int num, string shape)
{
	Card temp;
	temp.num = num;
	temp.shape = shape;

	return temp;
}

void Shuffle(vector<Card>& deck)
{
	for (int i = 0; i < 1000; i++)
	{
		int sour = rand() % (52 * SET);
		int dest = rand() % (52 * SET);

		Card temp = deck[sour];
		deck[sour] = deck[dest];
		deck[dest] = temp;
	}
}
//=======================================================메인 시작
int main()
{
	srand(time(NULL));

	vector<Card>deck;
	Player player;
	Player dealer;

	int cardCount = 0;
	int input;

	//=============================================덱만들기
	for (int i = 0; i < 52*SET; i++)
	{
		string temp;
		int cut = i % 52;

		switch (cut / 13)
		{
		case DIA:
			temp = "◆";
				break;
		case CLOVER:
			temp = "♣";
				break;
		case HEART:
			temp = "♥";
				break;
		case SPADE:
			temp = "♠";
				break;
		}
		deck.push_back(MakeDeck(i % 13 + 1, temp));
	}

	cout << "플레이어의 이름 입력 : "; cin >> player.name;

	dealer.name = "딜러";
	player.money = 50000;
	dealer.money = 50000;

	//============================================================================게임시작

	while (true) //계속반복
	{
		cardCount = 0; //카드의합 초기화
		Shuffle(deck); //덱 섞기
		player.win = true; //플레이어의 상태 일단 게임진행중에는 승리=참
		player.money -= 1000; //매게임 진행시 1000원씩 차감.

		player.card.clear(); //새롭게 패를 받으려면 기존에 받았던 카드들은 초기화
		player.card.push_back(deck[cardCount]); 
		cardCount++; //덱을받으면 덱의인데스는 하나씩증가된다>>다음패를받을수있게.	
		player.card.push_back(deck[cardCount]);
		cardCount++; //게임 시작할때 2개의 패를 벡터로 받는다.

		cout << "===================================My TURN" << endl;
		player.MakeJokbo(); //플레이어의 카드의 합계산
		player.Print(); //플레이어의 카드패 출력

		//카드2개를 출력시킨뒤 새로운 카드를 받을지 안받고 승부할지
		while (true)
		{
			cout << endl;
			cout << "[1]새카드 추가 / [2]승부";
			cin >> input;
			//입력에따른 조건 걸기
			if (input == 2) break;  // 조건은 승부시에 브레이크걸어줌.

			player.card.push_back(deck[cardCount]); //2번 이외에는 1번뿐이니 카드추가
			cardCount++; //카드카운트 증가
			player.MakeJokbo(); //카드의합 추가후 다시구하기
			player.Print(); //추가된카드 포함시켜서 다시 출력

			if (player.jokbo > 21) //플레이어 카드수의 합이 21을넘길시
			{
				cout << "플레이어 버스트" << endl;
				player.win = false; //플레이어의 상태가 승리(참)에서 패배(거짓)으로변경.
				break; //바로위 반복문을벗어난다. (처음의 반복문부터 다시시작)
			}
			else player.win = true; //그외에는 플레이어의 상태가 그대로 승리(참)유지.
		}

		//===============================================================================딜러
		dealer.win = true; //딜러의 상태도 게임도중은 항상 승리(참)상태로.
		dealer.card.clear(); //딜러의 첫시작때마다 패정리(초기화)
		dealer.card.push_back(deck[cardCount]);
		cardCount++; //덱을받으면 덱의인데스는 하나씩증가된다>>다음패를받을수있게.	
		dealer.card.push_back(deck[cardCount]);
		cardCount++; //게임 시작할때 2개의 패를 벡터로 받는다.

		cout << "===================================Dealer TURN" << endl;
		dealer.MakeJokbo(); //딜러의 카드의 합계산
		dealer.Print(); //딜러의 카드패 출력

		//딜러는 카드패의 합이 17미만일때 자동으로 더받기하도록 설정한다.
		while (dealer.jokbo < 17)
		{
			dealer.card.push_back(deck[cardCount]); //하나 새로받고
			cardCount++; //카운트증가
			dealer.MakeJokbo(); //새로받은 딜러의 카드의 합계산
			dealer.Print(true); //새로받고 딜러의 카드패 출력
			//조건생성
			if (dealer.jokbo > 21) //딜러카드패의 합이 21이 넘게되면 패배
			{
				cout << "딜러의 버스트 플레이어 승리" << endl;
				player.money += 3000;
				dealer.win = false; //딜러가 버스트하면 상태가 승리(참)에서 패배(거짓)으로 변경.
				break; //반복문 탈출
			}
			else dealer.win = true; //딜러의 버스트상태시 외에는 게임진행가능한 승리(참)상태유지.
		}

		//====================================플레이어와 딜러의 상태 세팅이 끝난후 승패비교 시작
		if (dealer.win && player.win) //딜러 플레이어 양쪽이 버스트되지않은상태일때
		{
			if (dealer.jokbo < player.jokbo) // 플레이어의 합이 딜러의 합보다 클경우
			{
				cout << "플레이어의 승리" << endl;
				player.money += 3000;
			}
			//그외 딜러의 승리
			else cout << "딜러의 승리" << endl;
		}
	}
	return 0;
}

'공부' 카테고리의 다른 글

C++ OOP 조사  (0) 2022.11.15
블랙잭 과제 (진행중)  (0) 2022.11.15
시험 오답 노트(복습용/비공개)  (0) 2022.11.13
22.11.09 복습  (0) 2022.11.09
복습 - 행렬 회전 과제  (0) 2022.11.09

댓글