C 关于我的简单21点计划的建议/改进
我想在下学期的课程中取得一个领先,所以我制作了这个21点的基本版本,以开始理解C的基础知识,我希望你能有任何想法帮助我更好地理解C及其正常的编码实践 C语言中的很多东西对我来说都是新的,因为我来自JAVA的背景,所以如果我在函数声明、指针的使用上犯了错误,或者如果我正在考虑如何错误地处理问题,并且应该以完全不同的方式处理问题,请让我知道C 关于我的简单21点计划的建议/改进,c,blackjack,C,Blackjack,我想在下学期的课程中取得一个领先,所以我制作了这个21点的基本版本,以开始理解C的基础知识,我希望你能有任何想法帮助我更好地理解C及其正常的编码实践 C语言中的很多东西对我来说都是新的,因为我来自JAVA的背景,所以如果我在函数声明、指针的使用上犯了错误,或者如果我正在考虑如何错误地处理问题,并且应该以完全不同的方式处理问题,请让我知道 #include <stdio.h> #include <stdlib.h> #include <time.h> #incl
#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;
}
#包括
#包括
#包括
#包括
const int handSize=2;
int随机卡(int*isAce);
int-sumCards(int-cards[],int*hasAce[2]);
int main(){
srand(时间(空));
int playGame=0;
int dealerIsAce[手推];
int*dealerAcePointers[handSize];
int playerIsAce[手动大小];
int*PlayerAcceptointers[手持];
对于(int i=0;i17){
dealerCards[0]=dealerSum;
dealerCards[1]=randCard(DealerAcceptointers[1]);
}
playerSum=sumCards(玩家卡、玩家积分卡);
printf(“您:\n%d+%d=%d”,playerCards[0],playerCards[1],playerSum);
如果(playerSum>21){
printf(“破产”);
游戏=1;
}否则{
printf(“\n您想“打”还是“站”?\n”);
}
如果(游戏==0){
字符流[10];
if(strcmp(获取(流),“命中”)==0){
playerCards[0]=playerSum;
玩家卡[1]=随机卡(玩家积分[1]);
}否则{
游戏=1;
}
}
}while(playGame==0);
如果(playerSum>21){
如果(经销商数量>21){
printf(“\nTie!”);
}否则{
printf(“\nDeler赢!”);
}
}否则{
如果(playerSum>dealerSum){
printf(“\n玩家获胜!”);
}else if(playerSum==dealerSum){
printf(“\nTie!”);
}else if(playerSum11){
卡片=10;
}否则,如果(卡==11){
*isAce=1;
}
回程卡;
}
int-sumCards(int-cards[],int*hasAce[2]){
整数和=卡片[0]+卡片[1];
如果(总和>21&&*hasAce[0]==1){
总和-=10;
*hasAce[0]=*hasAce[1];
如果(*hasAce[1]==1){
*hasAce=0;
}
}
回报金额;
}
正如一位评论者所提到的,这可以在其他地方问得更好,不过我还是要提供一些意见。这些都是观点,每个人都可能不同意我说的话
顺便说一句,我完全无视21点的规则,并假设你的逻辑是正确的
首先,代码中没有任何注释。你提到这是为了一个班级,因此评论更重要,因为一些穷人必须破译大量的评论来了解他们在做什么。(不管怎样,注释代码是很重要的。顺便说一句,我总是使用“我会在几个月内解决这个问题吗”的方法)
在main()。我个人会把它分解成不同的功能。然后你也可以考虑把它放在一个单独的文件中,函数声明的头文件。
handSize
被用作常量,您可以将其改为预处理器宏:\define HAND\u SIZE 2
do while
循环可以替换为while(true)
循环,然后在完成时使用'break'关键字进行转义(您当前正在设置playGame=1
。这还有一个优点,就是没有if(playGame==0)
conditional。另外,在C中,布尔变量为1表示true,0表示false,因此让int playGame=1;
然后do{}while(playGame)更正常
和playGame=0;
当你完成循环时。这种情况是一种特殊情况,你实际上想突破,而不是跑到循环的末尾
出于安全原因()
从更全面的计划角度来看,这些观点甚至更加主观,主要是我解决问题的方式:
我个人会将dealerCards和playerCards设置为足够大,以容纳尽可能多的牌(我认为21点中是5张),并将它们初始化为0。目前,您正在将当前牌的总和分配给dealerCards
数组的第一个元素,这意味着这些值不是实际的牌
我不会使用单独的数组来跟踪卡片是否是ACE,而是为{EMPTY_SLOT,ACE,TWO,…,JACK,QUEEN,KING}创建一个枚举然后将其存储在我的卡片数组中。randCard
可以只返回枚举的一个成员,不带任何参数,sumCards
只在数组中迭代并求和。这也意味着您可以显示用户的实际手数,而不仅仅是总数
为了便于参考,我修改了你的代码,使之符合我的要求。逻辑可能不完美(或与21点完全相同的版本),但
#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");
}