From b39a6bf3e7add336dbb127394e8c611ec1d29cd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=BCnther?= Date: Fri, 21 Sep 2007 01:43:48 +0200 Subject: Renamed *.c files to C++ suffix *.cpp --- bitmap.c | 190 ---------------------------- bitmap.cpp | 190 ++++++++++++++++++++++++++++ deck.c | 89 ------------- deck.cpp | 89 +++++++++++++ game.c | 408 ------------------------------------------------------------ game.cpp | 408 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ heap.c | 316 ---------------------------------------------- heap.cpp | 316 ++++++++++++++++++++++++++++++++++++++++++++++ history.c | 163 ------------------------ history.cpp | 163 ++++++++++++++++++++++++ i18n.c | 233 ---------------------------------- i18n.cpp | 233 ++++++++++++++++++++++++++++++++++ setup.c | 60 --------- setup.cpp | 60 +++++++++ spider.c | 72 ----------- spider.cpp | 72 +++++++++++ tableau.c | 315 ---------------------------------------------- tableau.cpp | 315 ++++++++++++++++++++++++++++++++++++++++++++++ 18 files changed, 1846 insertions(+), 1846 deletions(-) delete mode 100644 bitmap.c create mode 100644 bitmap.cpp delete mode 100644 deck.c create mode 100644 deck.cpp delete mode 100644 game.c create mode 100644 game.cpp delete mode 100644 heap.c create mode 100644 heap.cpp delete mode 100644 history.c create mode 100644 history.cpp delete mode 100644 i18n.c create mode 100644 i18n.cpp delete mode 100644 setup.c create mode 100644 setup.cpp delete mode 100644 spider.c create mode 100644 spider.cpp delete mode 100644 tableau.c create mode 100644 tableau.cpp diff --git a/bitmap.c b/bitmap.c deleted file mode 100644 index 38ce31b..0000000 --- a/bitmap.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Spider-Arachnid: A plugin for the Video Disk Recorder - * - * Copyright (C) 2005-2007, Thomas Günther - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * $Id: bitmap.c 87 2007-06-22 22:37:36Z tom $ - */ - -#include "bitmap.h" -#include -#include -#include -#include - - -/** --- class Bitmap ------------------------------------------------------- **/ - -/** Constructor */ -Bitmap::Bitmap(int width, int height) : - cBitmap(width, height, 4) -{ -} - -/** Constructor for a bitmap with frame */ -Bitmap::Bitmap(int width, int height, tColor frameColor, tColor backgroundColor) : - cBitmap(width, height, 4) -{ - DrawRectangle(0, 0, width - 1, height - 1, backgroundColor); - frame(0, 0, width - 1, height - 1, frameColor); -} - -/** Constructor for a bitmap read from an xpm file */ -Bitmap::Bitmap(int width, int height, const char* dir, const char* name) : - cBitmap(width, height, 4) -{ - char* path; - asprintf(&path, "%s/%s.xpm", dir, name); - loadXpm(path); - free(path); -} - -/** Constructor for a card bitmap read from an xpm file */ -Bitmap::Bitmap(int width, int height, const char* dir, - const char* suit, const char* rank) : - cBitmap(width, height, 4) -{ - char* path; - asprintf(&path, "%s/%s_%s.xpm", dir, suit, rank); - loadXpm(path); - free(path); -} - -/** Write a text into the bitmap */ -void Bitmap::text(const char* text, bool centered) -{ - DrawRectangle(0, 0, Width() - 1, Height() - 1, clrWhite); - frame(0, 0, Width() - 1, Height() - 1, clrRed); - const cFont* font = cFont::GetFont(fontOsd); - cTextWrapper wrapper(text, font, Width()); - int y = max((Height() - wrapper.Lines() * font->Height()) / 2, 0); - for (int l = 0; l < wrapper.Lines(); ++l, y += font->Height()) - { - int x = 0; - if (centered) - x = max((Width() - font->Width(wrapper.GetLine(l))) / 2, 0); - DrawText(x, y, wrapper.GetLine(l), clrBlack, clrWhite, font); - } -} - -/** Draw a frame into the bitmap */ -void Bitmap::frame(int x1, int y1, int x2, int y2, tColor frameColor) -{ - DrawRectangle(x1, y1, x2, y1 + 1, frameColor); - DrawRectangle(x1, y1, x1 + 1, y2, frameColor); - DrawRectangle(x1, y2 - 1, x2, y2, frameColor); - DrawRectangle(x2 - 1, y1, x2, y2, frameColor); -} - -/** Load a bitmap from an xpm file - taken from ElchiAIO4d patch */ -bool Bitmap::loadXpm(const char* FileName, tColor NoneColor) -{ - bool bRet = false; - FILE *infile; - infile = fopen(FileName, "r"); - if (infile) { - bool ok = true; - char buf[512]; - char *ptr; - int state = 0; - int width, height, colors, colwidth, cnt = 0; - int temp; - uint pal[65536]; - - while (ok && fgets(buf, sizeof(buf), infile) != NULL) { - int len = strlen(buf); - ptr = buf; - if (ptr[len - 1] == '\n') - ptr[--len] = '\0'; - - if (state > 0 && strncmp(ptr, "/*", 2) == 0) { - continue; - } - - switch (state) { - case 0: - if (strcmp(ptr, "/* XPM */") != 0) { - esyslog("ERROR: loading xpm %s failed: invalid header", FileName); - ok = false; - break; - } - ++state; - break; - case 1: - ++state; - break; - case 2: - sscanf(ptr, "\"%d %d %d %d\",", &width, &height, &colors, &colwidth); - if (colwidth > 2) { - esyslog("ERROR: wrong colorwidth in xpm %s", FileName); - ok = false; - break; - } - cnt = 0; - ++state; - break; - case 3: - ++ptr; - temp = 0; - for (int i = 0; i < colwidth; ++i) { - temp <<= 8; - temp += (int)*ptr; - ++ptr; - } - ++ptr; - if (strncmp(ptr, "c ", 2) != 0) { - esyslog("ERROR: wrong character in xpm %s", FileName); - ok = false; - break; - } - ptr += 2; - if (*ptr == '#') { - int col = strtoul(++ptr, NULL, 16); - pal[temp] = 0xff000000 | col; - } - else { - pal[temp] = NoneColor; - } - if (++cnt == colors) { - cnt = 0; - ++state; - } - break; - case 4: - ++ptr; - for (int p = 0; p < width; ++p) { - temp = 0; - for (int i = 0; i < colwidth; ++i) { - temp <<= 8; - temp += (int)*ptr; - ++ptr; - } - DrawPixel(p, cnt, (tColor)pal[temp]); - } - if (++cnt == height) { - ++state; - bRet = true; - } - break; - default: - break; - } - } - fclose(infile); - } - return bRet; -} diff --git a/bitmap.cpp b/bitmap.cpp new file mode 100644 index 0000000..998d5d8 --- /dev/null +++ b/bitmap.cpp @@ -0,0 +1,190 @@ +/* + * Spider-Arachnid: A plugin for the Video Disk Recorder + * + * Copyright (C) 2005-2007, Thomas Günther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * $Id: bitmap.cpp 94 2007-09-20 23:43:48Z tom $ + */ + +#include "bitmap.h" +#include +#include +#include +#include + + +/** --- class Bitmap ------------------------------------------------------- **/ + +/** Constructor */ +Bitmap::Bitmap(int width, int height) : + cBitmap(width, height, 4) +{ +} + +/** Constructor for a bitmap with frame */ +Bitmap::Bitmap(int width, int height, tColor frameColor, tColor backgroundColor) : + cBitmap(width, height, 4) +{ + DrawRectangle(0, 0, width - 1, height - 1, backgroundColor); + frame(0, 0, width - 1, height - 1, frameColor); +} + +/** Constructor for a bitmap read from an xpm file */ +Bitmap::Bitmap(int width, int height, const char* dir, const char* name) : + cBitmap(width, height, 4) +{ + char* path; + asprintf(&path, "%s/%s.xpm", dir, name); + loadXpm(path); + free(path); +} + +/** Constructor for a card bitmap read from an xpm file */ +Bitmap::Bitmap(int width, int height, const char* dir, + const char* suit, const char* rank) : + cBitmap(width, height, 4) +{ + char* path; + asprintf(&path, "%s/%s_%s.xpm", dir, suit, rank); + loadXpm(path); + free(path); +} + +/** Write a text into the bitmap */ +void Bitmap::text(const char* text, bool centered) +{ + DrawRectangle(0, 0, Width() - 1, Height() - 1, clrWhite); + frame(0, 0, Width() - 1, Height() - 1, clrRed); + const cFont* font = cFont::GetFont(fontOsd); + cTextWrapper wrapper(text, font, Width()); + int y = max((Height() - wrapper.Lines() * font->Height()) / 2, 0); + for (int l = 0; l < wrapper.Lines(); ++l, y += font->Height()) + { + int x = 0; + if (centered) + x = max((Width() - font->Width(wrapper.GetLine(l))) / 2, 0); + DrawText(x, y, wrapper.GetLine(l), clrBlack, clrWhite, font); + } +} + +/** Draw a frame into the bitmap */ +void Bitmap::frame(int x1, int y1, int x2, int y2, tColor frameColor) +{ + DrawRectangle(x1, y1, x2, y1 + 1, frameColor); + DrawRectangle(x1, y1, x1 + 1, y2, frameColor); + DrawRectangle(x1, y2 - 1, x2, y2, frameColor); + DrawRectangle(x2 - 1, y1, x2, y2, frameColor); +} + +/** Load a bitmap from an xpm file - taken from ElchiAIO4d patch */ +bool Bitmap::loadXpm(const char* FileName, tColor NoneColor) +{ + bool bRet = false; + FILE *infile; + infile = fopen(FileName, "r"); + if (infile) { + bool ok = true; + char buf[512]; + char *ptr; + int state = 0; + int width, height, colors, colwidth, cnt = 0; + int temp; + uint pal[65536]; + + while (ok && fgets(buf, sizeof(buf), infile) != NULL) { + int len = strlen(buf); + ptr = buf; + if (ptr[len - 1] == '\n') + ptr[--len] = '\0'; + + if (state > 0 && strncmp(ptr, "/*", 2) == 0) { + continue; + } + + switch (state) { + case 0: + if (strcmp(ptr, "/* XPM */") != 0) { + esyslog("ERROR: loading xpm %s failed: invalid header", FileName); + ok = false; + break; + } + ++state; + break; + case 1: + ++state; + break; + case 2: + sscanf(ptr, "\"%d %d %d %d\",", &width, &height, &colors, &colwidth); + if (colwidth > 2) { + esyslog("ERROR: wrong colorwidth in xpm %s", FileName); + ok = false; + break; + } + cnt = 0; + ++state; + break; + case 3: + ++ptr; + temp = 0; + for (int i = 0; i < colwidth; ++i) { + temp <<= 8; + temp += (int)*ptr; + ++ptr; + } + ++ptr; + if (strncmp(ptr, "c ", 2) != 0) { + esyslog("ERROR: wrong character in xpm %s", FileName); + ok = false; + break; + } + ptr += 2; + if (*ptr == '#') { + int col = strtoul(++ptr, NULL, 16); + pal[temp] = 0xff000000 | col; + } + else { + pal[temp] = NoneColor; + } + if (++cnt == colors) { + cnt = 0; + ++state; + } + break; + case 4: + ++ptr; + for (int p = 0; p < width; ++p) { + temp = 0; + for (int i = 0; i < colwidth; ++i) { + temp <<= 8; + temp += (int)*ptr; + ++ptr; + } + DrawPixel(p, cnt, (tColor)pal[temp]); + } + if (++cnt == height) { + ++state; + bRet = true; + } + break; + default: + break; + } + } + fclose(infile); + } + return bRet; +} diff --git a/deck.c b/deck.c deleted file mode 100644 index b708a5f..0000000 --- a/deck.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Spider-Arachnid: A plugin for the Video Disk Recorder - * - * Copyright (C) 2005-2007, Thomas Günther - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * $Id: deck.c 87 2007-06-22 22:37:36Z tom $ - */ - -#include "deck.h" -#include -#include -#include - - -/** Random number 0 .. max-1 */ -unsigned int rand(unsigned int max) -{ - static unsigned int seed = cTimeMs::Now(); - return (unsigned int)((double)max * rand_r(&seed) / (RAND_MAX + 1.0)); -} - - -/** --- class Deck --------------------------------------------------------- **/ - -/** Constructor */ -Deck::Deck(int cards, int suits, int decks) : - allCards(cards * suits * decks) -{ - cardsInSuit = cards; - suitCount = suits; - deckCount = decks; - shuffle(); -} - -/** Current count of cards */ -int Deck::count() const -{ - return allCards.size(); -} - -/** Card in deck */ -const Card& Deck::card(int position) const -{ - return allCards[position]; -} - -/** Shuffle the deck */ -void Deck::shuffle() -{ - for (unsigned int i = 0; i < allCards.size(); ++i) - { - int pos = -1; - while (pos < 0) - pos = rand(allCards.size()); - while (allCards[pos].suit >= 0) - pos = (pos + 1) % allCards.size(); - allCards[pos] = Card((i / cardsInSuit) % suitCount, i % cardsInSuit); - } -} - - -/** --- class Card --------------------------------------------------------- **/ - -/** Constructor */ -Card::Card(int s, int r) -{ - suit = s; - rank = r; -} - -/** Matches this card to an other card? */ -bool Card::matchesTo(const Card& other) const -{ - return (suit == other.suit && rank + 1 == other.rank); -} diff --git a/deck.cpp b/deck.cpp new file mode 100644 index 0000000..0537ee9 --- /dev/null +++ b/deck.cpp @@ -0,0 +1,89 @@ +/* + * Spider-Arachnid: A plugin for the Video Disk Recorder + * + * Copyright (C) 2005-2007, Thomas Günther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * $Id: deck.cpp 94 2007-09-20 23:43:48Z tom $ + */ + +#include "deck.h" +#include +#include +#include + + +/** Random number 0 .. max-1 */ +unsigned int rand(unsigned int max) +{ + static unsigned int seed = cTimeMs::Now(); + return (unsigned int)((double)max * rand_r(&seed) / (RAND_MAX + 1.0)); +} + + +/** --- class Deck --------------------------------------------------------- **/ + +/** Constructor */ +Deck::Deck(int cards, int suits, int decks) : + allCards(cards * suits * decks) +{ + cardsInSuit = cards; + suitCount = suits; + deckCount = decks; + shuffle(); +} + +/** Current count of cards */ +int Deck::count() const +{ + return allCards.size(); +} + +/** Card in deck */ +const Card& Deck::card(int position) const +{ + return allCards[position]; +} + +/** Shuffle the deck */ +void Deck::shuffle() +{ + for (unsigned int i = 0; i < allCards.size(); ++i) + { + int pos = -1; + while (pos < 0) + pos = rand(allCards.size()); + while (allCards[pos].suit >= 0) + pos = (pos + 1) % allCards.size(); + allCards[pos] = Card((i / cardsInSuit) % suitCount, i % cardsInSuit); + } +} + + +/** --- class Card --------------------------------------------------------- **/ + +/** Constructor */ +Card::Card(int s, int r) +{ + suit = s; + rank = r; +} + +/** Matches this card to an other card? */ +bool Card::matchesTo(const Card& other) const +{ + return (suit == other.suit && rank + 1 == other.rank); +} diff --git a/game.c b/game.c deleted file mode 100644 index 98bd581..0000000 --- a/game.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Spider-Arachnid: A plugin for the Video Disk Recorder - * - * Copyright (C) 2005-2007, Thomas Günther - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * $Id: game.c 87 2007-06-22 22:37:36Z tom $ - */ - -#include "game.h" -#include "deck.h" -#include "tableau.h" -#include "heap.h" -#include "setup.h" -#include "bitmap.h" -#include "i18n.h" -#include -#include -#include - - -// Defintions for bitmaps -const int cursorWidth = 16; -const int cursorHeight = 22; -const int cardWidth = 71; -const int cardHeight = 96; - -const char* cursorName = "cursor"; -const char* coverName = "cover"; -const char* suitNames[] = { "herz", "karo", "pik", "kreuz" }; -const char* rankNames[] = { "ace", "two", "three", "four", "five", - "six", "seven", "eight", "nine", "ten", - "jack", "queen", "king" }; -const int suitCount = sizeof(suitNames) / sizeof(*suitNames); -const int rankCount = sizeof(rankNames) / sizeof(*rankNames); - -Bitmap* cursor = NULL; -Bitmap* back = NULL; -Bitmap* frame = NULL; -Bitmap* cards[suitCount][rankCount]; - - -/** --- class SpiderGame --------------------------------------------------- **/ - -/** Constructor */ -SpiderGame::SpiderGame(const SpiderSetup& setup, const char* confdir) : - cOsdObject(true), setup(setup), confdir(confdir) -{ - width = 504; - height = 360; - xPos = (720 - width) / 2; - yPos = (576 - height) / 2; - xDist = 1; - yDist = cardHeight / 6; - osd = NULL; - deck = NULL; - tableau = NULL; - currentPile = 0; - status = cursorOnPile; - info = new Bitmap(width * 2 / 3, 60); - infoText = NULL; -} - -/** Destructor */ -SpiderGame::~SpiderGame() -{ - delete deck; - delete tableau; - delete info; - delete osd; - for (int s = 0; s < suitCount; ++s) - for (int r = 0; r < rankCount; ++r) - delete cards[s][r]; - delete frame; - delete back; - delete cursor; - frame = back = cursor = NULL; -} - -/** Display the game on the OSD */ -void SpiderGame::Show() -{ - osd = cOsdProvider::NewOsd(0, 0); - if (osd) - { - tArea area = { xPos, yPos, xPos + width - 1, yPos + height - 1, 4 }; - osd->SetAreas(&area, 1); - start(); - paint(); - } -} - -/** Process user events */ -eOSState SpiderGame::ProcessKey(eKeys key) -{ - eOSState state = cOsdObject::ProcessKey(key); - if (state == osUnknown) - { - if (key == kBack) - return osEnd; - if (key == kBlue || (status == gameOver && key == kOk)) - { - start(); - status = cursorOnPile; - currentPile = 0; - } - else if (status == cursorOnPile) - { - switch (key) - { - case kLeft: - case kLeft|k_Repeat: - if (currentPile > 0) - --currentPile; - break; - case kRight: - case kRight|k_Repeat: - if (currentPile < tableau->piles.size() - 1) - ++currentPile; - break; - case kUp: - status = cursorOnPack; - break; - case kOk: - if (!tableau->piles[currentPile]->empty()) - { - tableau->select(currentPile); - status = selectedPile; - } - break; - case kGreen: - tableau->backward(); - break; - case kYellow: - tableau->forward(); - break; - default: - return osContinue; - } - } - else if (status == selectedPile) - { - int selected = tableau->selected->selected(); - int destination; - switch (key) - { - case kLeft: - destination = tableau->autoMoveLeft(currentPile); - if (destination >= 0) - { - currentPile = destination; - tableau->select(currentPile, selected); - } - break; - case kRight: - destination = tableau->autoMoveRight(currentPile); - if (destination >= 0) - { - currentPile = destination; - tableau->select(currentPile, selected); - } - break; - case kUp: - case kUp|k_Repeat: - tableau->selected->select(selected + 1); - if (key == kUp) - { - if (selected == deck->cardsInSuit) - { - tableau->remove(); - status = cursorOnPile; - } - else if (selected == tableau->selected->selected()) - infoText = tr("Only complete suits are allowed to remove"); - } - break; - case kDown: - case kDown|k_Repeat: - if (selected > 1) - tableau->selected->select(selected - 1); - break; - case kOk: - tableau->unselect(); - status = cursorOnPile; - break; - default: - return osContinue; - } - } - else if (status == cursorOnPack) - { - switch (key) - { - case kDown: - status = cursorOnPile; - currentPile = 0; - break; - case kOk: - if (tableau->pack->empty()) - infoText = tr("No cards left"); - else if (!tableau->noPileEmpty()) - infoText = tr("Deal not allowed with empty piles"); - else - tableau->deal(); - break; - default: - return osContinue; - } - } - if (tableau->gameOver()) - { - status = gameOver; - infoText = tr("Congratulations!\nPress OK to start a new game"); - } - paint(); - state = osContinue; - } - return state; -} - -/** Start a new game */ -void SpiderGame::start() -{ - // Load bitmaps - if (cursor == NULL) - { - cursor = new Bitmap(cursorWidth, cursorHeight, confdir, cursorName); - back = new Bitmap(cardWidth, cardHeight, confdir, coverName); - frame = new Bitmap(cardWidth, cardHeight, clrWhite, clrGray50); - - for (int s = 0; s < suitCount; ++s) - for (int r = 0; r < rankCount; ++r) - cards[s][r] = new Bitmap(cardWidth, cardHeight, confdir, - suitNames[s], rankNames[r]); - } - - delete deck; - delete tableau; - deck = NULL; - tableau = NULL; - - int deckCount, dealCount, pileCount; - - if (setup.variation == SpiderSetup::Mini) - { - deckCount = 1; - dealCount = 4; - pileCount = 7; - } - else // normal variation - { - deckCount = 2; - dealCount = 5; - pileCount = 10; - xDist = -23; - } - - if (pileCount > rankCount * suitCount * deckCount) - pileCount = rankCount * suitCount * deckCount; - int finalCount = suitCount * deckCount; - deck = new Deck(rankCount, suitCount, deckCount); - tableau = new Tableau(*deck, pileCount, finalCount, dealCount); -} - -/** Paint all pieces of the game */ -void SpiderGame::paint() -{ - int x1 = xPos; - int x2 = xPos + width - 1; - int y1 = yPos; - int y2 = yPos + height - 1; - - // Save and restore palette to reduce flickering - cPalette savePalette(*osd->GetBitmap(0)); - osd->DrawRectangle(x1, y1, x2, y2, clrGray50); - osd->SetPalette(savePalette, 0); - - // Paint red frame - osd->DrawRectangle(x1, y1, x2, y1 + 1, clrRed); - osd->DrawRectangle(x1, y1, x1 + 1, y2, clrRed); - osd->DrawRectangle(x1, y2 - 1, x2, y2, clrRed); - osd->DrawRectangle(x2 - 1, y1, x2, y2, clrRed); - - paintPack(); - - unsigned int f; - for (f = 0; f < tableau->finals.size(); ++f) - if (tableau->finals[f]->empty()) - break; - unsigned int count = f; - for (f = tableau->finals.size(); f-- > count;) - paintFinal(f); - for (f = 0; f < count; ++f) - paintFinal(f); - - unsigned int p; - for (p = tableau->piles.size(); p-- > currentPile + 1;) - paintPile(p); - for (p = 0; p <= currentPile; ++p) - paintPile(p); - - if (infoText) - { - info->text(infoText); - osd->DrawBitmap(xPos + (width - info->Width()) / 2, yPos + 10, *info); - infoText = NULL; - } - osd->Flush(); -} - -/** Paint the pack */ -void SpiderGame::paintPack() -{ - int packX = xPos + 1; - int packY = yPos + 1; - if (tableau->pack->empty()) - paintFrame(packX, packY); - else - paintBack(packX, packY); - if (status == cursorOnPack) - paintCursor(packX, packY); -} - -/** Paint a final heap */ -void SpiderGame::paintFinal(unsigned int f) -{ - int offset = tableau->piles.size() - tableau->finals.size(); - int finalX = xPos + 1 + (f + offset) * (cardWidth + xDist); - int finalY = yPos + 1; - if (tableau->finals[f]->empty()) - paintFrame(finalX, finalY); - else - paintCard(finalX, finalY, tableau->finals[f]->top()); -} - -/** Paint a pile */ -void SpiderGame::paintPile(unsigned int p) -{ - int pileX = xPos + 1 + p * (cardWidth + xDist); - int pileY = yPos + 1 + cardHeight + 1; - paintFrame(pileX, pileY); - - int count = tableau->piles[p]->count(); - int closed = count - tableau->piles[p]->open(); - int unselected = count - tableau->piles[p]->selected(); - int dist = yDist; - if (pileY + (count + 1) * dist > yPos + height) - dist = (yPos + height - pileY) / (count + 1); - - for (int c = 0; c < count; ++c, pileY += dist) - { - if (c == unselected) - pileY += dist; - if (c < closed) - paintBack(pileX, pileY); - else - paintCard(pileX, pileY, tableau->piles[p]->card(c)); - } - if (count > 0) - pileY -= dist; - if ((status == cursorOnPile || status == selectedPile) && p == currentPile) - paintCursor(pileX, pileY); -} - -/** Paint the cursor onto a card */ -void SpiderGame::paintCursor(int x, int y) -{ - int x0 = x + (cardWidth - cursorWidth) / 2; - int y0 = y + (cardHeight - cursorHeight) / 2; - tColor color = clrBlue; - if (status == selectedPile) - color = clrYellow; - for (x = 0; x < cursorWidth; ++x) - for (y = 0; y < cursorHeight; ++y) - if (cursor->Color(*cursor->Data(x, y)) != clrTransparent) - osd->DrawRectangle(x0 + x, y0 + y, x0 + x, y0 + y, color); -} - -/** Paint an empty card frame */ -void SpiderGame::paintFrame(int x, int y) -{ - osd->DrawBitmap(x, y, *frame); -} - -/** Paint a card back */ -void SpiderGame::paintBack(int x, int y) -{ - osd->DrawBitmap(x, y, *back); -} - -/** Paint a card */ -void SpiderGame::paintCard(int x, int y, const Card& card) -{ - osd->DrawBitmap(x, y, *cards[card.suit][card.rank]); -} diff --git a/game.cpp b/game.cpp new file mode 100644 index 0000000..61ba151 --- /dev/null +++ b/game.cpp @@ -0,0 +1,408 @@ +/* + * Spider-Arachnid: A plugin for the Video Disk Recorder + * + * Copyright (C) 2005-2007, Thomas Günther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * $Id: game.cpp 94 2007-09-20 23:43:48Z tom $ + */ + +#include "game.h" +#include "deck.h" +#include "tableau.h" +#include "heap.h" +#include "setup.h" +#include "bitmap.h" +#include "i18n.h" +#include +#include +#include + + +// Defintions for bitmaps +const int cursorWidth = 16; +const int cursorHeight = 22; +const int cardWidth = 71; +const int cardHeight = 96; + +const char* cursorName = "cursor"; +const char* coverName = "cover"; +const char* suitNames[] = { "herz", "karo", "pik", "kreuz" }; +const char* rankNames[] = { "ace", "two", "three", "four", "five", + "six", "seven", "eight", "nine", "ten", + "jack", "queen", "king" }; +const int suitCount = sizeof(suitNames) / sizeof(*suitNames); +const int rankCount = sizeof(rankNames) / sizeof(*rankNames); + +Bitmap* cursor = NULL; +Bitmap* back = NULL; +Bitmap* frame = NULL; +Bitmap* cards[suitCount][rankCount]; + + +/** --- class SpiderGame --------------------------------------------------- **/ + +/** Constructor */ +SpiderGame::SpiderGame(const SpiderSetup& setup, const char* confdir) : + cOsdObject(true), setup(setup), confdir(confdir) +{ + width = 504; + height = 360; + xPos = (720 - width) / 2; + yPos = (576 - height) / 2; + xDist = 1; + yDist = cardHeight / 6; + osd = NULL; + deck = NULL; + tableau = NULL; + currentPile = 0; + status = cursorOnPile; + info = new Bitmap(width * 2 / 3, 60); + infoText = NULL; +} + +/** Destructor */ +SpiderGame::~SpiderGame() +{ + delete deck; + delete tableau; + delete info; + delete osd; + for (int s = 0; s < suitCount; ++s) + for (int r = 0; r < rankCount; ++r) + delete cards[s][r]; + delete frame; + delete back; + delete cursor; + frame = back = cursor = NULL; +} + +/** Display the game on the OSD */ +void SpiderGame::Show() +{ + osd = cOsdProvider::NewOsd(0, 0); + if (osd) + { + tArea area = { xPos, yPos, xPos + width - 1, yPos + height - 1, 4 }; + osd->SetAreas(&area, 1); + start(); + paint(); + } +} + +/** Process user events */ +eOSState SpiderGame::ProcessKey(eKeys key) +{ + eOSState state = cOsdObject::ProcessKey(key); + if (state == osUnknown) + { + if (key == kBack) + return osEnd; + if (key == kBlue || (status == gameOver && key == kOk)) + { + start(); + status = cursorOnPile; + currentPile = 0; + } + else if (status == cursorOnPile) + { + switch (key) + { + case kLeft: + case kLeft|k_Repeat: + if (currentPile > 0) + --currentPile; + break; + case kRight: + case kRight|k_Repeat: + if (currentPile < tableau->piles.size() - 1) + ++currentPile; + break; + case kUp: + status = cursorOnPack; + break; + case kOk: + if (!tableau->piles[currentPile]->empty()) + { + tableau->select(currentPile); + status = selectedPile; + } + break; + case kGreen: + tableau->backward(); + break; + case kYellow: + tableau->forward(); + break; + default: + return osContinue; + } + } + else if (status == selectedPile) + { + int selected = tableau->selected->selected(); + int destination; + switch (key) + { + case kLeft: + destination = tableau->autoMoveLeft(currentPile); + if (destination >= 0) + { + currentPile = destination; + tableau->select(currentPile, selected); + } + break; + case kRight: + destination = tableau->autoMoveRight(currentPile); + if (destination >= 0) + { + currentPile = destination; + tableau->select(currentPile, selected); + } + break; + case kUp: + case kUp|k_Repeat: + tableau->selected->select(selected + 1); + if (key == kUp) + { + if (selected == deck->cardsInSuit) + { + tableau->remove(); + status = cursorOnPile; + } + else if (selected == tableau->selected->selected()) + infoText = tr("Only complete suits are allowed to remove"); + } + break; + case kDown: + case kDown|k_Repeat: + if (selected > 1) + tableau->selected->select(selected - 1); + break; + case kOk: + tableau->unselect(); + status = cursorOnPile; + break; + default: + return osContinue; + } + } + else if (status == cursorOnPack) + { + switch (key) + { + case kDown: + status = cursorOnPile; + currentPile = 0; + break; + case kOk: + if (tableau->pack->empty()) + infoText = tr("No cards left"); + else if (!tableau->noPileEmpty()) + infoText = tr("Deal not allowed with empty piles"); + else + tableau->deal(); + break; + default: + return osContinue; + } + } + if (tableau->gameOver()) + { + status = gameOver; + infoText = tr("Congratulations!\nPress OK to start a new game"); + } + paint(); + state = osContinue; + } + return state; +} + +/** Start a new game */ +void SpiderGame::start() +{ + // Load bitmaps + if (cursor == NULL) + { + cursor = new Bitmap(cursorWidth, cursorHeight, confdir, cursorName); + back = new Bitmap(cardWidth, cardHeight, confdir, coverName); + frame = new Bitmap(cardWidth, cardHeight, clrWhite, clrGray50); + + for (int s = 0; s < suitCount; ++s) + for (int r = 0; r < rankCount; ++r) + cards[s][r] = new Bitmap(cardWidth, cardHeight, confdir, + suitNames[s], rankNames[r]); + } + + delete deck; + delete tableau; + deck = NULL; + tableau = NULL; + + int deckCount, dealCount, pileCount; + + if (setup.variation == SpiderSetup::Mini) + { + deckCount = 1; + dealCount = 4; + pileCount = 7; + } + else // normal variation + { + deckCount = 2; + dealCount = 5; + pileCount = 10; + xDist = -23; + } + + if (pileCount > rankCount * suitCount * deckCount) + pileCount = rankCount * suitCount * deckCount; + int finalCount = suitCount * deckCount; + deck = new Deck(rankCount, suitCount, deckCount); + tableau = new Tableau(*deck, pileCount, finalCount, dealCount); +} + +/** Paint all pieces of the game */ +void SpiderGame::paint() +{ + int x1 = xPos; + int x2 = xPos + width - 1; + int y1 = yPos; + int y2 = yPos + height - 1; + + // Save and restore palette to reduce flickering + cPalette savePalette(*osd->GetBitmap(0)); + osd->DrawRectangle(x1, y1, x2, y2, clrGray50); + osd->SetPalette(savePalette, 0); + + // Paint red frame + osd->DrawRectangle(x1, y1, x2, y1 + 1, clrRed); + osd->DrawRectangle(x1, y1, x1 + 1, y2, clrRed); + osd->DrawRectangle(x1, y2 - 1, x2, y2, clrRed); + osd->DrawRectangle(x2 - 1, y1, x2, y2, clrRed); + + paintPack(); + + unsigned int f; + for (f = 0; f < tableau->finals.size(); ++f) + if (tableau->finals[f]->empty()) + break; + unsigned int count = f; + for (f = tableau->finals.size(); f-- > count;) + paintFinal(f); + for (f = 0; f < count; ++f) + paintFinal(f); + + unsigned int p; + for (p = tableau->piles.size(); p-- > currentPile + 1;) + paintPile(p); + for (p = 0; p <= currentPile; ++p) + paintPile(p); + + if (infoText) + { + info->text(infoText); + osd->DrawBitmap(xPos + (width - info->Width()) / 2, yPos + 10, *info); + infoText = NULL; + } + osd->Flush(); +} + +/** Paint the pack */ +void SpiderGame::paintPack() +{ + int packX = xPos + 1; + int packY = yPos + 1; + if (tableau->pack->empty()) + paintFrame(packX, packY); + else + paintBack(packX, packY); + if (status == cursorOnPack) + paintCursor(packX, packY); +} + +/** Paint a final heap */ +void SpiderGame::paintFinal(unsigned int f) +{ + int offset = tableau->piles.size() - tableau->finals.size(); + int finalX = xPos + 1 + (f + offset) * (cardWidth + xDist); + int finalY = yPos + 1; + if (tableau->finals[f]->empty()) + paintFrame(finalX, finalY); + else + paintCard(finalX, finalY, tableau->finals[f]->top()); +} + +/** Paint a pile */ +void SpiderGame::paintPile(unsigned int p) +{ + int pileX = xPos + 1 + p * (cardWidth + xDist); + int pileY = yPos + 1 + cardHeight + 1; + paintFrame(pileX, pileY); + + int count = tableau->piles[p]->count(); + int closed = count - tableau->piles[p]->open(); + int unselected = count - tableau->piles[p]->selected(); + int dist = yDist; + if (pileY + (count + 1) * dist > yPos + height) + dist = (yPos + height - pileY) / (count + 1); + + for (int c = 0; c < count; ++c, pileY += dist) + { + if (c == unselected) + pileY += dist; + if (c < closed) + paintBack(pileX, pileY); + else + paintCard(pileX, pileY, tableau->piles[p]->card(c)); + } + if (count > 0) + pileY -= dist; + if ((status == cursorOnPile || status == selectedPile) && p == currentPile) + paintCursor(pileX, pileY); +} + +/** Paint the cursor onto a card */ +void SpiderGame::paintCursor(int x, int y) +{ + int x0 = x + (cardWidth - cursorWidth) / 2; + int y0 = y + (cardHeight - cursorHeight) / 2; + tColor color = clrBlue; + if (status == selectedPile) + color = clrYellow; + for (x = 0; x < cursorWidth; ++x) + for (y = 0; y < cursorHeight; ++y) + if (cursor->Color(*cursor->Data(x, y)) != clrTransparent) + osd->DrawRectangle(x0 + x, y0 + y, x0 + x, y0 + y, color); +} + +/** Paint an empty card frame */ +void SpiderGame::paintFrame(int x, int y) +{ + osd->DrawBitmap(x, y, *frame); +} + +/** Paint a card back */ +void SpiderGame::paintBack(int x, int y) +{ + osd->DrawBitmap(x, y, *back); +} + +/** Paint a card */ +void SpiderGame::paintCard(int x, int y, const Card& card) +{ + osd->DrawBitmap(x, y, *cards[card.suit][card.rank]); +} diff --git a/heap.c b/heap.c deleted file mode 100644 index 8758a3e..0000000 --- a/heap.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Spider-Arachnid: A plugin for the Video Disk Recorder - * - * Copyright (C) 2005-2007, Thomas Günther - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * $Id: heap.c 87 2007-06-22 22:37:36Z tom $ - */ - -#include "heap.h" -#include "deck.h" - - -/** --- base class Heap ---------------------------------------------------- **/ - -/** Constructor */ -Heap::Heap(unsigned int maxCards) -{ - maxCount = maxCards; - emptyChanged = true; -} - -/** Destructor */ -Heap::~Heap() -{ -} - -/** Current count of cards */ -int Heap::count() const -{ - return allCards.size(); -} - -/** Card in heap */ -const Card& Heap::card(int position) const -{ - return allCards[position]; -} - -/** Top card of the heap */ -const Card& Heap::top() const -{ - return allCards.back(); -} - -/** Add a new card */ -void Heap::add(const Card& card) -{ - if (allCards.size() < maxCount) - { - if (allCards.empty()) - emptyChanged = true; - allCards.push_back(card); - } -} - -/** Remove the top card */ -void Heap::remove() -{ - if (!allCards.empty()) - { - allCards.pop_back(); - if (allCards.empty()) - emptyChanged = true; - } -} - -/** Move some matching cards to an other heap */ -void Heap::moveTo(Heap* other, int countToMove) -{ - for (int i = count() - countToMove; i < count(); ++i) - other->add(card(i)); - for (int i = 0; i < countToMove; ++i) - remove(); -} - -/** Is the heap empty? */ -bool Heap::empty() const -{ - return allCards.empty(); -} - -/** Is the heap changed? */ -bool Heap::changed() const -{ - return emptyChanged; -} - -/** Reset changed property */ -void Heap::resetChanged() -{ - emptyChanged = false; -} - - -/** --- class Pack --------------------------------------------------------- **/ - -/** Constructor */ -Pack::Pack(const Deck& deck) : - Heap(deck.count()) -{ - for (int pos = 0; pos < deck.count(); ++pos) - add(deck.card(pos)); -} - -/** First initial deal of a game */ -void Pack::initialDeal(Piles& piles, int rows, Piles& extra) -{ - for (int r = 0; r < rows; ++r) - deal(piles); - deal(extra); - - // turn all open cards - for (unsigned int p = 0; p < piles.size(); ++p) - piles[p]->turn(); -} - -/** Deal one row to the piles */ -void Pack::deal(Piles& piles) -{ - for (unsigned int p = 0; p < piles.size(); ++p) - { - piles[p]->add(top()); - remove(); - } -} - -/** Cancel the deal */ -void Pack::takeBackDeal(Piles& piles) -{ - for (int p = piles.size(); --p >= 0; ) - { - add(piles[p]->top()); - piles[p]->remove(); - } -} - - -/** --- class Pile --------------------------------------------------------- **/ - -/** Constructor */ -Pile::Pile(const Deck& deck) : - Heap(deck.count()) -{ - currentOpen = 0; - currentMatching = 0; - currentSelected = 0; - currentChanged = 0; -} - -/** Add a new card */ -void Pile::add(const Card& card) -{ - Heap::add(card); - ++currentOpen; - if (topCardsMatches()) - ++currentMatching; - currentSelected = 0; - ++currentChanged; -} - -/** Remove top card from pile */ -void Pile::remove() -{ - if (currentSelected > 0) - --currentSelected; - if (topCardsMatches()) - --currentMatching; - if (currentOpen > 0) - --currentOpen; - Heap::remove(); - if (currentChanged > 0) - --currentChanged; - if (currentChanged < 1 && !empty()) - currentChanged = 1; -} - -/** Turn all open top cards or rather open the top card */ -void Pile::turn() -{ - if (currentOpen < 1 && !empty()) - currentOpen = 1; - else - currentOpen = 0; - currentMatching = 0; - if (currentChanged < 1 && !empty()) - currentChanged = 1; -} - -/** Current count of open cards */ -int Pile::open() const -{ - return currentOpen; -} - -/** Current count of matching cards */ -int Pile::getMatching() const -{ - return currentMatching; -} - -/** The two open top cards are matching */ -bool Pile::topCardsMatches() const -{ - return (open() >= 2 && card(count() - 1).matchesTo(card(count() - 2))); -} - -/** Current count of selected cards */ -int Pile::selected() const -{ - return currentSelected; -} - -/** Select up to max matching cards on the end of this pile */ -void Pile::select(int max) -{ - currentSelected = 0; - if (open() > 0) - { - currentSelected = 1; - for (int i = count(); --i > count() - open(); ) - if (card(i).matchesTo(card(i - 1))) - currentSelected++; - else - break; - } - if (currentSelected > max && max > 0) - currentSelected = max; - if (currentChanged < currentSelected) - currentChanged = currentSelected; -} - -/** Unselect this pile */ -void Pile::unselect() -{ - if (currentChanged < currentSelected) - currentChanged = currentSelected; - currentSelected = 0; -} - -/** Adapt the selection to match an other pile */ -void Pile::adaptSelectionTo(const Pile* other) -{ - if (!other->empty()) - { - if (currentChanged < currentSelected) - currentChanged = currentSelected; - int diff = other->top().rank - top().rank; - if (diff > 0 && diff <= currentSelected) - currentSelected = diff; - else - currentSelected = 0; - } -} - -/** Matches the selection to an other pile? */ -bool Pile::selectionMatchesTo(const Pile* other, bool matchSuit) const -{ - return (!other->empty() && - (other->top().rank == top().rank + currentSelected) && - (other->top().suit == top().suit || !matchSuit)); -} - -/** Is the heap changed? */ -bool Pile::changed() const -{ - return (Heap::changed() || currentChanged > 0); -} - -/** Reset changed property */ -void Pile::resetChanged() -{ - Heap::resetChanged(); - currentChanged = 0; -} - -/** How many cards are changed? */ -int Pile::cardsChanged() const -{ - return currentChanged; -} - - -/** --- class FinalHeap ---------------------------------------------------- **/ - -/** Constructor */ -FinalHeap::FinalHeap(const Deck& deck) : - Heap(deck.cardsInSuit) -{ - bonus = false; -} - -/** Set bonus of the final heap */ -void FinalHeap::setBonus(bool newBonus) -{ - bonus = newBonus; -} - -/** Has this final heap bonus? */ -bool FinalHeap::getBonus() const -{ - return bonus; -} diff --git a/heap.cpp b/heap.cpp new file mode 100644 index 0000000..d15b9c5 --- /dev/null +++ b/heap.cpp @@ -0,0 +1,316 @@ +/* + * Spider-Arachnid: A plugin for the Video Disk Recorder + * + * Copyright (C) 2005-2007, Thomas Günther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * $Id: heap.cpp 94 2007-09-20 23:43:48Z tom $ + */ + +#include "heap.h" +#include "deck.h" + + +/** --- base class Heap ---------------------------------------------------- **/ + +/** Constructor */ +Heap::Heap(unsigned int maxCards) +{ + maxCount = maxCards; + emptyChanged = true; +} + +/** Destructor */ +Heap::~Heap() +{ +} + +/** Current count of cards */ +int Heap::count() const +{ + return allCards.size(); +} + +/** Card in heap */ +const Card& Heap::card(int position) const +{ + return allCards[position]; +} + +/** Top card of the heap */ +const Card& Heap::top() const +{ + return allCards.back(); +} + +/** Add a new card */ +void Heap::add(const Card& card) +{ + if (allCards.size() < maxCount) + { + if (allCards.empty()) + emptyChanged = true; + allCards.push_back(card); + } +} + +/** Remove the top card */ +void Heap::remove() +{ + if (!allCards.empty()) + { + allCards.pop_back(); + if (allCards.empty()) + emptyChanged = true; + } +} + +/** Move some matching cards to an other heap */ +void Heap::moveTo(Heap* other, int countToMove) +{ + for (int i = count() - countToMove; i < count(); ++i) + other->add(card(i)); + for (int i = 0; i < countToMove; ++i) + remove(); +} + +/** Is the heap empty? */ +bool Heap::empty() const +{ + return allCards.empty(); +} + +/** Is the heap changed? */ +bool Heap::changed() const +{ + return emptyChanged; +} + +/** Reset changed property */ +void Heap::resetChanged() +{ + emptyChanged = false; +} + + +/** --- class Pack --------------------------------------------------------- **/ + +/** Constructor */ +Pack::Pack(const Deck& deck) : + Heap(deck.count()) +{ + for (int pos = 0; pos < deck.count(); ++pos) + add(deck.card(pos)); +} + +/** First initial deal of a game */ +void Pack::initialDeal(Piles& piles, int rows, Piles& extra) +{ + for (int r = 0; r < rows; ++r) + deal(piles); + deal(extra); + + // turn all open cards + for (unsigned int p = 0; p < piles.size(); ++p) + piles[p]->turn(); +} + +/** Deal one row to the piles */ +void Pack::deal(Piles& piles) +{ + for (unsigned int p = 0; p < piles.size(); ++p) + { + piles[p]->add(top()); + remove(); + } +} + +/** Cancel the deal */ +void Pack::takeBackDeal(Piles& piles) +{ + for (int p = piles.size(); --p >= 0; ) + { + add(piles[p]->top()); + piles[p]->remove(); + } +} + + +/** --- class Pile --------------------------------------------------------- **/ + +/** Constructor */ +Pile::Pile(const Deck& deck) : + Heap(deck.count()) +{ + currentOpen = 0; + currentMatching = 0; + currentSelected = 0; + currentChanged = 0; +} + +/** Add a new card */ +void Pile::add(const Card& card) +{ + Heap::add(card); + ++currentOpen; + if (topCardsMatches()) + ++currentMatching; + currentSelected = 0; + ++currentChanged; +} + +/** Remove top card from pile */ +void Pile::remove() +{ + if (currentSelected > 0) + --currentSelected; + if (topCardsMatches()) + --currentMatching; + if (currentOpen > 0) + --currentOpen; + Heap::remove(); + if (currentChanged > 0) + --currentChanged; + if (currentChanged < 1 && !empty()) + currentChanged = 1; +} + +/** Turn all open top cards or rather open the top card */ +void Pile::turn() +{ + if (currentOpen < 1 && !empty()) + currentOpen = 1; + else + currentOpen = 0; + currentMatching = 0; + if (currentChanged < 1 && !empty()) + currentChanged = 1; +} + +/** Current count of open cards */ +int Pile::open() const +{ + return currentOpen; +} + +/** Current count of matching cards */ +int Pile::getMatching() const +{ + return currentMatching; +} + +/** The two open top cards are matching */ +bool Pile::topCardsMatches() const +{ + return (open() >= 2 && card(count() - 1).matchesTo(card(count() - 2))); +} + +/** Current count of selected cards */ +int Pile::selected() const +{ + return currentSelected; +} + +/** Select up to max matching cards on the end of this pile */ +void Pile::select(int max) +{ + currentSelected = 0; + if (open() > 0) + { + currentSelected = 1; + for (int i = count(); --i > count() - open(); ) + if (card(i).matchesTo(card(i - 1))) + currentSelected++; + else + break; + } + if (currentSelected > max && max > 0) + currentSelected = max; + if (currentChanged < currentSelected) + currentChanged = currentSelected; +} + +/** Unselect this pile */ +void Pile::unselect() +{ + if (currentChanged < currentSelected) + currentChanged = currentSelected; + currentSelected = 0; +} + +/** Adapt the selection to match an other pile */ +void Pile::adaptSelectionTo(const Pile* other) +{ + if (!other->empty()) + { + if (currentChanged < currentSelected) + currentChanged = currentSelected; + int diff = other->top().rank - top().rank; + if (diff > 0 && diff <= currentSelected) + currentSelected = diff; + else + currentSelected = 0; + } +} + +/** Matches the selection to an other pile? */ +bool Pile::selectionMatchesTo(const Pile* other, bool matchSuit) const +{ + return (!other->empty() && + (other->top().rank == top().rank + currentSelected) && + (other->top().suit == top().suit || !matchSuit)); +} + +/** Is the heap changed? */ +bool Pile::changed() const +{ + return (Heap::changed() || currentChanged > 0); +} + +/** Reset changed property */ +void Pile::resetChanged() +{ + Heap::resetChanged(); + currentChanged = 0; +} + +/** How many cards are changed? */ +int Pile::cardsChanged() const +{ + return currentChanged; +} + + +/** --- class FinalHeap ---------------------------------------------------- **/ + +/** Constructor */ +FinalHeap::FinalHeap(const Deck& deck) : + Heap(deck.cardsInSuit) +{ + bonus = false; +} + +/** Set bonus of the final heap */ +void FinalHeap::setBonus(bool newBonus) +{ + bonus = newBonus; +} + +/** Has this final heap bonus? */ +bool FinalHeap::getBonus() const +{ + return bonus; +} diff --git a/history.c b/history.c deleted file mode 100644 index b045092..0000000 --- a/history.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Spider-Arachnid: A plugin for the Video Disk Recorder - * - * Copyright (C) 2005-2007, Thomas Günther - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * $Id: history.c 87 2007-06-22 22:37:36Z tom $ - */ - -#include "history.h" -#include "deck.h" -#include "heap.h" - - -/** --- class History ------------------------------------------------------ **/ - -/** Constructor */ -History::History() -{ - executed = 0; -} - -/** Destructor */ -History::~History() -{ - for (unsigned int pos = history.size(); pos > 0; --pos) - { - // Remove object created outside of History - delete history.back(); - history.pop_back(); - } -} - -/** Current move in the history */ -Move* History::current() -{ - return history[executed - 1]; -} - -/** Add a new move */ -void History::add(Move* move) -{ - for (unsigned int pos = history.size(); pos > executed; --pos) - { - // Remove object created outside of History - delete history.back(); - history.pop_back(); - } - history.push_back(move); - ++executed; -} - -/** Set previous move as current */ -void History::backward() -{ - if (movesExecuted()) - --executed; -} - -/** Set next move as current */ -void History::forward() -{ - if (movesToExecute()) - ++executed; -} - -/** Are there executed moves in the history */ -bool History::movesExecuted() -{ - return executed > 0; -} - -/** Are there moves to execute in the history */ -bool History::movesToExecute() -{ - return executed < history.size(); -} - - -/** --- class DealMove ----------------------------------------------------- **/ - -/** Constructor */ -DealMove::DealMove(Pack* s, Piles& d) : - source(s), destination(d) -{ -} - -/** Do the move */ -void DealMove::execute() -{ - source->deal(destination); -} - -/** Redo the move */ -void DealMove::takeBack() -{ - source->takeBackDeal(destination); -} - - -/** --- class NormalMove --------------------------------------------------- **/ - -/** Constructor */ -NormalMove::NormalMove(Pile* s, Pile* d, int c, bool t) : - source(s), destination(d), count(c), turn(t) -{ -} - -/** Do the move */ -void NormalMove::execute() -{ - source->moveTo(destination, count); - if (turn) - source->turn(); -} - -/** Redo the move */ -void NormalMove::takeBack() -{ - if (turn) - source->turn(); - destination->moveTo(source, count); -} - - -/** --- class FinalMove ---------------------------------------------------- **/ - -/** Constructor */ -FinalMove::FinalMove(Pile* s, FinalHeap* d, int c, bool t, bool b) : - source(s), destination(d), count(c), turn(t), bonus(b) -{ -} - -/** Do the move */ -void FinalMove::execute() -{ - source->moveTo(destination, count); - if (turn) - source->turn(); - destination->setBonus(bonus); -} - -/** Redo the move */ -void FinalMove::takeBack() -{ - destination->setBonus(false); - if (turn) - source->turn(); - destination->moveTo(source, count); -} diff --git a/history.cpp b/history.cpp new file mode 100644 index 0000000..745dc3e --- /dev/null +++ b/history.cpp @@ -0,0 +1,163 @@ +/* + * Spider-Arachnid: A plugin for the Video Disk Recorder + * + * Copyright (C) 2005-2007, Thomas Günther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * $Id: history.cpp 94 2007-09-20 23:43:48Z tom $ + */ + +#include "history.h" +#include "deck.h" +#include "heap.h" + + +/** --- class History ------------------------------------------------------ **/ + +/** Constructor */ +History::History() +{ + executed = 0; +} + +/** Destructor */ +History::~History() +{ + for (unsigned int pos = history.size(); pos > 0; --pos) + { + // Remove object created outside of History + delete history.back(); + history.pop_back(); + } +} + +/** Current move in the history */ +Move* History::current() +{ + return history[executed - 1]; +} + +/** Add a new move */ +void History::add(Move* move) +{ + for (unsigned int pos = history.size(); pos > executed; --pos) + { + // Remove object created outside of History + delete history.back(); + history.pop_back(); + } + history.push_back(move); + ++executed; +} + +/** Set previous move as current */ +void History::backward() +{ + if (movesExecuted()) + --executed; +} + +/** Set next move as current */ +void History::forward() +{ + if (movesToExecute()) + ++executed; +} + +/** Are there executed moves in the history */ +bool History::movesExecuted() +{ + return executed > 0; +} + +/** Are there moves to execute in the history */ +bool History::movesToExecute() +{ + return executed < history.size(); +} + + +/** --- class DealMove ----------------------------------------------------- **/ + +/** Constructor */ +DealMove::DealMove(Pack* s, Piles& d) : + source(s), destination(d) +{ +} + +/** Do the move */ +void DealMove::execute() +{ + source->deal(destination); +} + +/** Redo the move */ +void DealMove::takeBack() +{ + source->takeBackDeal(destination); +} + + +/** --- class NormalMove --------------------------------------------------- **/ + +/** Constructor */ +NormalMove::NormalMove(Pile* s, Pile* d, int c, bool t) : + source(s), destination(d), count(c), turn(t) +{ +} + +/** Do the move */ +void NormalMove::execute() +{ + source->moveTo(destination, count); + if (turn) + source->turn(); +} + +/** Redo the move */ +void NormalMove::takeBack() +{ + if (turn) + source->turn(); + destination->moveTo(source, count); +} + + +/** --- class FinalMove ---------------------------------------------------- **/ + +/** Constructor */ +FinalMove::FinalMove(Pile* s, FinalHeap* d, int c, bool t, bool b) : + source(s), destination(d), count(c), turn(t), bonus(b) +{ +} + +/** Do the move */ +void FinalMove::execute() +{ + source->moveTo(destination, count); + if (turn) + source->turn(); + destination->setBonus(bonus); +} + +/** Redo the move */ +void FinalMove::takeBack() +{ + destination->setBonus(false); + if (turn) + source->turn(); + destination->moveTo(source, count); +} diff --git a/i18n.c b/i18n.c deleted file mode 100644 index 3d1d5ce..0000000 --- a/i18n.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Spider-Arachnid: A plugin for the Video Disk Recorder - * - * Copyright (C) 2005-2007, Thomas Günther - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * $Id: i18n.c 87 2007-06-22 22:37:36Z tom $ - * - * - * Translations provided by: - * - * Spanish bittor from open7x0.org - * - */ - -#include "i18n.h" -#include - - -const tI18nPhrase Phrases[] = { - { "Spider Arachnid", // English - "Spider Arachnid", // Deutsch / German - "", // Slovenski / Slovenian - "", // Italiano / Italian - "", // Nederlands / Dutch - "", // Português / Portuguese - "", // Français / French - "", // Norsk / Norwegian - "", // suomi / Finnish - "", // Polski / Polish - "Spider Arachnid", // Español / Spanish - "", // ÅëëçíéêÜ / Greek - "", // Svenska / Swedish - "", // Românã / Romanian - "", // Magyar / Hungarian - "", // Català / Catalanian - "", // ÀãááÚØÙ / Russian - "", // Hrvatski / Croatian - "", // Eesti / Estonian - "", // Dansk / Danish - "", // Èesky / Czech - }, - { "Spider Arachnid - the best patience game", // English - "Spider Arachnid - die beste Patience", // Deutsch / German - "", // Slovenski / Slovenian - "", // Italiano / Italian - "", // Nederlands / Dutch - "", // Português / Portuguese - "", // Français / French - "", // Norsk / Norwegian - "", // suomi / Finnish - "", // Polski / Polish - "Spider Arachnid - mejor juego paciencia", // Español / Spanish - "", // ÅëëçíéêÜ / Greek - "", // Svenska / Swedish - "", // Românã / Romanian - "", // Magyar / Hungarian - "", // Català / Catalanian - "", // ÀãááÚØÙ / Russian - "", // Hrvatski / Croatian - "", // Eesti / Estonian - "", // Dansk / Danish - "", // Èesky / Czech - }, - { "Variation", // English - "Variante", // Deutsch / German - "", // Slovenski / Slovenian - "", // Italiano / Italian - "", // Nederlands / Dutch - "", // Português / Portuguese - "", // Français / French - "", // Norsk / Norwegian - "", // suomi / Finnish - "", // Polski / Polish - "Variación", // Español / Spanish - "", // ÅëëçíéêÜ / Greek - "", // Svenska / Swedish - "", // Românã / Romanian - "", // Magyar / Hungarian - "", // Català / Catalanian - "", // ÀãááÚØÙ / Russian - "", // Hrvatski / Croatian - "", // Eesti / Estonian - "", // Dansk / Danish - "", // Èesky / Czech - }, - { "Mini (one deck)", // English - "Mini (ein Blatt)", // Deutsch / German - "", // Slovenski / Slovenian - "", // Italiano / Italian - "", // Nederlands / Dutch - "", // Português / Portuguese - "", // Français / French - "", // Norsk / Norwegian - "", // suomi / Finnish - "", // Polski / Polish - "Mini (una baraja)", // Español / Spanish - "", // ÅëëçíéêÜ / Greek - "", // Svenska / Swedish - "", // Românã / Romanian - "", // Magyar / Hungarian - "", // Català / Catalanian - "", // ÀãááÚØÙ / Russian - "", // Hrvatski / Croatian - "", // Eesti / Estonian - "", // Dansk / Danish - "", // Èesky / Czech - }, - { "Normal", // English - "Normal", // Deutsch / German - "", // Slovenski / Slovenian - "", // Italiano / Italian - "", // Nederlands / Dutch - "", // Português / Portuguese - "", // Français / French - "", // Norsk / Norwegian - "", // suomi / Finnish - "", // Polski / Polish - "Normal", // Español / Spanish - "", // ÅëëçíéêÜ / Greek - "", // Svenska / Swedish - "", // Românã / Romanian - "", // Magyar / Hungarian - "", // Català / Catalanian - "", // ÀãááÚØÙ / Russian - "", // Hrvatski / Croatian - "", // Eesti / Estonian - "", // Dansk / Danish - "", // Èesky / Czech - }, - { "Only complete suits are allowed to remove", // English - "Nur vollständige Sätze können entfernt werden", // Deutsch / German - "", // Slovenski / Slovenian - "", // Italiano / Italian - "", // Nederlands / Dutch - "", // Português / Portuguese - "", // Français / French - "", // Norsk / Norwegian - "", // suomi / Finnish - "", // Polski / Polish - "Sólo puede eliminar los palos completos", // Español / Spanish - "", // ÅëëçíéêÜ / Greek - "", // Svenska / Swedish - "", // Românã / Romanian - "", // Magyar / Hungarian - "", // Català / Catalanian - "", // ÀãááÚØÙ / Russian - "", // Hrvatski / Croatian - "", // Eesti / Estonian - "", // Dansk / Danish - "", // Èesky / Czech - }, - { "No cards left", // English - "Keine Karten übrig", // Deutsch / German - "", // Slovenski / Slovenian - "", // Italiano / Italian - "", // Nederlands / Dutch - "", // Português / Portuguese - "", // Français / French - "", // Norsk / Norwegian - "", // suomi / Finnish - "", // Polski / Polish - "No dejó cartas", // Español / Spanish - "", // ÅëëçíéêÜ / Greek - "", // Svenska / Swedish - "", // Românã / Romanian - "", // Magyar / Hungarian - "", // Català / Catalanian - "", // ÀãááÚØÙ / Russian - "", // Hrvatski / Croatian - "", // Eesti / Estonian - "", // Dansk / Danish - "", // Èesky / Czech - }, - { "Deal not allowed with empty piles", // English - "Neue Karten nur, wenn alle Reihen belegt", // Deutsch / German - "", // Slovenski / Slovenian - "", // Italiano / Italian - "", // Nederlands / Dutch - "", // Português / Portuguese - "", // Français / French - "", // Norsk / Norwegian - "", // suomi / Finnish - "", // Polski / Polish - "Reparto no permitido con montones vacíos", // Español / Spanish - "", // ÅëëçíéêÜ / Greek - "", // Svenska / Swedish - "", // Românã / Romanian - "", // Magyar / Hungarian - "", // Català / Catalanian - "", // ÀãááÚØÙ / Russian - "", // Hrvatski / Croatian - "", // Eesti / Estonian - "", // Dansk / Danish - "", // Èesky / Czech - }, - { "Congratulations!\nPress OK to start a new game", // English - "Herzlichen Glückwunsch!\nOK startet ein neues Spiel", // Deutsch / German - "", // Slovenski / Slovenian - "", // Italiano / Italian - "", // Nederlands / Dutch - "", // Português / Portuguese - "", // Français / French - "", // Norsk / Norwegian - "", // suomi / Finnish - "", // Polski / Polish - "¡Felicidades!\nPulse OK para iniciar un nuevo juego", // Español / Spanish - "", // ÅëëçíéêÜ / Greek - "", // Svenska / Swedish - "", // Românã / Romanian - "", // Magyar / Hungarian - "", // Català / Catalanian - "", // ÀãááÚØÙ / Russian - "", // Hrvatski / Croatian - "", // Eesti / Estonian - "", // Dansk / Danish - "", // Èesky / Czech - }, - { NULL } -}; diff --git a/i18n.cpp b/i18n.cpp new file mode 100644 index 0000000..d90e538 --- /dev/null +++ b/i18n.cpp @@ -0,0 +1,233 @@ +/* + * Spider-Arachnid: A plugin for the Video Disk Recorder + * + * Copyright (C) 2005-2007, Thomas Günther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * $Id: i18n.cpp 94 2007-09-20 23:43:48Z tom $ + * + * + * Translations provided by: + * + * Spanish bittor from open7x0.org + * + */ + +#include "i18n.h" +#include + + +const tI18nPhrase Phrases[] = { + { "Spider Arachnid", // English + "Spider Arachnid", // Deutsch / German + "", // Slovenski / Slovenian + "", // Italiano / Italian + "", // Nederlands / Dutch + "", // Português / Portuguese + "", // Français / French + "", // Norsk / Norwegian + "", // suomi / Finnish + "", // Polski / Polish + "Spider Arachnid", // Español / Spanish + "", // ÅëëçíéêÜ / Greek + "", // Svenska / Swedish + "", // Românã / Romanian + "", // Magyar / Hungarian + "", // Català / Catalanian + "", // ÀãááÚØÙ / Russian + "", // Hrvatski / Croatian + "", // Eesti / Estonian + "", // Dansk / Danish + "", // Èesky / Czech + }, + { "Spider Arachnid - the best patience game", // English + "Spider Arachnid - die beste Patience", // Deutsch / German + "", // Slovenski / Slovenian + "", // Italiano / Italian + "", // Nederlands / Dutch + "", // Português / Portuguese + "", // Français / French + "", // Norsk / Norwegian + "", // suomi / Finnish + "", // Polski / Polish + "Spider Arachnid - mejor juego paciencia", // Español / Spanish + "", // ÅëëçíéêÜ / Greek + "", // Svenska / Swedish + "", // Românã / Romanian + "", // Magyar / Hungarian + "", // Català / Catalanian + "", // ÀãááÚØÙ / Russian + "", // Hrvatski / Croatian + "", // Eesti / Estonian + "", // Dansk / Danish + "", // Èesky / Czech + }, + { "Variation", // English + "Variante", // Deutsch / German + "", // Slovenski / Slovenian + "", // Italiano / Italian + "", // Nederlands / Dutch + "", // Português / Portuguese + "", // Français / French + "", // Norsk / Norwegian + "", // suomi / Finnish + "", // Polski / Polish + "Variación", // Español / Spanish + "", // ÅëëçíéêÜ / Greek + "", // Svenska / Swedish + "", // Românã / Romanian + "", // Magyar / Hungarian + "", // Català / Catalanian + "", // ÀãááÚØÙ / Russian + "", // Hrvatski / Croatian + "", // Eesti / Estonian + "", // Dansk / Danish + "", // Èesky / Czech + }, + { "Mini (one deck)", // English + "Mini (ein Blatt)", // Deutsch / German + "", // Slovenski / Slovenian + "", // Italiano / Italian + "", // Nederlands / Dutch + "", // Português / Portuguese + "", // Français / French + "", // Norsk / Norwegian + "", // suomi / Finnish + "", // Polski / Polish + "Mini (una baraja)", // Español / Spanish + "", // ÅëëçíéêÜ / Greek + "", // Svenska / Swedish + "", // Românã / Romanian + "", // Magyar / Hungarian + "", // Català / Catalanian + "", // ÀãááÚØÙ / Russian + "", // Hrvatski / Croatian + "", // Eesti / Estonian + "", // Dansk / Danish + "", // Èesky / Czech + }, + { "Normal", // English + "Normal", // Deutsch / German + "", // Slovenski / Slovenian + "", // Italiano / Italian + "", // Nederlands / Dutch + "", // Português / Portuguese + "", // Français / French + "", // Norsk / Norwegian + "", // suomi / Finnish + "", // Polski / Polish + "Normal", // Español / Spanish + "", // ÅëëçíéêÜ / Greek + "", // Svenska / Swedish + "", // Românã / Romanian + "", // Magyar / Hungarian + "", // Català / Catalanian + "", // ÀãááÚØÙ / Russian + "", // Hrvatski / Croatian + "", // Eesti / Estonian + "", // Dansk / Danish + "", // Èesky / Czech + }, + { "Only complete suits are allowed to remove", // English + "Nur vollständige Sätze können entfernt werden", // Deutsch / German + "", // Slovenski / Slovenian + "", // Italiano / Italian + "", // Nederlands / Dutch + "", // Português / Portuguese + "", // Français / French + "", // Norsk / Norwegian + "", // suomi / Finnish + "", // Polski / Polish + "Sólo puede eliminar los palos completos", // Español / Spanish + "", // ÅëëçíéêÜ / Greek + "", // Svenska / Swedish + "", // Românã / Romanian + "", // Magyar / Hungarian + "", // Català / Catalanian + "", // ÀãááÚØÙ / Russian + "", // Hrvatski / Croatian + "", // Eesti / Estonian + "", // Dansk / Danish + "", // Èesky / Czech + }, + { "No cards left", // English + "Keine Karten übrig", // Deutsch / German + "", // Slovenski / Slovenian + "", // Italiano / Italian + "", // Nederlands / Dutch + "", // Português / Portuguese + "", // Français / French + "", // Norsk / Norwegian + "", // suomi / Finnish + "", // Polski / Polish + "No dejó cartas", // Español / Spanish + "", // ÅëëçíéêÜ / Greek + "", // Svenska / Swedish + "", // Românã / Romanian + "", // Magyar / Hungarian + "", // Català / Catalanian + "", // ÀãááÚØÙ / Russian + "", // Hrvatski / Croatian + "", // Eesti / Estonian + "", // Dansk / Danish + "", // Èesky / Czech + }, + { "Deal not allowed with empty piles", // English + "Neue Karten nur, wenn alle Reihen belegt", // Deutsch / German + "", // Slovenski / Slovenian + "", // Italiano / Italian + "", // Nederlands / Dutch + "", // Português / Portuguese + "", // Français / French + "", // Norsk / Norwegian + "", // suomi / Finnish + "", // Polski / Polish + "Reparto no permitido con montones vacíos", // Español / Spanish + "", // ÅëëçíéêÜ / Greek + "", // Svenska / Swedish + "", // Românã / Romanian + "", // Magyar / Hungarian + "", // Català / Catalanian + "", // ÀãááÚØÙ / Russian + "", // Hrvatski / Croatian + "", // Eesti / Estonian + "", // Dansk / Danish + "", // Èesky / Czech + }, + { "Congratulations!\nPress OK to start a new game", // English + "Herzlichen Glückwunsch!\nOK startet ein neues Spiel", // Deutsch / German + "", // Slovenski / Slovenian + "", // Italiano / Italian + "", // Nederlands / Dutch + "", // Português / Portuguese + "", // Français / French + "", // Norsk / Norwegian + "", // suomi / Finnish + "", // Polski / Polish + "¡Felicidades!\nPulse OK para iniciar un nuevo juego", // Español / Spanish + "", // ÅëëçíéêÜ / Greek + "", // Svenska / Swedish + "", // Românã / Romanian + "", // Magyar / Hungarian + "", // Català / Catalanian + "", // ÀãááÚØÙ / Russian + "", // Hrvatski / Croatian + "", // Eesti / Estonian + "", // Dansk / Danish + "", // Èesky / Czech + }, + { NULL } +}; diff --git a/setup.c b/setup.c deleted file mode 100644 index 7255c81..0000000 --- a/setup.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Spider-Arachnid: A plugin for the Video Disk Recorder - * - * Copyright (C) 2005-2007, Thomas Günther - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * $Id: setup.c 87 2007-06-22 22:37:36Z tom $ - */ - -#include "setup.h" -#include "i18n.h" -#include - - -/** --- class SpiderSetup -------------------------------------------------- **/ - -SpiderSetup::SpiderSetup() -{ - variation = Mini; -} - -bool SpiderSetup::parse(const char* name, const char* value) -{ - if (!strcasecmp(name, "Variation")) - variation = atoi(value); - else - return false; - return true; -} - - -/** --- class SpiderSetupMenu ---------------------------------------------- **/ - -SpiderSetupMenu::SpiderSetupMenu(SpiderSetup& setup) : - setup(setup), data(setup) -{ - variationTexts[0] = tr("Mini (one deck)"); - variationTexts[1] = tr("Normal"); - Add(new cMenuEditStraItem(tr("Variation"), &data.variation, - 2, variationTexts)); -} - -void SpiderSetupMenu::Store() -{ - setup = data; - SetupStore("Variation", setup.variation); -} diff --git a/setup.cpp b/setup.cpp new file mode 100644 index 0000000..f59ca5d --- /dev/null +++ b/setup.cpp @@ -0,0 +1,60 @@ +/* + * Spider-Arachnid: A plugin for the Video Disk Recorder + * + * Copyright (C) 2005-2007, Thomas Günther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * $Id: setup.cpp 94 2007-09-20 23:43:48Z tom $ + */ + +#include "setup.h" +#include "i18n.h" +#include + + +/** --- class SpiderSetup -------------------------------------------------- **/ + +SpiderSetup::SpiderSetup() +{ + variation = Mini; +} + +bool SpiderSetup::parse(const char* name, const char* value) +{ + if (!strcasecmp(name, "Variation")) + variation = atoi(value); + else + return false; + return true; +} + + +/** --- class SpiderSetupMenu ---------------------------------------------- **/ + +SpiderSetupMenu::SpiderSetupMenu(SpiderSetup& setup) : + setup(setup), data(setup) +{ + variationTexts[0] = tr("Mini (one deck)"); + variationTexts[1] = tr("Normal"); + Add(new cMenuEditStraItem(tr("Variation"), &data.variation, + 2, variationTexts)); +} + +void SpiderSetupMenu::Store() +{ + setup = data; + SetupStore("Variation", setup.variation); +} diff --git a/spider.c b/spider.c deleted file mode 100644 index 7fe0388..0000000 --- a/spider.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Spider-Arachnid: A plugin for the Video Disk Recorder - * - * Copyright (C) 2005-2007, Thomas Günther - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * $Id: spider.c 88 2007-06-23 00:15:39Z tom $ - */ - -#include "spider.h" -#include "game.h" -#include "setup.h" -#include "i18n.h" -#include - - -static const char* VERSION = "0.1.4"; -static const char* DESCRIPTION = "Spider Arachnid - the best patience game"; -static const char* MAINMENUENTRY = "Spider Arachnid"; - - -/** --- class SpiderPlugin ------------------------------------------------- **/ - -class SpiderPlugin : public cPlugin -{ -private: - SpiderSetup setup; -public: - virtual const char* Version() { return VERSION; } - virtual const char* Description() { return tr(DESCRIPTION); } - virtual bool Start(); - virtual const char* MainMenuEntry() { return tr(MAINMENUENTRY); } - virtual cOsdObject* MainMenuAction(); - virtual cMenuSetupPage* SetupMenu(); - virtual bool SetupParse(const char* name, const char* value); -}; - -bool SpiderPlugin::Start() -{ - RegisterI18n(Phrases); - return true; -} - -cOsdObject* SpiderPlugin::MainMenuAction() -{ - return new SpiderGame(setup, ConfigDirectory(Name())); -} - -cMenuSetupPage* SpiderPlugin::SetupMenu() -{ - return new SpiderSetupMenu(setup); -} - -bool SpiderPlugin::SetupParse(const char* name, const char* value) -{ - return setup.parse(name, value); -} - -VDRPLUGINCREATOR(SpiderPlugin); // Don't touch this! diff --git a/spider.cpp b/spider.cpp new file mode 100644 index 0000000..0c8be2b --- /dev/null +++ b/spider.cpp @@ -0,0 +1,72 @@ +/* + * Spider-Arachnid: A plugin for the Video Disk Recorder + * + * Copyright (C) 2005-2007, Thomas Günther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * $Id: spider.cpp 94 2007-09-20 23:43:48Z tom $ + */ + +#include "spider.h" +#include "game.h" +#include "setup.h" +#include "i18n.h" +#include + + +static const char* VERSION = "0.1.4"; +static const char* DESCRIPTION = "Spider Arachnid - the best patience game"; +static const char* MAINMENUENTRY = "Spider Arachnid"; + + +/** --- class SpiderPlugin ------------------------------------------------- **/ + +class SpiderPlugin : public cPlugin +{ +private: + SpiderSetup setup; +public: + virtual const char* Version() { return VERSION; } + virtual const char* Description() { return tr(DESCRIPTION); } + virtual bool Start(); + virtual const char* MainMenuEntry() { return tr(MAINMENUENTRY); } + virtual cOsdObject* MainMenuAction(); + virtual cMenuSetupPage* SetupMenu(); + virtual bool SetupParse(const char* name, const char* value); +}; + +bool SpiderPlugin::Start() +{ + RegisterI18n(Phrases); + return true; +} + +cOsdObject* SpiderPlugin::MainMenuAction() +{ + return new SpiderGame(setup, ConfigDirectory(Name())); +} + +cMenuSetupPage* SpiderPlugin::SetupMenu() +{ + return new SpiderSetupMenu(setup); +} + +bool SpiderPlugin::SetupParse(const char* name, const char* value) +{ + return setup.parse(name, value); +} + +VDRPLUGINCREATOR(SpiderPlugin); // Don't touch this! diff --git a/tableau.c b/tableau.c deleted file mode 100644 index 70744bd..0000000 --- a/tableau.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Spider-Arachnid: A plugin for the Video Disk Recorder - * - * Copyright (C) 2005-2007, Thomas Günther - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * $Id: tableau.c 87 2007-06-22 22:37:36Z tom $ - */ - -#include "tableau.h" -#include "deck.h" -#include "heap.h" -#include "history.h" - - -/** --- class Tableau ------------------------------------------------------ **/ - -/** Constructor */ -Tableau::Tableau(Deck& deck, int pileCount, int finalCount, int deals) : - dealCount(deals), deck(deck), piles(pileCount), finals(finalCount) -{ - cardsToOpen = deck.count() - (deals + 1) * pileCount; - for ( ; cardsToOpen < 0; cardsToOpen += pileCount) - --deals; - - pack = new Pack(deck); - for (unsigned int p = 0; p < piles.size(); ++p) - piles[p] = new Pile(deck); - for (unsigned int f = 0; f < finals.size(); ++f) - finals[f] = new FinalHeap(deck); - - history = new History(); - - // choice of piles for extra deal with remaining cards - Piles extra(cardsToOpen % pileCount); - if (!extra.empty()) - { - int extraMax = extra.size() - 1; - int pilesMax = piles.size() - 1; - for (int e = 0; e <= extraMax / 2; ++e) - { - int p = (e * pilesMax) / extraMax; - extra[e] = piles[p]; - extra[extraMax - e] = piles[pilesMax - p]; - } - } - - // deal cards to open - pack->initialDeal(piles, cardsToOpen / pileCount, extra); - - // deal one open row - pack->deal(piles); - - selected = 0; -} - -/** Destructor */ -Tableau::~Tableau() -{ - delete pack; - for (unsigned int p = 0; p < piles.size(); ++p) - delete piles[p]; - for (unsigned int f = 0; f < finals.size(); ++f) - delete finals[f]; - delete history; -} - -/** Current count of deals */ -int Tableau::deals() -{ - return dealCount - pack->count() / piles.size(); -} - -/** Current count of points */ -int Tableau::points() -{ - int openCard = 10; - int openPile = 15; - int matchingCard = 2; - int readyFinal = 50; - int bonusFinal = 2; - int bonusfreeFinals = 3; - - int points = openCard * cardsToOpen; - for (unsigned int p = 0; p < piles.size(); ++p) - { - if (piles[p]->count() > piles[p]->open()) - points -= openCard * (piles[p]->count() - piles[p]->open()); - else - points += openPile; - points += matchingCard * piles[p]->getMatching(); - } - int emptyFinals = 0; - int bonusFinals = 0; - for (unsigned int f = 0; f < finals.size(); ++f) - if (finals[f]->empty()) - ++emptyFinals; - else if (finals[f]->getBonus()) - ++bonusFinals; - points += readyFinal * (finals.size() - emptyFinals); - if (emptyFinals == 0 && bonusFinals > bonusfreeFinals) - points += bonusFinal * (bonusFinals - bonusfreeFinals); - return points; -} - -/** Is no pile empty? */ -bool Tableau::noPileEmpty() -{ - for (unsigned int p = 0; p < piles.size(); p++) - if (piles[p]->empty()) - return false; - return true; -} - -/** Matches all cards in all piles? */ -bool Tableau::allCardsMatches() -{ - for (unsigned int p = 0; p < piles.size(); ++p) - if (piles[p]->count() > piles[p]->open() || - piles[p]->count() > piles[p]->getMatching() * - deck.cardsInSuit / (deck.cardsInSuit - 1)) - return false; - return true; -} - -/** Is the game over? */ -bool Tableau::gameOver() -{ - for (unsigned int p = 0; p < piles.size(); p++) - if (!piles[p]->empty()) - return false; - return true; -} - -/** Select p-th pile by selecting up to max matching cards on its end */ -void Tableau::select(int p, int max) -{ - if (!piles[p]->empty()) - { - unselect(); - selected = piles[p]; - selected->select(max); - changed = true; - } -} - -/** Unselect the selected pile */ -void Tableau::unselect() -{ - if (selected) - { - selected->unselect(); - selected = 0; - } -} - -/** Move cards from selected pile to p-th pile */ -void Tableau::move(int p) -{ - selected->adaptSelectionTo(piles[p]); - int count = selected->selected(); - if (count > 0) - { - bool turn = (count == selected->open() && count < selected->count()); - history->add(new NormalMove(selected, piles[p], count, turn)); - history->current()->execute(); - } - unselect(); - changed = true; -} - -/** Search move from p-th pile to the next left pile, return destination */ -int Tableau::autoMoveLeft(int p) -{ - int i = -1; - if (!piles[p]->empty()) - { - if (selected != piles[p]) - select(p); - for (i = p - 1; i >= 0; --i) - if (piles[i]->empty() || selected->selectionMatchesTo(piles[i])) - break; - if (i >= 0) - move(i); - changed = true; - } - return i; -} - -/** Search move from p-th pile to the next right pile, return destination */ -int Tableau::autoMoveRight(int p) -{ - int i = -1; - if (!piles[p]->empty()) - { - if (selected != piles[p]) - select(p); - for (i = p + 1; i < (int)piles.size(); ++i) - if (piles[i]->empty() || selected->selectionMatchesTo(piles[i])) - break; - if (i < (int)piles.size()) - move(i); - else - i = -1; - changed = true; - } - return i; -} - -/** Search best move from p-th pile, return destination */ -int Tableau::autoMove(int p) -{ - int i = -1; - if (!piles[p]->empty()) - { - if (selected != piles[p]) - select(p); - if (allCardsMatches() && selected->selected() == deck.cardsInSuit) - remove(); - else - { - i = p; - while ((i = (i + 1) % piles.size()) != p) - if (selected->selectionMatchesTo(piles[i], true)) - break; - if (i == p) - while ((i = (i + 1) % piles.size()) != p) - if (selected->selectionMatchesTo(piles[i], false)) - break; - if (i == p) - while ((i = (i + 1) % piles.size()) != p) - if (piles[i]->empty()) - break; - if (i != p) - move(i); - else - i = -1; - } - } - return i; -} - -/** Deal one row */ -void Tableau::deal() -{ - if (!pack->empty() && noPileEmpty()) - { - history->add(new DealMove(pack, piles)); - history->current()->execute(); - - unselect(); - changed = true; - } -} - -/** Remove one suit of cards from selected pile to the final heaps */ -void Tableau::remove() -{ - int count = selected->selected(); - if (count == deck.cardsInSuit) - { - unsigned int f; - for (f = 0; f < finals.size(); ++f) - if (finals[f]->empty()) - break; - if (f < finals.size()) - { - bool turn = (count == selected->open() && count < selected->count()); - bool bonus = allCardsMatches(); - history->add(new FinalMove(selected, finals[f], count, turn, bonus)); - history->current()->execute(); - } - unselect(); - changed = true; - } -} - -/** Go one move backward in the history */ -void Tableau::backward() -{ - if (history->movesExecuted()) - { - history->current()->takeBack(); - history->backward(); - - unselect(); - changed = true; - } -} - -/** Go one move forward in the history */ -void Tableau::forward() -{ - if (history->movesToExecute()) - { - history->forward(); - history->current()->execute(); - - unselect(); - changed = true; - } -} diff --git a/tableau.cpp b/tableau.cpp new file mode 100644 index 0000000..a53f4d8 --- /dev/null +++ b/tableau.cpp @@ -0,0 +1,315 @@ +/* + * Spider-Arachnid: A plugin for the Video Disk Recorder + * + * Copyright (C) 2005-2007, Thomas Günther + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * $Id: tableau.cpp 94 2007-09-20 23:43:48Z tom $ + */ + +#include "tableau.h" +#include "deck.h" +#include "heap.h" +#include "history.h" + + +/** --- class Tableau ------------------------------------------------------ **/ + +/** Constructor */ +Tableau::Tableau(Deck& deck, int pileCount, int finalCount, int deals) : + dealCount(deals), deck(deck), piles(pileCount), finals(finalCount) +{ + cardsToOpen = deck.count() - (deals + 1) * pileCount; + for ( ; cardsToOpen < 0; cardsToOpen += pileCount) + --deals; + + pack = new Pack(deck); + for (unsigned int p = 0; p < piles.size(); ++p) + piles[p] = new Pile(deck); + for (unsigned int f = 0; f < finals.size(); ++f) + finals[f] = new FinalHeap(deck); + + history = new History(); + + // choice of piles for extra deal with remaining cards + Piles extra(cardsToOpen % pileCount); + if (!extra.empty()) + { + int extraMax = extra.size() - 1; + int pilesMax = piles.size() - 1; + for (int e = 0; e <= extraMax / 2; ++e) + { + int p = (e * pilesMax) / extraMax; + extra[e] = piles[p]; + extra[extraMax - e] = piles[pilesMax - p]; + } + } + + // deal cards to open + pack->initialDeal(piles, cardsToOpen / pileCount, extra); + + // deal one open row + pack->deal(piles); + + selected = 0; +} + +/** Destructor */ +Tableau::~Tableau() +{ + delete pack; + for (unsigned int p = 0; p < piles.size(); ++p) + delete piles[p]; + for (unsigned int f = 0; f < finals.size(); ++f) + delete finals[f]; + delete history; +} + +/** Current count of deals */ +int Tableau::deals() +{ + return dealCount - pack->count() / piles.size(); +} + +/** Current count of points */ +int Tableau::points() +{ + int openCard = 10; + int openPile = 15; + int matchingCard = 2; + int readyFinal = 50; + int bonusFinal = 2; + int bonusfreeFinals = 3; + + int points = openCard * cardsToOpen; + for (unsigned int p = 0; p < piles.size(); ++p) + { + if (piles[p]->count() > piles[p]->open()) + points -= openCard * (piles[p]->count() - piles[p]->open()); + else + points += openPile; + points += matchingCard * piles[p]->getMatching(); + } + int emptyFinals = 0; + int bonusFinals = 0; + for (unsigned int f = 0; f < finals.size(); ++f) + if (finals[f]->empty()) + ++emptyFinals; + else if (finals[f]->getBonus()) + ++bonusFinals; + points += readyFinal * (finals.size() - emptyFinals); + if (emptyFinals == 0 && bonusFinals > bonusfreeFinals) + points += bonusFinal * (bonusFinals - bonusfreeFinals); + return points; +} + +/** Is no pile empty? */ +bool Tableau::noPileEmpty() +{ + for (unsigned int p = 0; p < piles.size(); p++) + if (piles[p]->empty()) + return false; + return true; +} + +/** Matches all cards in all piles? */ +bool Tableau::allCardsMatches() +{ + for (unsigned int p = 0; p < piles.size(); ++p) + if (piles[p]->count() > piles[p]->open() || + piles[p]->count() > piles[p]->getMatching() * + deck.cardsInSuit / (deck.cardsInSuit - 1)) + return false; + return true; +} + +/** Is the game over? */ +bool Tableau::gameOver() +{ + for (unsigned int p = 0; p < piles.size(); p++) + if (!piles[p]->empty()) + return false; + return true; +} + +/** Select p-th pile by selecting up to max matching cards on its end */ +void Tableau::select(int p, int max) +{ + if (!piles[p]->empty()) + { + unselect(); + selected = piles[p]; + selected->select(max); + changed = true; + } +} + +/** Unselect the selected pile */ +void Tableau::unselect() +{ + if (selected) + { + selected->unselect(); + selected = 0; + } +} + +/** Move cards from selected pile to p-th pile */ +void Tableau::move(int p) +{ + selected->adaptSelectionTo(piles[p]); + int count = selected->selected(); + if (count > 0) + { + bool turn = (count == selected->open() && count < selected->count()); + history->add(new NormalMove(selected, piles[p], count, turn)); + history->current()->execute(); + } + unselect(); + changed = true; +} + +/** Search move from p-th pile to the next left pile, return destination */ +int Tableau::autoMoveLeft(int p) +{ + int i = -1; + if (!piles[p]->empty()) + { + if (selected != piles[p]) + select(p); + for (i = p - 1; i >= 0; --i) + if (piles[i]->empty() || selected->selectionMatchesTo(piles[i])) + break; + if (i >= 0) + move(i); + changed = true; + } + return i; +} + +/** Search move from p-th pile to the next right pile, return destination */ +int Tableau::autoMoveRight(int p) +{ + int i = -1; + if (!piles[p]->empty()) + { + if (selected != piles[p]) + select(p); + for (i = p + 1; i < (int)piles.size(); ++i) + if (piles[i]->empty() || selected->selectionMatchesTo(piles[i])) + break; + if (i < (int)piles.size()) + move(i); + else + i = -1; + changed = true; + } + return i; +} + +/** Search best move from p-th pile, return destination */ +int Tableau::autoMove(int p) +{ + int i = -1; + if (!piles[p]->empty()) + { + if (selected != piles[p]) + select(p); + if (allCardsMatches() && selected->selected() == deck.cardsInSuit) + remove(); + else + { + i = p; + while ((i = (i + 1) % piles.size()) != p) + if (selected->selectionMatchesTo(piles[i], true)) + break; + if (i == p) + while ((i = (i + 1) % piles.size()) != p) + if (selected->selectionMatchesTo(piles[i], false)) + break; + if (i == p) + while ((i = (i + 1) % piles.size()) != p) + if (piles[i]->empty()) + break; + if (i != p) + move(i); + else + i = -1; + } + } + return i; +} + +/** Deal one row */ +void Tableau::deal() +{ + if (!pack->empty() && noPileEmpty()) + { + history->add(new DealMove(pack, piles)); + history->current()->execute(); + + unselect(); + changed = true; + } +} + +/** Remove one suit of cards from selected pile to the final heaps */ +void Tableau::remove() +{ + int count = selected->selected(); + if (count == deck.cardsInSuit) + { + unsigned int f; + for (f = 0; f < finals.size(); ++f) + if (finals[f]->empty()) + break; + if (f < finals.size()) + { + bool turn = (count == selected->open() && count < selected->count()); + bool bonus = allCardsMatches(); + history->add(new FinalMove(selected, finals[f], count, turn, bonus)); + history->current()->execute(); + } + unselect(); + changed = true; + } +} + +/** Go one move backward in the history */ +void Tableau::backward() +{ + if (history->movesExecuted()) + { + history->current()->takeBack(); + history->backward(); + + unselect(); + changed = true; + } +} + +/** Go one move forward in the history */ +void Tableau::forward() +{ + if (history->movesToExecute()) + { + history->forward(); + history->current()->execute(); + + unselect(); + changed = true; + } +} -- cgit v1.2.3