Ticket #5615: pairs-multiple-board-sizes.diff

File pairs-multiple-board-sizes.diff, 14.9 KB (added by adams, 14 years ago)

Patch to add support for variable board sizes

  • src/apps/pairs/Pairs.cpp

     
    11/*
    2  * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com. All rights reserved.
     2 * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com.
     3 * All rights reserved.
    34 * Distributed under the terms of the MIT License.
    45 */
    56
     
    1617
    1718
    1819Pairs::Pairs()
    19     : BApplication(kSignature),
    20       fWindow(NULL)
     20    :
     21    BApplication(kSignature),
     22    fWindow(NULL)
    2123{
    2224    be_locale->GetAppCatalog(&fCatalog);
    2325}
  • src/apps/pairs/PairsView.h

     
    11/*
    2  * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com. All rights reserved.
     2 * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com.
     3 * All rights reserved.
    34 * Distributed under the terms of the MIT License.
    45 */
    56
     
    1516class PairsView : public BView {
    1617public:
    1718                                PairsView(BRect frame, const char* name,
     19                                    int width, int height,
    1820                                    uint32 resizingMode);
    1921
    2022    virtual                     ~PairsView();
    2123    virtual void                AttachedToWindow();
    2224    virtual void                Draw(BRect updateRect);
    2325    virtual void                CreateGameBoard();
     26   
     27            int                 fWidth;
     28            int                 fHeight;
     29            int                 fNumOfCards;
    2430
    25             TopButton*          fDeckCard[16];
     31            BList               fDeckCard;
    2632            int                 GetIconFromPos(int pos);
    2733
    2834private:
     
    3238            bool                _HasBitmap(BList& bitmaps, BBitmap* bitmap);
    3339
    3440            BMessage*           fButtonMessage;
    35             BBitmap*            fCard[8];
    36             int                 fRandPos[16];
    37             int                 fPosX[16];
    38             int                 fPosY[16];
     41            BList               fCardBitmaps;
     42            int*                fRandPos;
     43            int*                fPosX;
     44            int*                fPosY;
    3945};
    4046
    4147
  • src/apps/pairs/PairsTopButton.h

     
    11/*
    2  * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com. All rights reserved.
     2 * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com.
     3 * All rights reserved.
    34 * Distributed under the terms of the MIT License.
    45 */
    56
  • src/apps/pairs/Pairs.h

     
    11/*
    2  * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com. All rights reserved.
     2 * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com.
     3 * All rights reserved.
    34 * Distributed under the terms of the MIT License.
    45 */
    56
  • src/apps/pairs/PairsGlobal.h

     
    11/*
    2  * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com. All rights reserved.
     2 * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com.
     3 * All rights reserved.
    34 * Distributed under the terms of the MIT License.
    45 */
    56
     
    1213const uint32 kMsgCardButton = 'card';
    1314const uint32 kMsgPairComparing = 'pcom';
    1415const int kBitmapSize = 64;
     16const int kSpaceSize = 10;
    1517
    1618
    1719#endif // PAIRS_GLOBAL_H
  • src/apps/pairs/PairsWindow.cpp

     
    11/*
    2  * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com. All rights reserved.
     2 * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com.
     3 * All rights reserved.
    34 * Distributed under the terms of the MIT License.
    45 */
    56
     
    1213#include <Button.h>
    1314#include <Catalog.h>
    1415#include <Locale.h>
     16#include <Menu.h>
     17#include <MenuBar.h>
     18#include <MenuItem.h>
    1519#include <MessageRunner.h>
    1620#include <String.h>
    1721#include <TextView.h>
     
    2529#undef TR_CONTEXT
    2630#define TR_CONTEXT "PairsWindow"
    2731
     32const uint32 MENU_NEW                   = 'MGnw';
     33const uint32 MENU_SIZE                  = 'MGsz';
     34const uint32 MENU_QUIT                  = 'MGqu';
     35
    2836PairsWindow::PairsWindow()
    29     : BWindow(BRect(100, 100, 405, 405), "Pairs", B_TITLED_WINDOW,
     37    : BWindow(BRect(100, 100, 405, 423), "Pairs", B_TITLED_WINDOW,
    3038        B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE
    3139            | B_NOT_RESIZABLE | B_NOT_ZOOMABLE),
    32       fPairComparing(NULL),
    33       fIsFirstClick(true),
    34       fIsPairsActive(true),
    35       fPairCard(0),
    36       fPairCardTmp(0),
    37       fButtonTmp(0),
    38       fButton(0),
    39       fButtonClicks(0),
    40       fFinishPairs(0)
     40    fPairComparing(NULL),
     41    fIsFirstClick(true),
     42    fIsPairsActive(true),
     43    fPairCard(0),
     44    fPairCardTmp(0),
     45    fButtonTmp(0),
     46    fButton(0),
     47    fButtonClicks(0),
     48    fFinishPairs(0)
    4149{
    42     fPairsView = new PairsView(Bounds().InsetByCopy(0, 0).OffsetToSelf(0, 0),
    43         "PairsView", B_FOLLOW_NONE);
    44     fPairsView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
    45     AddChild(fPairsView);
     50    _MakeMenuBar();
     51       
     52    _MakeGameView(4, 4);   
    4653
    4754    CenterOnScreen();
    4855}
     
    5562
    5663
    5764void
     65PairsWindow::_MakeMenuBar()
     66{
     67    fMenuBar = new BMenuBar(BRect(0, 0, 0, 0), "menubar");
     68    AddChild(fMenuBar);
     69   
     70    BMenu* menu = new BMenu(TR("Game"));
     71    fMenuBar->AddItem(menu);
     72   
     73    BMenuItem* menuItem;
     74    menu->AddItem(menuItem = new BMenuItem(TR("New"),
     75        new BMessage(MENU_NEW), 'N'));
     76   
     77    menu->AddSeparatorItem();
     78   
     79    BMenu* sizeMenu = new BMenu(TR("Size"));
     80    sizeMenu->SetRadioMode(true);
     81   
     82    BMessage* sizeMessage = new BMessage(MENU_SIZE);
     83    sizeMessage->AddInt32("width",4);
     84    sizeMessage->AddInt32("height",4);
     85    sizeMenu->AddItem(menuItem = new BMenuItem(TR("Beginner (4x4)"),
     86        sizeMessage));
     87    menuItem->SetMarked(true);
     88   
     89    sizeMessage = new BMessage(MENU_SIZE);
     90    sizeMessage->AddInt32("width",6);
     91    sizeMessage->AddInt32("height",6);
     92    sizeMenu->AddItem(menuItem = new BMenuItem(TR("Intermediate (6x6)"),
     93        sizeMessage));
     94       
     95    sizeMessage = new BMessage(MENU_SIZE);
     96    sizeMessage->AddInt32("width",8);
     97    sizeMessage->AddInt32("height",8);
     98    sizeMenu->AddItem(menuItem = new BMenuItem(TR("Expert (8x8)"),
     99        sizeMessage));
     100   
     101    menu->AddItem(sizeMenu);
     102   
     103    menu->AddSeparatorItem();
     104   
     105    menu->AddItem(menuItem = new BMenuItem(TR("Quit"),
     106        new BMessage(MENU_QUIT), 'Q'));
     107}
     108
     109
     110void
     111PairsWindow::_MakeGameView(int width, int height)
     112{
     113    BRect viewBounds = Bounds();
     114    viewBounds.top = fMenuBar->Bounds().Height() + 1;
     115       
     116    fPairsView = new PairsView(viewBounds, "PairsView", width, height,
     117        B_FOLLOW_NONE);
     118    fPairsView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
     119    AddChild(fPairsView);
     120}
     121
     122
     123void
     124PairsWindow::NewGame()
     125{
     126    fButtonClicks = 0;
     127    fFinishPairs = 0;
     128    fPairsView->CreateGameBoard();
     129}
     130
     131
     132void
     133PairsWindow::SetGameSize(int width, int height) {
     134    ResizeTo((kBitmapSize + kSpaceSize) * width + kSpaceSize,
     135        (kBitmapSize + kSpaceSize) * height + kSpaceSize
     136        + fMenuBar->Bounds().Height());
     137    RemoveChild(fPairsView);
     138    delete fPairsView;
     139    _MakeGameView(width, height);
     140    NewGame();
     141}
     142
     143
     144void
    58145PairsWindow::MessageReceived(BMessage* message)
    59 {
     146{   
    60147    switch (message->what) {
     148        case MENU_NEW:         
     149            NewGame();
     150            break;
     151        case MENU_SIZE:
     152            int32 width;
     153            int32 height;
     154            message->FindInt32("width", &width);
     155            message->FindInt32("height", &height);
     156            SetGameSize(width, height);
     157            break;
     158        case MENU_QUIT:
     159            be_app->PostMessage(B_QUIT_REQUESTED);
     160            break;
    61161        case kMsgCardButton:
    62162            if (fIsPairsActive) {
    63163                fButtonClicks++;
     
    66166                if (message->FindInt32("ButtonNum", &num) < B_OK)
    67167                    break;
    68168
    69                 // look what Icon is behind a button
    70                 for (int h = 0; h < 16; h++) {
     169                // look what Icon is behind a button               
     170                for (int h = 0; h < fPairsView->fNumOfCards; h++) {
    71171                    if (fPairsView->GetIconFromPos(h) == num) {
    72                         fPairCard = (h % 8);
     172                        fPairCard = (h % fPairsView->fNumOfCards / 2);
    73173                        fButton = fPairsView->GetIconFromPos(h);
    74174                        break;
    75175                    }
    76176                }
    77177
    78178                // gameplay
    79                 fPairsView->fDeckCard[fButton]->Hide();
     179                ((TopButton*)fPairsView->fDeckCard.ItemAt(fButton))->Hide();
    80180
    81181                if (fIsFirstClick) {
    82182                    fPairCardTmp = fPairCard;
     
    104204
    105205                if (fPairCard == fPairCardTmp) {
    106206                    fFinishPairs++;
    107                 } else {
    108                     fPairsView->fDeckCard[fButton]->Show();
    109                     fPairsView->fDeckCard[fButtonTmp]->Show();
     207                } else {                   
     208                    ((TopButton*)fPairsView->fDeckCard.ItemAt(fButton))->Show();
     209                    ((TopButton*)fPairsView->fDeckCard.ItemAt(fButtonTmp))->Show();
    110210                }
    111211
    112212                // game end and results
    113                 if (fFinishPairs == 8) {
     213                if (fFinishPairs == fPairsView->fNumOfCards / 2) {
    114214                    BString strAbout;
    115215                    strAbout
    116216                        << "Pairs\n"
     
    136236
    137237                    if (alert->Go() == 0) {
    138238                        // New game
    139                         fButtonClicks = 0;
    140                         fFinishPairs = 0;
    141                         fPairsView->CreateGameBoard();
     239                        NewGame();                     
    142240                    } else {
    143241                        // Quit game
    144242                        be_app->PostMessage(B_QUIT_REQUESTED);
  • src/apps/pairs/PairsView.cpp

     
    11/*
    2  * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com. All rights reserved.
     2 * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com.
     3 * All rights reserved.
    34 * Distributed under the terms of the MIT License.
    45 */
    56
     
    2627#include "PairsGlobal.h"
    2728#include "PairsTopButton.h"
    2829
    29 // TODO: support custom board sizes
    30 
    31 PairsView::PairsView(BRect frame, const char* name, uint32 resizingMode)
    32     : BView(frame, name, resizingMode, B_WILL_DRAW)
     30PairsView::PairsView(BRect frame, const char* name,
     31                        int width, int height,
     32                        uint32 resizingMode)
     33    :
     34    BView(frame, name, resizingMode, B_WILL_DRAW),
     35    fWidth(width),
     36    fHeight(height),
     37    fNumOfCards(width * height),
     38    fRandPos(new int[fNumOfCards]),
     39    fPosX(new int[fNumOfCards]),
     40    fPosY(new int[fNumOfCards])
    3341{
    34     // init bitmap pointers
    35     for (int i = 0; i < 8; i++)
    36         fCard[i] = NULL;
    37 
    3842    CreateGameBoard();
    3943    _SetPairsBoard();
    4044}
     
    5559
    5660PairsView::~PairsView()
    5761{
    58     for (int i = 0; i < 8; i++)
    59         delete fCard[i];
     62    for (int i = 0; i < fCardBitmaps.CountItems(); i++)
     63        delete ((BBitmap*)fCardBitmaps.ItemAt(i));
    6064
    61     for (int i = 0; i < 16; i++)
    62         delete fDeckCard[i];
     65    for (int i = 0; i < fDeckCard.CountItems(); i++)
     66        delete ((TopButton*)fDeckCard.ItemAt(i));
     67       
     68        delete fRandPos;
     69        delete fPosX;
     70        delete fPosY;
    6371}
    6472
    6573
     
    9199    // TODO: maybe read the icons only once at startup
    92100
    93101    // clean out any previous icons
    94     for (int i = 0; i < 8; i++) {
    95         delete fCard[i];
    96         fCard[i] = NULL;
     102    for (int i = 0; i < fCardBitmaps.CountItems(); i++) {
     103        delete ((BBitmap*)fCardBitmaps.ItemAt(i));
    97104    }
     105    fCardBitmaps.MakeEmpty();
    98106
    99107    BDirectory appsDirectory;
    100108    BDirectory prefsDirectory;
     
    152160    // pick eight random bitmaps from the ones we got in the list
    153161    srand((unsigned)time(0));
    154162
    155     for (int i = 0; i < 8; i++) {
     163    for (int i = 0; i < fNumOfCards / 2; i++) {
    156164        int32 index = rand() % bitmaps.CountItems();
    157         fCard[i] = (BBitmap*)bitmaps.RemoveItem(index);
    158         if (fCard[i] == NULL) {
    159             BAlert* alert = new BAlert("fatal", "Pairs did not find enough "
    160                 "vector icons in the system, it needs at least eight.",
     165        BBitmap* bitmap = ((BBitmap*)bitmaps.RemoveItem(index));       
     166        if (bitmap == NULL) {
     167            BString strErr;
     168            strErr
     169                << "Pairs did not find enough vector icons in the system; it "
     170                << "needs at least " << fNumOfCards / 2;
     171            BAlert* alert = new BAlert("fatal", strErr,
    161172                "OK", NULL, NULL, B_WIDTH_FROM_WIDEST, B_STOP_ALERT);
    162173            alert->Go();
    163174            exit(1);
    164175        }
     176        fCardBitmaps.AddItem(bitmap);
    165177    }
    166178
    167179    // delete the remaining bitmaps from the list
     
    173185void
    174186PairsView::_SetPairsBoard()
    175187{
    176     for (int i = 0; i < 16; i++) {
     188    for (int i = 0; i < fNumOfCards; i++) {
    177189        fButtonMessage = new BMessage(kMsgCardButton);
    178190        fButtonMessage->AddInt32("ButtonNum", i);
    179191
    180         int x =  i % 4 * (kBitmapSize + 10) + 10;
    181         int y =  i / 4 * (kBitmapSize + 10) + 10;
    182 
    183         fDeckCard[i] = new TopButton(x, y, fButtonMessage);
    184         AddChild(fDeckCard[i]);
     192        int x =  i % fWidth * (kBitmapSize + kSpaceSize) + kSpaceSize;
     193        int y =  i / fHeight * (kBitmapSize + kSpaceSize) + kSpaceSize;
     194       
     195        TopButton* button = new TopButton(x, y, fButtonMessage);
     196        fDeckCard.AddItem(button);     
     197        AddChild(button);
    185198    }
    186199}
    187200
     
    191204{
    192205    _ReadRandomIcons();
    193206
    194     srand((unsigned)time(0));
     207    srand((unsigned)time(0));   
    195208
    196     int positions[16];
    197     for (int i = 0; i < 16; i++)
     209    int* positions = new int[fNumOfCards];
     210    for (int i = 0; i < fNumOfCards; i++)
    198211        positions[i] = i;
    199212
    200     for (int i = 16; i >= 1; i--) {
     213    for (int i = fNumOfCards; i >= 1; i--) {
    201214        int index = rand() % i;
    202215
    203         fRandPos[16-i] = positions[index];
     216        fRandPos[fNumOfCards - i] = positions[index];
    204217
    205218        for (int j = index; j < i - 1; j++)
    206219            positions[j] = positions[j + 1];
    207220    }
    208221
    209     for (int i = 0; i < 16; i++) {
    210         fPosX[i] = (fRandPos[i]) % 4 * (kBitmapSize + 10) + 10;
    211         fPosY[i] = (fRandPos[i]) / 4 * (kBitmapSize + 10) + 10;
     222    for (int i = 0; i < fNumOfCards; i++) {
     223        fPosX[i] = (fRandPos[i]) % fWidth * (kBitmapSize + kSpaceSize)
     224            + kSpaceSize;
     225        fPosY[i] = (fRandPos[i]) / fHeight * (kBitmapSize + kSpaceSize)
     226            + kSpaceSize;
    212227    }
     228   
     229    delete [] positions;
    213230}
    214231
    215232
     
    219236    SetDrawingMode(B_OP_ALPHA);
    220237
    221238    // draw rand pair 1 & 2
    222     for (int i = 0; i < 16; i++)
    223         DrawBitmap(fCard[i % 8], BPoint(fPosX[i], fPosY[i]));
     239    for (int i = 0; i < fNumOfCards; i++) {
     240        BBitmap* bitmap = ((BBitmap*)fCardBitmaps.ItemAt(i % fNumOfCards / 2));
     241        DrawBitmap(bitmap, BPoint(fPosX[i], fPosY[i]));
     242    }
    224243}
    225244
    226245
  • src/apps/pairs/PairsWindow.h

     
    11/*
    2  * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com. All rights reserved.
     2 * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com.
     3 * All rights reserved.
    34 * Distributed under the terms of the MIT License.
    45 */
    56
     
    1819        virtual                 ~PairsWindow();
    1920
    2021        virtual void            MessageReceived(BMessage* message);
     22       
     23        void                    NewGame();
     24        void                    SetGameSize(int width, int height);
    2125
    2226private:
     27                void            _MakeGameView(int width, int height);
     28                void            _MakeMenuBar();
     29
    2330                BView*          fBackgroundView;
    2431                PairsView*      fPairsView;
     32                BMenuBar*       fMenuBar;
    2533                BMessageRunner* fPairComparing;
    2634                bool            fIsFirstClick;
    2735                bool            fIsPairsActive;
  • src/apps/pairs/PairsTopButton.cpp

     
    11/*
    2  * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com. All rights reserved.
     2 * Copyright 2008 Ralf Schülke, ralf.schuelke@googlemail.com.
     3 * All rights reserved.
    34 * Distributed under the terms of the MIT License.
    45 */
    56