Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309/* * PROJECT: Spider Solitaire * LICENSE: See COPYING in top level directory * FILE: base/applications/games/spider/spigame.cpp * PURPOSE: Spider Solitaire game functions * PROGRAMMER: Gregor Schneider */
#include "spider.h"
#define NUM_DECK_CARDS 5#define NUM_SMALLER_STACKS 4#define NUM_CARD_COLORS 4#define NUM_ONECOLOR_CARDS 13#define NUM_STD_CARDS 52#define NUM_SPIDER_CARDS 104
CardStack deck;CardRegion *from;CardRegion *pDeck;CardRegion *pStack[NUM_STACKS];bool fGameStarted = false;int yRowStackCardOffset;int cardsFinished;extern TCHAR MsgDeal[];extern TCHAR MsgWin[];
CardStack CreatePlayDeck(){ CardStack newStack; int i, colors = 1, num = 0;
switch (dwDifficulty) { case IDC_DIF_ONECOLOR: colors = 1; break; case IDC_DIF_TWOCOLORS: colors = 2; break; case IDC_DIF_FOURCOLORS: colors = 4; break; } for (i = 0; i < NUM_SPIDER_CARDS; i++) { num += NUM_CARD_COLORS / colors; Card newCard(num % NUM_STD_CARDS); newStack.Push(newCard); } return newStack;}
void NewGame(void){ int i, j; /* First four stack with five, all other with 4 */ int covCards = 5; CardStack fakeDeck, temp;
SpiderWnd.EmptyStacks();
/* Create a new card-deck, fake deck */ deck = CreatePlayDeck(); deck.Shuffle(); fakeDeck.NewDeck(); fakeDeck.Shuffle();
/* Reset progress value */ cardsFinished = 0;
/* Deal to each stack */ for (i = 0; i < NUM_STACKS; i++) { temp.Clear(); if (i == NUM_SMALLER_STACKS) { covCards--; } for (j = 0; j <= covCards; j++) { temp.Push(deck.Pop(1)); } pStack[i]->SetFaceDirection(CS_FACE_DOWNUP, covCards); pStack[i]->SetCardStack(temp); } /* Deal five fake cards to the deck */ pDeck->SetCardStack(fakeDeck.Pop(5));
SpiderWnd.Redraw(); fGameStarted = false;}
bool stackLookingGood(const CardStack &mystack, int numChecks){ int i; for (i = 0; i < numChecks; i++) { if (mystack[i].LoVal() != mystack[i + 1].LoVal() - 1) { return false; } if (mystack[i].Suit() != mystack[i + 1].Suit()) { return false; } } return true;}
/* Card to be turned from a stack */void TurnStackCard(CardRegion &stackobj){ int numfacedown;
stackobj.GetFaceDirection(&numfacedown); if (stackobj.NumCards() <= numfacedown) { if (numfacedown > 0) numfacedown--; stackobj.SetFaceDirection(CS_FACE_DOWNUP, numfacedown); stackobj.Redraw(); }}
/* Click on the deck */void CARDLIBPROC DeckClickProc(CardRegion &stackobj, int NumDragCards){ CardStack temp, fakeDeck = pDeck->GetCardStack(); fGameStarted = true;
if (fakeDeck.NumCards() != 0 && deck.NumCards() != 0) { int i, facedown, faceup; /* Add one card to every stack */ for (i = 0; i < NUM_STACKS; i++) { temp = pStack[i]->GetCardStack(); temp.Push(deck.Pop());
/* Check if we accidentally finished a row */ pStack[i]->GetFaceDirection(&facedown); faceup = temp.NumCards() - facedown; if (faceup >= NUM_ONECOLOR_CARDS) { /* Check stack finished, remove cards if so */ if (stackLookingGood(temp, NUM_ONECOLOR_CARDS - 1)) { int j; for (j = 0; j < NUM_ONECOLOR_CARDS; j++) { temp.RemoveCard(0); } cardsFinished += NUM_ONECOLOR_CARDS; pStack[i]->SetCardStack(temp); /* Turn now topmost card */ TurnStackCard(*pStack[i]); } } pStack[i]->SetCardStack(temp); } /* Remove one card from the fake ones */ pDeck->SetCardStack(fakeDeck.Pop(fakeDeck.NumCards() - 1)); } pDeck->Update(); SpiderWnd.Redraw();}
/* Cards dragged from a stack */bool CARDLIBPROC StackDragProc(CardRegion &stackobj, int numDragCards){ int numfacedown, numcards;
stackobj.GetFaceDirection(&numfacedown); numcards = stackobj.NumCards();
/* Only cards facing up */ if (numDragCards <= numcards - numfacedown) { const CardStack &mystack = stackobj.GetCardStack(); /* Don't allow to drag unsuited cards */ if (!stackLookingGood(mystack, numDragCards - 1)) { return false; } /* Remember where the cards come from */ from = &stackobj; return true; } else { return false; }}
/* Game finished successfully */void GameFinished(){ SpiderWnd.EmptyStacks();
MessageBox(SpiderWnd, MsgWin, szAppName, MB_OK | MB_ICONINFORMATION); if( IDYES == MessageBox(SpiderWnd, MsgDeal, szAppName, MB_YESNO | MB_ICONQUESTION) ) { NewGame(); } else { fGameStarted = false; }}
/* Card added, check for win situation */void CARDLIBPROC StackAddProc(CardRegion &stackobj, const CardStack &added){ if (cardsFinished == NUM_SPIDER_CARDS) { GameFinished(); }}
/* Cards dropped to a stack */bool CARDLIBPROC StackDropProc(CardRegion &stackobj, CardStack &dragcards){ Card dragcard = dragcards[dragcards.NumCards() - 1]; int faceup, facedown;
/* Only drop our cards on other stacks */ if (stackobj.Id() == from->Id()) { return false; }
/* If stack is empty, everything can be dropped */ if (stackobj.NumCards() != 0) { const CardStack &mystack = stackobj.GetCardStack();
/* Can only drop if card is 1 less */ if (mystack[0].LoVal() != dragcard.LoVal() + 1) { return false; }
/* Check if stack complete */ stackobj.GetFaceDirection(&facedown); faceup = stackobj.NumCards() - facedown;
if (faceup + dragcards.NumCards() >= NUM_ONECOLOR_CARDS) { int i, max = NUM_ONECOLOR_CARDS - dragcards.NumCards() - 1;
/* Dragged cards have been checked to be in order, check stack cards */ if (mystack[0].Suit() == dragcard.Suit() && stackLookingGood(mystack, max)) { CardStack s = stackobj.GetCardStack(); CardStack f;
/* Remove from card stack */ for (i = 0; i < max + 1; i++) { s.RemoveCard(0); } /* Remove dragged cards */ dragcards = f; stackobj.SetCardStack(s); cardsFinished += NUM_ONECOLOR_CARDS; /* Flip top card of the dest stack */ TurnStackCard(stackobj); } } } /* Flip the top card of the source stack */ TurnStackCard(*from); fGameStarted = true; return true;}
/* Create card regions */void CreateSpider(){ int i, pos;
/* Compute the value for yRowStackCardOffset based on the height of the card, so the card number and suite isn't hidden on larger cards except Ace */ yRowStackCardOffset = (int)(__cardheight / 6.4);
pDeck = SpiderWnd.CreateRegion(0, true, 0, 0, -15, 0); pDeck->SetFaceDirection(CS_FACE_DOWN, 0); pDeck->SetEmptyImage(CS_EI_CIRC); pDeck->SetPlacement(CS_XJUST_RIGHT, CS_YJUST_BOTTOM, - X_BORDER, - Y_BORDER); pDeck->SetDragRule(CS_DRAG_NONE, 0); pDeck->SetDropRule(CS_DROP_NONE, 0); pDeck->SetClickReleaseProc(DeckClickProc);
/* Create the row stacks */ for (i = 0; i < NUM_STACKS; i++) { pStack[i] = SpiderWnd.CreateRegion(NUM_STACKS+i, true, 0, Y_BORDER, 0, yRowStackCardOffset); pStack[i]->SetFaceDirection(CS_FACE_DOWN, 0); pos = i - NUM_STACKS/2; pStack[i]->SetPlacement(CS_XJUST_CENTER, 0, pos * (__cardwidth + X_BORDER) + 6 * (X_BORDER + 1) + 3, 0); pStack[i]->SetEmptyImage(CS_EI_SUNK); pStack[i]->SetDragRule(CS_DRAG_CALLBACK, StackDragProc); pStack[i]->SetDropRule(CS_DROP_CALLBACK, StackDropProc); pStack[i]->SetAddCardProc(StackAddProc); }}