二十一点游戏的一般算法是什么?我正在用 C++ 编写一个,结果有太多的 if 语句破坏了整个事情。
该项目是一个win32 GUI应用程序,我发布了消息循环以及检查游戏状态的程序部分发布完整的代码将使它变得巨大,所以这里是所有文件的链接: 完整源代码
消息循环
LRESULT CALLBACK WndProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ){
switch(Msg)
{
case WM_PAINT:
{
PAINTSTRUCT PS;
HDC hDC = BeginPaint(hWnd, &PS);
You.Draw(hDC);
Dealer.Draw(hDC);
EndPaint(hWnd, &PS);
if(Bet.Enabled){
Bet.GetFocus();
Bet.Select(0,Bet.Length());
}
}
return 0;
case WM_CTLCOLORSTATIC:
{
SetBkMode((HDC)wParam, TRANSPARENT);
}
return (INT_PTR)(HBRUSH)GetStockObject(NULL_BRUSH);
case WM_CREATE:
{
//Create edit control
Bet.Create(hWnd, 10, 550, 100, 25, "0");
//Create labels
char Buffer[30];
sprintf(Buffer, "%d", You.HandValue());
BetLabel.Create(hWnd, 10, 500, 100, 40, "Enter Bet Amount");
GameControls.Create(hWnd, 10, 375, 100, 40, "Game Controls");
PlayerLabels.Create(hWnd, 10, 10, 100, 20, "You:");
PlayerLabels.Create(hWnd, 10, 150, 100, 20, "Dealer:");
HandValueLabel.Create(hWnd, (int)You.x[You.cards] + 85, (int)You.y[You.cards] + 25, 100, 20, Buffer);
YourMoney.Create(hWnd, 125, 500, 100, 40, "Your money: ");
sprintf(Buffer, "%d", You.money);
MoneyValue.Create(hWnd, 125, 525, 100, 40, Buffer);
//Create buttons
Ok.Create(hWnd, 10, 600, 100, 50, "Ok");
Hit.Create(hWnd, 10, 425, 100, 50, "Hit");
Stand.Create(hWnd, 120, 425, 100, 50, "Stand");
//Select Text
Bet.Select(0,3);
}
return 0;
case WM_CLOSE:
exit(0);
break;
case WM_COMMAND:
{
switch(HIWORD(wParam))
{
case BN_CLICKED:
{
switch(LOWORD(wParam))
{
case ID_OK:
{
//Place bet
int bet = 0;
bet = StringToNumber(Bet.Text());
You.money -= bet;
char Buffer[30];
sprintf(Buffer, "%d", You.money);
MoneyValue.SetText(Buffer);
//Update the window
InvalidateRect(hWnd, 0, TRUE);
You.Bet = YES;
Ok.Disable();
Bet.Disable();
You.DealCard();
You.DealCard();
Dealer.DealCard();
Dealer.DealCard();
You.win = false;
You.bust = false;
You.playing = YES;
Dealer.win = NO;
Dealer.bust = NO;
Dealer.playing = YES;
}
break;
case ID_HIT:
{
if(You.HandValue() < 21 && You.playing && !You.bust){
//Deal a card to the player, if he hasn't won or lost
You.DealCard();
}
if((Dealer.HandValue() <= 17 || Dealer.HandValue() < You.HandValue()) && Dealer.playing)
{
Dealer.DealCard();
}
//Update Hand Value
char Buffer[30];
sprintf(Buffer, "%d", You.HandValue());
HandValueLabel.SetText(Buffer);
InvalidateRect(hWnd,0,TRUE);
MoveWindow(HandValueLabel.Handle, (int)You.x[You.cards] + 80, (int)You.y[You.cards] + 25, 100, 20, TRUE);
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT);
}
break;
case ID_STAND:
if(Hit.Enabled){
//Don't deal more cards
Hit.Disable();
You.playing = false;
}
if((Dealer.HandValue() <= 17 || Dealer.HandValue() < You.HandValue()) && Dealer.playing){
//Deal a card to the dealer
Dealer.DealCard();
}
}
状态检查器
void ProcessStatus(HWND hWnd){
if(Dealer.HandValue() > 17){
if(Dealer.HandValue() > You.HandValue() && Dealer.playing){
Dealer.playing = false;
}
else if(!You.playing && Dealer.HandValue() <= You.HandValue() && Dealer.playing){
Dealer.DealCard();
}
}
else if(Dealer.HandValue() <= 17 && Dealer.HandValue() <= You.HandValue() && !You.playing && Dealer.playing){
Dealer.DealCard();
}
if(EvaluateStatus() != 0){
status = OVER;
}
if(EvaluateStatus() == -1){
switch(MessageBoxA(hWnd, "You Lost! \n Keep Playing ?", "You Lost!", MB_YESNO | MB_ICONQUESTION))
{
case IDYES:
Reset();
break;
case IDNO:
exit(0);
break;
}
}
else if(EvaluateStatus() == 1){
switch(MessageBoxA(hWnd, "You Won! \n Keep Playing ?", "You Won!", MB_YESNO | MB_ICONQUESTION))
{
case IDYES:
Reset();
break;
case IDNO:
exit(0);
break;
}
}
}
int EvaluateStatus()
{
if(You.HandValue() > 21 && You.playing)
{
You.bust = true;
Dealer.win = true;
You.playing = NO;
return -1;
}
if(You.HandValue() == 21)
{
You.win = true;
return 1;
}
if(Dealer.HandValue() > 21)
{
Dealer.bust = true;
You.win = true;
return 1;
}
if(Dealer.HandValue() == 21)
{
Dealer.win = true;
return -1;
}
if(!You.playing && Dealer.HandValue() > You.HandValue() &&!Dealer.bust)
{
Dealer.win = true;
return -1;
}
if(You.HandValue() > Dealer.HandValue() && (!You.playing && (!Dealer.playing || Dealer.bust)))
{
You.win = true;
return 1;
}
if(You.HandValue() == Dealer.HandValue() && (!You.playing || !Dealer.playing))
{
You.win = true;
return 1;
}