/////////////////////////////////////////////////////////////////////////////// // $Id: Engine.cxx,v 1.2 1996/01/06 05:11:34 bwmott Exp $ /////////////////////////////////////////////////////////////////////////////// // // Engine.cxx - Oonsoo engine class // // // Bradford W. Mott // Copyright (C) 1994 // December 13,1994 // /////////////////////////////////////////////////////////////////////////////// // $Log: Engine.cxx,v $ // Revision 1.2 1996/01/06 05:11:34 bwmott // Changed all NULLs to 0 // // Revision 1.1 1995/01/12 02:07:15 bmott // Initial revision // /////////////////////////////////////////////////////////////////////////////// #include #include "UIApplication.hxx" #include "TopLevel.hxx" #include "PushButton.hxx" #include "MainDeck.hxx" #include "PlainDeck.hxx" #include "PlayingDeck.hxx" #include "NewGameCommand.hxx" #include "AboutCommand.hxx" #include "HelpCommand.hxx" #include "QuitOrCloseCommand.hxx" #include "DealCardsCommand.hxx" #include "DeckMoveCommand.hxx" #include "LinkedList.hxx" #include "Engine.hxx" /////////////////////////////////////////////////////////////////////////////// // Constructor /////////////////////////////////////////////////////////////////////////////// Engine::Engine(SpriteCollection* sprites) : mySpriteCollection(sprites) { myTitle = 0; myCongratulation = 0; // Init deck references myMainDeck = 0; for(int t=0; t<12; ++t) myPlayingDeck[t] = 0; // Build the oonsoo main application window TopLevel* toplevel = new TopLevel("Oonsoo", 100, 100, 800, 600, new QuitOrCloseCommand()); toplevel->background("Gray65"); // Create a frame with a border Frame* cardTableFrame = new Frame(toplevel, "cardTableFrame", 10,10, 780, 540, Sunken); cardTableFrame->background("Gray70"); // Create a frame to act as the card table myCardTable = new Frame(cardTableFrame, "cardTable", 5, 5, 770, 530, Flat); myCardTable->background("Gray70"); // Create the oonsoo title Sprite* title = mySpriteCollection->getByName("Title"); myTitle = new DrawingArea(myCardTable, "title", (770 - title->width()) / 2, (530 - title->height()) / 3, title->width(), title->height()); myTitle->background(title); // Create push buttons PushButton* pushButton = new PushButton(toplevel, "newGame", 10, 600-40, 90, 30, "New Game", new NewGameCommand(this)); pushButton->background("Gray70"); pushButton = new PushButton(toplevel, "about", 110, 600-40, 90, 30, "About...", new AboutCommand(mySpriteCollection)); pushButton->background("Gray70"); pushButton = new PushButton(toplevel, "rules", 210, 600-40, 90, 30, "Help...", new HelpCommand(mySpriteCollection)); pushButton->background("Gray70"); pushButton = new PushButton(toplevel, "quit", 720, 600-40, 70, 30, "Quit", new QuitOrCloseCommand()); pushButton->background("Gray70"); // Manage the main application window toplevel->manage(); } /////////////////////////////////////////////////////////////////////////////// // Destructor /////////////////////////////////////////////////////////////////////////////// Engine::~Engine() { } /////////////////////////////////////////////////////////////////////////////// // Setup a new game /////////////////////////////////////////////////////////////////////////////// void Engine::newGame() { int t; // Make sure myTitle has been removed delete myTitle; myTitle = 0; // Make sure myCongratulation has been removed delete myCongratulation; myCongratulation = 0; // Remove old decks delete myMainDeck; for(t=0; t<12; ++t) delete myPlayingDeck[t]; // Main deck used to deal from myMainDeck = new MainDeck(myCardTable, "mainDeck", 20, 10, 64, 520, mySpriteCollection, new DealCardsCommand(this)); myMainDeck->shuffle(); myMainDeck->manage(); // Create all twelve playing decks LinkedList cards; myPlayingDeck[0] = new PlayingDeck(myCardTable, "playingDeck", 140 , 10, 64, 255, mySpriteCollection, &cards, new DeckMoveCommand(this)); myPlayingDeck[1] = new PlayingDeck(myCardTable, "playingDeck", 140+110, 10, 64, 255, mySpriteCollection, &cards, new DeckMoveCommand(this)); myPlayingDeck[2] = new PlayingDeck(myCardTable, "playingDeck", 140+220, 10, 64, 255, mySpriteCollection, &cards, new DeckMoveCommand(this)); myPlayingDeck[3] = new PlayingDeck(myCardTable, "playingDeck", 140+330, 10, 64, 255, mySpriteCollection, &cards, new DeckMoveCommand(this)); myPlayingDeck[4] = new PlayingDeck(myCardTable, "playingDeck", 140+440, 10, 64, 255, mySpriteCollection, &cards, new DeckMoveCommand(this)); myPlayingDeck[5] = new PlayingDeck(myCardTable, "playingDeck", 140+550, 10, 64, 255, mySpriteCollection, &cards, new DeckMoveCommand(this)); myPlayingDeck[6] = new PlayingDeck(myCardTable, "playingDeck", 140 , 275, 64, 255, mySpriteCollection, &cards, new DeckMoveCommand(this)); myPlayingDeck[7] = new PlayingDeck(myCardTable, "playingDeck", 140+110, 275, 64, 255, mySpriteCollection, &cards, new DeckMoveCommand(this)); myPlayingDeck[8] = new PlayingDeck(myCardTable, "playingDeck", 140+220, 275, 64, 255, mySpriteCollection, &cards, new DeckMoveCommand(this)); myPlayingDeck[9] = new PlayingDeck(myCardTable, "playingDeck", 140+330, 275, 64, 255, mySpriteCollection, &cards, new DeckMoveCommand(this)); myPlayingDeck[10] = new PlayingDeck(myCardTable, "playingDeck", 140+440, 275, 64, 255, mySpriteCollection, &cards, new DeckMoveCommand(this)); myPlayingDeck[11] = new PlayingDeck(myCardTable, "playingDeck", 140+550, 275, 64, 255, mySpriteCollection, &cards, new DeckMoveCommand(this)); // Manage each of the playing decks for(t=0; t<12; ++t) myPlayingDeck[t]->manage(); // Deal the first twelve cards face down dealCards(FaceDown); // Deal the second twelve cards face up dealCards(FaceUp); } /////////////////////////////////////////////////////////////////////////////// // Deal twelve cards from the main deck to the playing deck /////////////////////////////////////////////////////////////////////////////// void Engine::dealCards(CardOrientation orientation) { // Add a card to each playing deck for(int t=0; t<12; ++t) { // Get the top card Card* card = myMainDeck->remove(); // return if there are no more cards if(card == 0) return; card->orientation(orientation); myPlayingDeck[t]->add(card); } } /////////////////////////////////////////////////////////////////////////////// // Handle moving cards from one deck to somewhere else /////////////////////////////////////////////////////////////////////////////// void Engine::moveCards(Deck* from, Deck* moved) { int t; Sound* soundSystem = application->soundSystem(); // See if the moved deck intersects with any of the playing decks for(t = 0; t < 12; ++t) { int x1 = myPlayingDeck[t]->x(); int y1 = myPlayingDeck[t]->y(); int x2 = x1 + myPlayingDeck[t]->width(); int y2 = y1 + myPlayingDeck[t]->height(); int x3 = moved->x(); int y3 = moved->y(); int x4 = x3 + moved->width(); int y4 = y3 + moved->height(); // See if the moved deck intersects this playing deck if((x3 >= x1) && (x3 <= x2) && (y3 >= y1) && (y3 <= y2)) break; if((x4 >= x1) && (x4 <= x2) && (y4 >= y1) && (y4 <= y2)) break; if((x4 >= x1) && (x4 <= x2) && (y3 >= y1) && (y3 <= y2)) break; if((x3 >= x1) && (x3 <= x2) && (y4 >= y1) && (y4 <= y2)) break; } // Unmanage the moved deck moved->unmanage(); // Take the cards out of the moved deck and place them in a linked list LinkedList movedCards; for(Card* card = moved->remove(); card != 0; card = moved->remove()) movedCards.prepend(card); // Delete the moved deck delete moved; if(t != 12) { // If it's the deck they moved from then go ahead and add it back if(myPlayingDeck[t] == from) { from->add(&movedCards); } else if(myPlayingDeck[t]->checkValidAddition(&movedCards)) { myPlayingDeck[t]->add(&movedCards); // Tell the "from" deck to turn its top card over from->turnTopCardFaceUp(); // Check to see if the game is finished CheckAndHandleFinished(); } else { // Bad user! Move them back to where they came from from->add(&movedCards); if(soundSystem->state() == Enabled) soundSystem->playSample("BeepCasio"); else XBell(application->display(), 50); } } else { // Bad user! Move them back to where they came from from->add(&movedCards); if(soundSystem->state() == Enabled) soundSystem->playSample("BeepCasio"); else XBell(application->display(), 50); } } /////////////////////////////////////////////////////////////////////////////// // Check to see if the game has been finished /////////////////////////////////////////////////////////////////////////////// void Engine::CheckAndHandleFinished() { Sound* soundSystem = application->soundSystem(); // Make sure each playing deck is correct for(int t = 0; t < 12; ++t) { if(myPlayingDeck[t]->checkCompleteSuitInOrder() == 0) return; } // Ok, the game has been finished Sprite* congratulation = mySpriteCollection->getByName("Congratulation"); myCongratulation = new DrawingArea(myCardTable, "congratulation", 10, 10, congratulation->width(), congratulation->height()); myCongratulation->background(congratulation); myCongratulation->manage(); if(soundSystem->state() == Enabled) soundSystem->playSample("Chord"); else XBell(application->display(), 50); }