Last active
March 3, 2024 08:53
-
-
Save muromtsev/dbbf5f036111585cd1476180709332be to your computer and use it in GitHub Desktop.
BlackJack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <array> | |
#include <cstring> | |
#include <cstdlib> | |
#include <ctime> | |
// перечисление для достоинств карт | |
enum CardRank | |
{ | |
RANK_2, | |
RANK_3, | |
RANK_4, | |
RANK_5, | |
RANK_6, | |
RANK_7, | |
RANK_8, | |
RANK_9, | |
RANK_10, | |
RANK_JACK, | |
RANK_QUEEN, | |
RANK_KING, | |
RANK_ACE, | |
MAX_RANK | |
}; | |
// перечисление для мастей карт | |
enum CardSuit | |
{ | |
SUIT_CLUBS, | |
SUIT_DIAMONDS, | |
SUIT_HEARTS, | |
SUIT_SPADES, | |
MAX_SUIT | |
}; | |
// структура карты | |
// rank - достоинство карты | |
// suit - масть карты | |
struct Card | |
{ | |
CardRank rank; | |
CardSuit suit; | |
}; | |
// вывод значения достоинства и масти определенной карты | |
// в виде 2-буквенного кода | |
// например 2J | |
// параметр - константная ссылка типа структуры Card | |
void printCard(const Card &card) | |
{ | |
switch (card.rank) | |
{ | |
case RANK_2: std::cout << "2"; break; | |
case RANK_3: std::cout << "3"; break; | |
case RANK_4: std::cout << "4"; break; | |
case RANK_5: std::cout << "5"; break; | |
case RANK_6: std::cout << "6"; break; | |
case RANK_7: std::cout << "7"; break; | |
case RANK_8: std::cout << "8"; break; | |
case RANK_9: std::cout << "9"; break; | |
case RANK_10: std::cout << "10"; break; | |
case RANK_JACK: std::cout << "J"; break; | |
case RANK_QUEEN: std::cout << "Q"; break; | |
case RANK_KING: std::cout << "K"; break; | |
case RANK_ACE: std::cout << "A"; break; | |
default: std::cout << ""; | |
} | |
switch (card.suit) | |
{ | |
case SUIT_CLUBS: std::cout << "C"; break; | |
case SUIT_DIAMONDS: std::cout << "D"; break; | |
case SUIT_HEARTS: std::cout << "H"; break; | |
case SUIT_SPADES: std::cout << "P"; break; | |
default: std::cout << ""; | |
} | |
} | |
// выводит все значения карты | |
// параметр - константная ссылка на массив deck | |
void printDeck(const std::array<Card, 52> &deck) | |
{ | |
for (const auto &card : deck) | |
{ | |
printCard(card); | |
std::cout << ' '; | |
} | |
std::cout << '\n'; | |
} | |
// принимает две карты и меняет местами их значения | |
// параметр - две ссылки типа Card | |
void swapCard(Card &a, Card &b) | |
{ | |
Card temp = a; | |
a = b; | |
b = temp; | |
} | |
// перетасовывает колоду карт | |
// параметр - константная ссылка на массив deck | |
void shuffleDeck(std::array<Card, 52> &deck) | |
{ | |
for(int i = 0; i < 52; i++) { | |
// случайное число от 1 до 52 | |
int random_number = 1 + rand() % 52; | |
// Меняем местами с нашей текущей картой | |
swapCard(deck[i], deck[random_number]); | |
} | |
} | |
// возвращает значение карты | |
// параметр - константная ссылка типа Card | |
int getCardValue(const Card &card) | |
{ | |
switch(card.rank) | |
{ | |
case RANK_2: return 2; | |
case RANK_3: return 3; | |
case RANK_4: return 4; | |
case RANK_5: return 5; | |
case RANK_6: return 6; | |
case RANK_7: return 7; | |
case RANK_8: return 8; | |
case RANK_9: return 9; | |
case RANK_10: return 10; | |
case RANK_JACK: return 10; | |
case RANK_QUEEN: return 10; | |
case RANK_KING: return 10; | |
case RANK_ACE: return 11; | |
default: return 0; | |
} | |
return 0; | |
} | |
char getPlayerChoice() | |
{ | |
std::cout << "(h) to hit, or (s) to stand: "; | |
char choice; | |
do | |
{ | |
std::cin >> choice; | |
} while(choice != 'h' && choice != 's'); | |
return choice; | |
} | |
// возвращает true если игрок побеждает | |
// false - если он проигрывает | |
bool playBlackJack(const std::array<Card, 52> &deck) | |
{ | |
// указываем на первую карту | |
const Card *cardPtr = &deck[0]; | |
// хранение очков | |
int playerTotal = 0; | |
int dealerTotal = 0; | |
// Дилер получает одну карту | |
dealerTotal += getCardValue(*cardPtr++); | |
std::cout << "The dealer is showing: " << dealerTotal << "\n"; | |
// Игрок получает две карты | |
playerTotal += getCardValue(*cardPtr++); | |
playerTotal += getCardValue(*cardPtr++); | |
// Игрок начинает | |
while(true) | |
{ | |
std::cout << "You have: " << playerTotal << "\n"; | |
// Смотрим, не больше ли 21 очка у игрока | |
if(playerTotal > 21) | |
return false; | |
char choice = getPlayerChoice(); | |
if(choice == 's') | |
break; | |
playerTotal += getCardValue(*cardPtr++); | |
} | |
// Если игрок не проиграл и у него не больше 21 очка, то тогда | |
// дилер получает карты до тех пор, пока у него не получится в сумме 17 очков | |
while(dealerTotal < 17) | |
{ | |
dealerTotal += getCardValue(*cardPtr++); | |
std::cout << "The dealer now has: " << dealerTotal << "\n"; | |
} | |
// Если у дилера больше 21 очка, то игрок победил | |
if(dealerTotal > 21) | |
return true; | |
return (playerTotal > dealerTotal); | |
} | |
int main() | |
{ | |
// устанавливаем значение системных часов в качестве стартового числа | |
srand(static_cast<unsigned int>(time(0))); | |
// представление колоды карт в виде массива | |
std::array<Card, 52> deck; | |
// инициализация колоды карт | |
int card = 0; | |
for(int suit = 0; suit < MAX_SUIT; suit++) | |
for(int rank = 0; rank < MAX_RANK; rank++) | |
{ | |
deck[card].suit = static_cast<CardSuit>(suit); | |
deck[card].rank = static_cast<CardRank>(rank); | |
++card; | |
} | |
// перетасовывает колоду карт | |
shuffleDeck(deck); | |
if(playBlackJack(deck)) | |
std::cout << "You win!\n"; | |
else | |
std::cout << "You lose!\n"; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment