#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#define CARD_MAX 52
typedef int Deck[CARD_MAX];
Deck deck;
int cardnumber = 0;
int playerwin = 0, dealerwin = 0, tie = 0;
int game();
void setupDeck(Deck deck);
void shuffleDeck(Deck deck);
void printCard(int card);
int pickCard(Deck deck, int cardnum);
void endProgram();
void playAgain();
main()
{
char yn;
srand(time(NULL));
setupDeck(deck);
shuffleDeck(deck);
again:
printf("Welcome! Do you wanna try your luck in a Blackjack Game? If so type 'y'.\n");
printf("If not type 'n' to close the program: ");
scanf_s("%c", &yn);
getchar();
if (yn == 'y')
game();
else if (yn == 'n')
{
printf("Looks like you aren't feeling lucky today! Comeback tomorrow!\n");
system("pause");
}
else
{
printf("Unknown character! Try again!\n");
goto again;
}
}
int game()
{
int card, cardvalue = 0, cardtype = 0, tcvp = 0, tcvd = 0;
int aceflagp = 0, faceflagp = 0, aceflagd = 0, faceflagd = 0, bjp = 0, bjd = 0;
int loopcounter;
char hitorpass;
system("cls");
printf("Your cards:\n");
for (loopcounter = 0; loopcounter < 2; loopcounter++)
{
card = pickCard(deck, cardnumber);
cardnumber++;
cardvalue = card % 13;
cardtype = card / 13;
printCard(cardvalue, cardtype);
if (cardvalue == 1)
{
aceflagp++;
cardvalue = 11;
}
else if (cardvalue == 0 || cardvalue == 11 || cardvalue == 12)
{
faceflagp = 1;
cardvalue = 10;
}
else
cardvalue = cardvalue;
tcvp += cardvalue;
}
if (aceflagp == 1 && faceflagp == 1)
bjp = 1;
printf("Dealers cards:\n");
card = pickCard(deck, cardnumber);
cardnumber++;
cardvalue = card % 13;
cardtype = card / 13;
printCard(cardvalue, cardtype);
if (cardvalue == 1)
{
aceflagd++;
cardvalue = 11;
}
else if (cardvalue == 0 || cardvalue == 11 || cardvalue == 12)
{
faceflagd = 1;
cardvalue = 10;
}
else
cardvalue = cardvalue;
tcvd += cardvalue;
card = pickCard(deck, cardnumber);
cardnumber++;
cardvalue = card % 13;
cardtype = card / 13;
if (cardvalue == 1)
{
aceflagd++;
cardvalue = 11;
}
else if (cardvalue == 0 || cardvalue == 11 || cardvalue == 12)
{
faceflagd = 1;
cardvalue = 10;
}
else
cardvalue = cardvalue;
tcvd += cardvalue;
if (aceflagd == 1 && faceflagd == 1)
bjd = 1;
if (bjp == 1 && bjd == 1)
{
printf("Both sides has Blackjack! Tie!\n");
tie++;
playAgain();
}
else if (bjp == 1)
{
printf("Player Blackjack!\n");
playerwin++;
playAgain();
}
else if (bjd == 1)
{
printf("Dealer Blackjack!\n");
dealerwin++;
playAgain();
}
printf("Your card total is %d.\n", tcvp);
again:
printf("If you want to hit type 'h'. If you want to pass type 'p'");
scanf_s("%c", &hitorpass);
getchar();
if (hitorpass == 'h')
{
card = pickCard(deck, cardnumber);
cardnumber++;
cardvalue = card % 13;
cardtype = card / 13;
printCard(cardvalue, cardtype);
if (cardvalue == 1)
{
aceflagp++;
cardvalue = 11;
}
else if (cardvalue == 0 || cardvalue == 11 || cardvalue == 12)
{
faceflagp = 1;
cardvalue = 10;
}
else
cardvalue = cardvalue;
tcvp += cardvalue;
if (tcvp > 21)
{
if (aceflagp > 0)
{
tcvp -= 10;
aceflagp--;
printf("Your card total is %d.\n", tcvp);
goto again;
}
else
{
printf("Your hand busted. You lost!\n");
dealerwin++;
playAgain();
}
}
else if (tcvp == 21)
{
printf("You have 21 in your hand can't hit more!\n");
goto dealersturn;
}
else if (tcvp < 21)
{
printf("Your card total is %d.\n", tcvp);
goto again;
}
}
else if (hitorpass == 'p')
{
dealersturn:
printf("Dealers turn:\n");
if (tcvd < 17)
{
card = pickCard(deck, cardnumber);
cardnumber++;
cardvalue = card % 13;
cardtype = card / 13;
printCard(cardvalue, cardtype);
if (cardvalue == 1)
{
aceflagd++;
cardvalue = 11;
}
else if (cardvalue == 0 || cardvalue == 11 || cardvalue == 12)
{
faceflagd = 1;
cardvalue = 10;
}
else
cardvalue = cardvalue;
tcvd += cardvalue;
if (tcvd > 21)
{
if (aceflagd > 0)
{
tcvd -= 10;
aceflagd--;
goto dealersturn;
}
else
{
printf("Dealers has a total of %d. Dealers hand busted!\n", tcvd);
playerwin++;
playAgain();
}
}
else if (tcvd < 17)
goto dealersturn;
else
{
if (tcvp > tcvd)
{
printf("Player has %d, dealer has %d. Player won!", tcvp, tcvd);
playerwin++;
playAgain();
}
else if (tcvp == tcvd)
{
printf("Both player and the dealer has %d. Tie!", tcvd);
tie++;
playAgain();
}
else
{
printf("Player has %d, dealer has %d. Dealer won!", tcvp, tcvd);
dealerwin++;
playAgain();
}
}
}
}
else
{
printf("Unknown character. Try again!");
goto again;
}
system("pause");
}
void endProgram()
{
printf("Thanks for playing my blackjack game! The results are:\n");
printf("Player won %d times!\n", playerwin);
printf("Dealer won %d times!\n", dealerwin);
printf("There have been a tie %d times!\n", tie);
system("pause");
}
void playAgain()
{
char chardummy;
again:
printf("Would you like to play again? Type 'y' for Yes and 'n' for No.\n");
scanf_s("%c", &chardummy);
getchar();
if (chardummy == 'y')
{
if (cardnumber >= 48)
{
printf("There is not enough card left in the deck!");
endProgram();
}
else
game();
}
else if (chardummy == 'n')
endProgram();
else
{
printf("Unknown character. Try again!");
goto again;
}
}
void setupDeck(Deck deck)
{
int i;
for (i = 0; i<CARD_MAX; i++)
{
deck[i] = i;
}
}
void shuffleDeck(Deck deck)
{
for (int i = 52 - 1; i >= 0; --i) {
int r = rand() % (i + 1);
int t = deck[i];
deck[i] = deck[r];
deck[r] = t;
}
}
void printCard(int cardvalue, int cardtype)
{
char cardtype2;
if (cardtype == 0)
cardtype2 = 'C';
else if (cardtype == 1)
cardtype2 = 'D';
else if (cardtype == 2)
cardtype2 = 'H';
else if (cardtype == 3)
cardtype2 = 'S';
switch (cardvalue)
{
case 0:
{
printf("*******\n");
printf("* *\n");
printf("* %c *\n", cardtype2);
printf("* K *\n", cardvalue);
printf("* *\n");
printf("*******\n");
break;
}
case 1:
{
printf("*******\n");
printf("* *\n");
printf("* %c *\n", cardtype2);
printf("* A *\n");
printf("* *\n");
printf("*******\n");
break;
}
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
{
printf("*******\n");
printf("* *\n");
printf("* %c *\n", cardtype2);
printf("* %2d *\n", cardvalue);
printf("* *\n");
printf("*******\n");
break;
}
case 11:
{
printf("*******\n");
printf("* *\n");
printf("* %c *\n", cardtype2);
printf("* J *\n", cardvalue);
printf("* *\n");
printf("*******\n");
break;
}
case 12:
{
printf("*******\n");
printf("* *\n");
printf("* %c *\n", cardtype2);
printf("* Q *\n", cardvalue);
printf("* *\n");
printf("*******\n");
break;
}
}
}
int pickCard(Deck deck, int cardnum)
{
if (cardnumber == 52)
{
printf("There is not enough cards left to complete the game!");
endProgram();
}
else
return deck[cardnum];
}
这是我的简单二十一点游戏的代码。由于某种原因经过几轮经销商转向不起作用。如果你能找到我不能的原因,我将不胜感激。并随时提供有关改进我的代码的提示。
答案 0 :(得分:2)
您在代码中遇到以下问题,我可以从编译器警告/错误中看到。
printCard
的声明与其用法及其实施不符。将声明更改为:
void printCard(int cardvalue, int cardtype);
明确返回main
的返回类型。将其更改为:
int main () ...
更改打印K
,J
和Q
的行。在这些行中你不需要printf
的额外参数。
printf("* K *\n");
printf("* J *\n");
printf("* Q *\n");
在上面,第一个是最重要的修复。通过这些更改,我能够毫无问题地运行您的程序。我的测试平台:Linux,gcc 4.8.4。
提高警告级别,以便您可以检测此类警告/错误,并在将来的编程工作中修复它们。
答案 1 :(得分:0)
因为你问......: - )
除了R Sahu所说的......
最大的问题(挑战?)我注意到,我不知道你的endProgram()函数实际上是如何结束的&#39;任何东西。它调用系统(&#34;暂停&#34;)然后恢复:
void endProgram()
{
printf("Thanks for playing my blackjack game! The results are:\n");
printf("Player won %d times!\n", playerwin);
printf("Dealer won %d times!\n", dealerwin);
printf("There have been a tie %d times!\n", tie);
system("pause);
}
这意味着pickCard()函数中的以下代码具有不可预测的行为:
int pickCard(Deck deck, int cardnum)
{
if (cardnumber == 52)
{
printf("There is not enough cards left to complete the game!");
endProgram(); // once we get here what do we return to the caller?
}
else
return deck[cardnum];
}
&#34;不可预测&#34;我具体指的是:pickCard()将返回cardnumber = 52?
我怀疑 pickCard()将调用endProgram(),这是一个无效函数,除了返回之外什么都不做,然后pickCard将脱离if-else语句并且尝试向调用者返回一个整数,它可能会从调用堆栈中选择一些垃圾来发回,这可能(或可能不是)是有效的卡值。
事实证明,你在大约5个不同的地方打电话给pickCard(),有时是玩家,有时是经销商。
如果pickCard()返回 way 超出范围的值,该逻辑会发生什么?
因为你只在main()的开头调用一次shuffleDeck(),所以你最终会“耗尽”#c;&#39;甲板并获取从pickCard()返回的未定义卡值。
哪种适合你的症状&#34;它在一段时间后在经销商处破裂 ...&#34;。
所以...对于一般的清理......
我会把你在game()方法中拥有的大部分变量拿出来并使它们成为全局变量。
我会添加大量的打印语句进行调试,这样您就可以验证代码是否按照您的想法进行操作。
你对system()的调用对我来说是一个挑战:
system("cls");
system("pause");
由于您在Windows上开发,我理解您使用系统的原因(让我想起过去编写dos批处理文件的历史)。
但是......我会鼓励你放弃系统()调用并编写自己的输入&#34; helper&#34;处理scanf_s或任何你想要使用的函数。 也许这样的东西可以提示并返回用户输入的任何字符。
char prompt_and_read_char(char * msg);
我鼓励你在没有goto语句的情况下重写。
你确实在游戏()函数中尝试循环,让玩家画牌; for循环,所以奖励积分。
您的整体风格和用户互动目标是合理的,并建议您最终制作有趣的游戏。
游戏()中的代码有200多行代码,这使得它比阅读时更难。
我建议在game()函数中执行类似的操作:目标是将所有卡片绘制功能仅用于播放器或经销商。
// Global Variable definitions...
int gameInProcess = 0; // global, set to false.
int tcvp = -1; // obvious bad
// note for global-var police: yeah, I know globals is not "good style".
// But cut our beginning programmer some slack here... this seems like the easiest way for
// them to get their game running. (Think of it as a first step toward cleaning up the
// game() method if that helps any).
// prototypes here.
// main() here.
...etc...
int game() {
gameInProcess = 1; // set to true.
tcvp = 0;
tcvd = 0;
while( gameInProcess ) {
// add plenty of print statements so you see what is going on; you can clean
// them up later by searching on DEBUG.
printf("DEBUG... game(): tcvp=%d tcvd=%d cardnumber=%d\n", tcvp, tcvd, cardnumber );
game_playerDraws( ); // updates tcvp, may set gameInProcess to 0 if player win or busts.
game_dealerDraws( ); // udpates tcvd, may set gameInProcess to 0 if dealer hits blackjack or goes bust.
...other functions for variations...
}
printf("game over, score: player=%d dealer=%d\n", tcvp, tcvd );
// add logic to decide winner.
// return to caller, maybe let them decide if we'll have another game using the same deck.
}
game_playerDraws( ) {
if( !gameInProcess ) {
printf("game_playerDraws(): gameInProcess=%d, nothing to do.\n", gameInProcess );
return;
}
// draw some cards, update globalcs if player wins or breaks.
}
game_dealerDraws( ) {
... do dealer-approriate things...
}
这样做的好处是,如果你放弃了牌组,你可以设置gameInProcess = 0;并且返回,一切都优雅地停止。
您可以添加一个选项以随机播放新牌组并开始另一场比赛。
但最大的好处是它会给你一个干净的方式来开始和结束每个游戏,这是你在当前版本的代码中缺少的东西。
祝你好运。你清楚地喜欢编程并且正在玩写作游戏。 坚持下去,我想你会学到很多东西。