gpt4 book ai didi

c - 对我的简单二十一点程序的建议/改进

转载 作者:行者123 更新时间:2023-11-30 20:28:56 27 4
gpt4 key购买 nike

我想在下学期的类(class)中取得领先,所以我制作了这个基本版本的 Blackjack 来开始理解 C 的基础知识,我希望您有任何想法可以帮助我更好地理解 C 和其正常的编码实践。

C 中的很多东西对我来说都是新的,因为我有 JAVA 背景,所以如果我在函数声明、指针的使用中犯了错误,或者我在考虑如何解决问题不正确,应该以完全不同的方式做事,请告诉我。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

const int handSize = 2;

int randCard(int *isAce);

int sumCards(int cards[], int *hasAce[2]);

int main() {
srand(time(NULL));

int playGame = 0;

int dealerIsAce[handSize];
int *dealerAcePointers[handSize];
int playerIsAce[handSize];
int *playerAcePointers[handSize];

for (int i = 0; i < handSize; i++) {
dealerIsAce[i] = 0;
playerIsAce[i] = 0;

dealerAcePointers[i] = &dealerIsAce[0];
playerAcePointers[i] = &playerIsAce[0];
}

int dealerCards[] = {randCard(dealerAcePointers[0]), randCard(dealerAcePointers[1])};
int playerCards[] = {randCard(playerAcePointers[0]), randCard(playerAcePointers[1])};

int dealerSum;
int playerSum;
do {
printf("The dealer:\n? + %d\n\n", dealerCards[1]);

dealerSum = sumCards(dealerCards, dealerAcePointers);
if (dealerSum > 17) {
dealerCards[0] = dealerSum;
dealerCards[1] = randCard(dealerAcePointers[1]);
}

playerSum = sumCards(playerCards, playerAcePointers);
printf("You:\n%d + %d = %d", playerCards[0], playerCards[1], playerSum);
if (playerSum > 21) {
printf(" BUSTED");
playGame = 1;
} else {
printf("\nWould you like to \"hit\" or \"stand\"?\n");
}

if (playGame == 0) {
char stream[10];
if (strcmp(gets(stream), "hit") == 0) {
playerCards[0] = playerSum;
playerCards[1] = randCard(playerAcePointers[1]);
} else {
playGame = 1;
}
}
} while (playGame == 0);

if (playerSum > 21) {
if (dealerSum > 21) {
printf("\nTie!");
} else {
printf("\nDealer Wins!");
}
} else {
if (playerSum > dealerSum) {
printf("\nPlayer Wins!");
} else if (playerSum == dealerSum) {
printf("\nTie!");
} else if (playerSum < dealerSum) {
printf("\nDealer Wins!");
}
}
return 0;
}

int randCard(int *isAce) {
int card = rand() % 13 + 2;
if (card > 11) {
card = 10;
} else if (card == 11) {
*isAce = 1;
}
return card;
}

int sumCards(int cards[], int *hasAce[2]) {
int sum = cards[0] + cards[1];
if (sum > 21 && *hasAce[0] == 1) {
sum -= 10;
*hasAce[0] = *hasAce[1];
if (*hasAce[1] == 1) {
*hasAce = 0;
}
}
return sum;
}

最佳答案

正如评论者提到的,这个问题最好在其他地方问,但无论如何我都会提供一些意见。这些都是个人观点,每个人可能都会不同意我所说的。

顺便说一句,我完全忽略了二十一点的规则并假设你所有的逻辑都是正确的。

首先,代码中没有任何注释。你提到这是为了一个类,因此评论甚至更重要,因为一些穷人必须破译大量这些内容才能弄清楚他们在做什么。 (无论如何,注释代码很重要,我总是使用“我会在一个月内弄清楚它的作用吗”方法)

main() 中有这么多东西是不寻常的。我个人会将其分解为不同的函数。然后,您还可以考虑将其放入单独的文件中,并带有函数声明的头文件。

handSize 被用作常量,您可以将其设为预处理器宏:#define HAND_SIZE 2

do-while 循环可以替换为 while(true) 循环,然后使用“break”关键字在完成时转义(在此处当前正在设置 playGame = 1。这还有一个优点是没有 if(playGame == 0) 条件。此外,在 C 中, bool 变量为 1 true 为 false,0 为 false,因此更正常的是先使用 int playGame = 1;,然后使用 do { } while(playGame)playGame = 0; 当你完成循环时。这种情况很特殊,因为你实际上想要跳出,而不是运行到循环末尾。

出于安全原因,

gets() 在 C11 中被删除 ( Implicit declaration of 'gets' )

关于更整体的方案要点。这些更加主观,而且大多只是我解决问题的方式:

我个人会让dealerCards和playerCards足够大,以容纳最大可能数量的牌(我认为二十一点中是5张?)并将它们初始化为0。目前,您正在将当前牌的总和分配给第一个元素dealerCards 数组的值,这意味着这些值不是实际的卡牌。

我不会使用单独的数组来跟踪牌是否是 A,而是为 {EMPTY_SLOT, ACE, TWO, ..., JACK, QUEEN, KING} 创建一个枚举,然后将其存储在我的 Cards 数组中。然后,randCard 可以只返回枚举的成员,并且不带任何参数,而 sumCards 只是迭代数组并对其求和。这也意味着您可以向他们显示用户的实际手牌,而不仅仅是总数。

出于引用目的,我已按照我的方式修改了您的代码。逻辑可能并不完美(或者与二十一点的版本完全相同),但这就是我要为“C 程序二十一点”作业提交的内容。注意:这也可以通过更多注释来完成,特别是顶部的一个 block ,解释总体结构是什么。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define HAND_SIZE 5

typedef enum
{
// Technically I didn't need to set the values, as they are the defaults but
// it's good to be explicit when you're using the order for something.
EMPTY = 0,
ACE = 1,
TWO = 2,
THREE,
FOUR,
FIVE,
SIX,
SEVEN,
EIGHT,
NINE,
TEN,
JACK,
QUEEN,
KING
} card_t; // Types you typedef generally end _t as a convention.


// These should be in a separate header, but I'm keeping this in 1 file for StackOverflow
card_t randCard();
int sumCards(card_t cards[]);
void play();

int main()
{
srand(time(NULL));

play();

return 0;
}

card_t randCard()
{
int card = rand() % 13 + 1;
return (card_t)card;
}

int sumCards(card_t cards[])
{
int total = 0;
int num_aces = 0;

for (int i = 0; i < HAND_SIZE; i++) {
switch(cards[i]) {
case ACE:
num_aces++;
total += 11;
break;
case JACK:
case QUEEN:
case KING:
total += 10;
break;
default:
total += (int)cards[i]; // Relying here on the fact that the cards are in the correct order.
break;
}
}

while (num_aces > 0 && total > 10) {
total -= 10;
num_aces--;
}

return total;
}

void play()
{
card_t playerCards[HAND_SIZE];
card_t dealerCards[HAND_SIZE];
card_t dealerKnown[HAND_SIZE]; // Equivalent to dealer cards, but with first 2 elements blank

for (int i = 0; i < HAND_SIZE; i++) {
playerCards[i] = EMPTY;
dealerCards[i] = EMPTY;
dealerKnown[i] = EMPTY;
}

playerCards[0] = randCard();
playerCards[1] = randCard();
dealerCards[0] = randCard();
dealerCards[1] = randCard();

int num_cards = 2;

while(num_cards <= HAND_SIZE) {
printf("The dealer: ? + %d\n\n", sumCards(dealerKnown));

if (sumCards(dealerCards) > 17) {
dealerCards[num_cards] = randCard();
}

int playerSum = sumCards(playerCards);
printf("Your total: %d\n", playerSum);
if (playerSum > 21) {
printf("BUSTED\n");
break;
} else {
printf("Would you like to \"hit\" or \"stand\"?\n");
}

char stream[10];
if (strcmp(fgets(stream, sizeof(stream), stdin), "hit\n") != 0) {
break;
}

playerCards[num_cards] = randCard();

num_cards++;
}

printf("\n"); // Printing the new line separately rather than at the beginning of all the strings below

int playerSum = sumCards(playerCards);
int dealerSum = sumCards(dealerCards);

if (playerSum > 21) {
if (dealerSum > 21) {
printf("Tie!");
} else {
printf("Dealer Wins!");
}
} else {
if (playerSum > dealerSum) {
printf("Player Wins!");
} else if (playerSum == dealerSum) {
printf("Tie!");
} else if (playerSum < dealerSum) {
printf("Dealer Wins!");
}
}

printf("\n");
}

关于c - 对我的简单二十一点程序的建议/改进,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59550694/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com