- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想在下学期的类(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/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!