Patch by Adam Smith. Extended the Pairs application to support arbitrary board

sizes. Thanks a lot! Fixes ticket #5615.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36032 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2010-04-05 10:46:08 +00:00
parent 523f15a901
commit 4c587ade77
9 changed files with 230 additions and 92 deletions
+5 -4
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright 2008 Ralf Schülke, [email protected]. All rights reserved. * Copyright 2008 Ralf Schülke, [email protected].
* Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
#include <stdlib.h> #include <stdlib.h>
@@ -16,8 +16,9 @@ const char* kSignature = "application/x-vnd.Haiku-Pairs";
Pairs::Pairs() Pairs::Pairs()
: BApplication(kSignature), :
fWindow(NULL) BApplication(kSignature),
fWindow(NULL)
{ {
be_locale->GetAppCatalog(&fCatalog); be_locale->GetAppCatalog(&fCatalog);
} }
+3 -4
View File
@@ -1,8 +1,7 @@
/* /*
* Copyright 2008 Ralf Schülke, [email protected]. All rights reserved. * Copyright 2008 Ralf Schülke, [email protected].
* Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
#ifndef PAIRS_H #ifndef PAIRS_H
#define PAIRS_H #define PAIRS_H
@@ -18,7 +17,7 @@ class Pairs : public BApplication {
public: public:
Pairs(); Pairs();
virtual ~Pairs(); virtual ~Pairs();
virtual void ReadyToRun(); virtual void ReadyToRun();
virtual void RefsReceived(BMessage* message); virtual void RefsReceived(BMessage* message);
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
+3 -2
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright 2008 Ralf Schülke, [email protected]. All rights reserved. * Copyright 2008 Ralf Schülke, [email protected].
* Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
#ifndef PAIRS_GLOBAL_H #ifndef PAIRS_GLOBAL_H
@@ -12,6 +12,7 @@
const uint32 kMsgCardButton = 'card'; const uint32 kMsgCardButton = 'card';
const uint32 kMsgPairComparing = 'pcom'; const uint32 kMsgPairComparing = 'pcom';
const int kBitmapSize = 64; const int kBitmapSize = 64;
const int kSpaceSize = 10;
#endif // PAIRS_GLOBAL_H #endif // PAIRS_GLOBAL_H
+2 -1
View File
@@ -1,5 +1,6 @@
/* /*
* Copyright 2008 Ralf Schülke, [email protected]. All rights reserved. * Copyright 2008 Ralf Schülke, [email protected].
* All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
+3 -4
View File
@@ -1,12 +1,11 @@
/* /*
* Copyright 2008 Ralf Schülke, [email protected]. All rights reserved. * Copyright 2008 Ralf Schülke, [email protected].
* Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
#ifndef PAIRS_TOP_BUTTON_H #ifndef PAIRS_TOP_BUTTON_H
#define PAIRS_TOP_BUTTON_H #define PAIRS_TOP_BUTTON_H
#include <OS.h> #include <OS.h>
class BButton; class BButton;
+56 -38
View File
@@ -1,6 +1,7 @@
/* /*
* Copyright 2008 Ralf Schülke, [email protected]. All rights reserved. * Copyright 2008 Ralf Schülke, [email protected].
* Distributed under the terms of the MIT License. * Copyright 2010 Adam Smith <[email protected]>
* All rights reserved. Distributed under the terms of the MIT License.
*/ */
#include "PairsView.h" #include "PairsView.h"
@@ -26,15 +27,17 @@
#include "PairsGlobal.h" #include "PairsGlobal.h"
#include "PairsTopButton.h" #include "PairsTopButton.h"
// TODO: support custom board sizes PairsView::PairsView(BRect frame, const char* name, int width, int height,
uint32 resizingMode)
PairsView::PairsView(BRect frame, const char* name, uint32 resizingMode) :
: BView(frame, name, resizingMode, B_WILL_DRAW) BView(frame, name, resizingMode, B_WILL_DRAW),
fWidth(width),
fHeight(height),
fNumOfCards(width * height),
fRandPos(new int[fNumOfCards]),
fPosX(new int[fNumOfCards]),
fPosY(new int[fNumOfCards])
{ {
// init bitmap pointers
for (int i = 0; i < 8; i++)
fCard[i] = NULL;
CreateGameBoard(); CreateGameBoard();
_SetPairsBoard(); _SetPairsBoard();
} }
@@ -55,11 +58,15 @@ PairsView::CreateGameBoard()
PairsView::~PairsView() PairsView::~PairsView()
{ {
for (int i = 0; i < 8; i++) for (int i = 0; i < fCardBitmaps.CountItems(); i++)
delete fCard[i]; delete ((BBitmap*)fCardBitmaps.ItemAt(i));
for (int i = 0; i < 16; i++) for (int i = 0; i < fDeckCard.CountItems(); i++)
delete fDeckCard[i]; delete ((TopButton*)fDeckCard.ItemAt(i));
delete fRandPos;
delete fPosX;
delete fPosY;
} }
@@ -91,10 +98,10 @@ PairsView::_ReadRandomIcons()
// TODO: maybe read the icons only once at startup // TODO: maybe read the icons only once at startup
// clean out any previous icons // clean out any previous icons
for (int i = 0; i < 8; i++) { for (int i = 0; i < fCardBitmaps.CountItems(); i++)
delete fCard[i]; delete ((BBitmap*)fCardBitmaps.ItemAt(i));
fCard[i] = NULL;
} fCardBitmaps.MakeEmpty();
BDirectory appsDirectory; BDirectory appsDirectory;
BDirectory prefsDirectory; BDirectory prefsDirectory;
@@ -149,19 +156,23 @@ PairsView::_ReadRandomIcons()
} }
} }
// pick eight random bitmaps from the ones we got in the list // pick random bitmaps from the ones we got in the list
srand((unsigned)time(0)); srand((unsigned)time(0));
for (int i = 0; i < 8; i++) { for (int i = 0; i < fNumOfCards / 2; i++) {
int32 index = rand() % bitmaps.CountItems(); int32 index = rand() % bitmaps.CountItems();
fCard[i] = (BBitmap*)bitmaps.RemoveItem(index); BBitmap* bitmap = ((BBitmap*)bitmaps.RemoveItem(index));
if (fCard[i] == NULL) { if (bitmap == NULL) {
BAlert* alert = new BAlert("fatal", "Pairs did not find enough " BString strErr;
"vector icons in the system, it needs at least eight.", strErr
<< "Pairs did not find enough vector icons in the system; it "
<< "needs at least " << fNumOfCards / 2;
BAlert* alert = new BAlert("fatal", strErr,
"OK", NULL, NULL, B_WIDTH_FROM_WIDEST, B_STOP_ALERT); "OK", NULL, NULL, B_WIDTH_FROM_WIDEST, B_STOP_ALERT);
alert->Go(); alert->Go();
exit(1); exit(1);
} }
fCardBitmaps.AddItem(bitmap);
} }
// delete the remaining bitmaps from the list // delete the remaining bitmaps from the list
@@ -173,15 +184,16 @@ PairsView::_ReadRandomIcons()
void void
PairsView::_SetPairsBoard() PairsView::_SetPairsBoard()
{ {
for (int i = 0; i < 16; i++) { for (int i = 0; i < fNumOfCards; i++) {
fButtonMessage = new BMessage(kMsgCardButton); fButtonMessage = new BMessage(kMsgCardButton);
fButtonMessage->AddInt32("ButtonNum", i); fButtonMessage->AddInt32("ButtonNum", i);
int x = i % 4 * (kBitmapSize + 10) + 10; int x = i % fWidth * (kBitmapSize + kSpaceSize) + kSpaceSize;
int y = i / 4 * (kBitmapSize + 10) + 10; int y = i / fHeight * (kBitmapSize + kSpaceSize) + kSpaceSize;
fDeckCard[i] = new TopButton(x, y, fButtonMessage); TopButton* button = new TopButton(x, y, fButtonMessage);
AddChild(fDeckCard[i]); fDeckCard.AddItem(button);
AddChild(button);
} }
} }
@@ -193,23 +205,27 @@ PairsView::_GenerateCardPos()
srand((unsigned)time(0)); srand((unsigned)time(0));
int positions[16]; int* positions = new int[fNumOfCards];
for (int i = 0; i < 16; i++) for (int i = 0; i < fNumOfCards; i++)
positions[i] = i; positions[i] = i;
for (int i = 16; i >= 1; i--) { for (int i = fNumOfCards; i >= 1; i--) {
int index = rand() % i; int index = rand() % i;
fRandPos[16-i] = positions[index]; fRandPos[fNumOfCards - i] = positions[index];
for (int j = index; j < i - 1; j++) for (int j = index; j < i - 1; j++)
positions[j] = positions[j + 1]; positions[j] = positions[j + 1];
} }
for (int i = 0; i < 16; i++) { for (int i = 0; i < fNumOfCards; i++) {
fPosX[i] = (fRandPos[i]) % 4 * (kBitmapSize + 10) + 10; fPosX[i] = (fRandPos[i]) % fWidth * (kBitmapSize + kSpaceSize)
fPosY[i] = (fRandPos[i]) / 4 * (kBitmapSize + 10) + 10; + kSpaceSize;
fPosY[i] = (fRandPos[i]) / fHeight * (kBitmapSize + kSpaceSize)
+ kSpaceSize;
} }
delete [] positions;
} }
@@ -219,8 +235,10 @@ PairsView::Draw(BRect updateRect)
SetDrawingMode(B_OP_ALPHA); SetDrawingMode(B_OP_ALPHA);
// draw rand pair 1 & 2 // draw rand pair 1 & 2
for (int i = 0; i < 16; i++) for (int i = 0; i < fNumOfCards; i++) {
DrawBitmap(fCard[i % 8], BPoint(fPosX[i], fPosY[i])); BBitmap* bitmap = ((BBitmap*)fCardBitmaps.ItemAt(i % fNumOfCards / 2));
DrawBitmap(bitmap, BPoint(fPosX[i], fPosY[i]));
}
} }
+13 -8
View File
@@ -1,8 +1,8 @@
/* /*
* Copyright 2008 Ralf Schülke, [email protected]. All rights reserved. * Copyright 2008 Ralf Schülke, [email protected].
* Distributed under the terms of the MIT License. * Copyright 2010 Adam Smith <[email protected]>
* All rights reserved. Distributed under the terms of the MIT License.
*/ */
#ifndef PAIRS_VIEW_H #ifndef PAIRS_VIEW_H
#define PAIRS_VIEW_H #define PAIRS_VIEW_H
@@ -15,6 +15,7 @@ class TopButton;
class PairsView : public BView { class PairsView : public BView {
public: public:
PairsView(BRect frame, const char* name, PairsView(BRect frame, const char* name,
int width, int height,
uint32 resizingMode); uint32 resizingMode);
virtual ~PairsView(); virtual ~PairsView();
@@ -22,7 +23,11 @@ public:
virtual void Draw(BRect updateRect); virtual void Draw(BRect updateRect);
virtual void CreateGameBoard(); virtual void CreateGameBoard();
TopButton* fDeckCard[16]; int fWidth;
int fHeight;
int fNumOfCards;
BList fDeckCard;
int GetIconFromPos(int pos); int GetIconFromPos(int pos);
private: private:
@@ -32,10 +37,10 @@ private:
bool _HasBitmap(BList& bitmaps, BBitmap* bitmap); bool _HasBitmap(BList& bitmaps, BBitmap* bitmap);
BMessage* fButtonMessage; BMessage* fButtonMessage;
BBitmap* fCard[8]; BList fCardBitmaps;
int fRandPos[16]; int* fRandPos;
int fPosX[16]; int* fPosX;
int fPosY[16]; int* fPosY;
}; };
+134 -28
View File
@@ -1,6 +1,7 @@
/* /*
* Copyright 2008 Ralf Schülke, [email protected]. All rights reserved. * Copyright 2008 Ralf Schülke, [email protected].
* Distributed under the terms of the MIT License. * Copyright 2010 Adam Smith <[email protected]>
* All rights reserved. Distributed under the terms of the MIT License.
*/ */
#include "PairsWindow.h" #include "PairsWindow.h"
@@ -12,6 +13,9 @@
#include <Button.h> #include <Button.h>
#include <Catalog.h> #include <Catalog.h>
#include <Locale.h> #include <Locale.h>
#include <Menu.h>
#include <MenuBar.h>
#include <MenuItem.h>
#include <MessageRunner.h> #include <MessageRunner.h>
#include <String.h> #include <String.h>
#include <TextView.h> #include <TextView.h>
@@ -21,28 +25,35 @@
#include "PairsView.h" #include "PairsView.h"
#include "PairsTopButton.h" #include "PairsTopButton.h"
// #pragma mark - PairsWindow // #pragma mark - PairsWindow
#undef TR_CONTEXT #undef TR_CONTEXT
#define TR_CONTEXT "PairsWindow" #define TR_CONTEXT "PairsWindow"
const uint32 MENU_NEW = 'MGnw';
const uint32 MENU_SIZE = 'MGsz';
const uint32 MENU_QUIT = 'MGqu';
PairsWindow::PairsWindow() PairsWindow::PairsWindow()
: BWindow(BRect(100, 100, 405, 405), "Pairs", B_TITLED_WINDOW, :
BWindow(BRect(100, 100, 405, 423), "Pairs", B_TITLED_WINDOW,
B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE
| B_NOT_RESIZABLE | B_NOT_ZOOMABLE), | B_NOT_RESIZABLE | B_NOT_ZOOMABLE),
fPairComparing(NULL), fPairComparing(NULL),
fIsFirstClick(true), fIsFirstClick(true),
fIsPairsActive(true), fIsPairsActive(true),
fPairCard(0), fPairCard(0),
fPairCardTmp(0), fPairCardTmp(0),
fButtonTmp(0), fButtonTmp(0),
fButton(0), fButton(0),
fButtonClicks(0), fButtonClicks(0),
fFinishPairs(0) fFinishPairs(0)
{ {
fPairsView = new PairsView(Bounds().InsetByCopy(0, 0).OffsetToSelf(0, 0), _MakeMenuBar();
"PairsView", B_FOLLOW_NONE); _MakeGameView(4, 4);
fPairsView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
AddChild(fPairsView);
CenterOnScreen(); CenterOnScreen();
} }
@@ -54,10 +65,107 @@ PairsWindow::~PairsWindow()
} }
void
PairsWindow::_MakeMenuBar()
{
fMenuBar = new BMenuBar(BRect(0, 0, 0, 0), "menubar");
AddChild(fMenuBar);
BMenu* menu = new BMenu(TR("Game"));
fMenuBar->AddItem(menu);
BMenuItem* menuItem;
menu->AddItem(menuItem = new BMenuItem(TR("New"),
new BMessage(MENU_NEW), 'N'));
menu->AddSeparatorItem();
BMenu* sizeMenu = new BMenu(TR("Size"));
sizeMenu->SetRadioMode(true);
BMessage* sizeMessage = new BMessage(MENU_SIZE);
sizeMessage->AddInt32("width", 4);
sizeMessage->AddInt32("height", 4);
sizeMenu->AddItem(menuItem = new BMenuItem(TR("Beginner (4x4)"),
sizeMessage));
menuItem->SetMarked(true);
sizeMessage = new BMessage(MENU_SIZE);
sizeMessage->AddInt32("width", 6);
sizeMessage->AddInt32("height", 6);
sizeMenu->AddItem(menuItem = new BMenuItem(TR("Intermediate (6x6)"),
sizeMessage));
sizeMessage = new BMessage(MENU_SIZE);
sizeMessage->AddInt32("width", 8);
sizeMessage->AddInt32("height", 8);
sizeMenu->AddItem(menuItem = new BMenuItem(TR("Expert (8x8)"),
sizeMessage));
menu->AddItem(sizeMenu);
menu->AddSeparatorItem();
menu->AddItem(menuItem = new BMenuItem(TR("Quit"),
new BMessage(MENU_QUIT), 'Q'));
}
void
PairsWindow::_MakeGameView(int width, int height)
{
BRect viewBounds = Bounds();
viewBounds.top = fMenuBar->Bounds().Height() + 1;
fPairsView = new PairsView(viewBounds, "PairsView", width, height,
B_FOLLOW_NONE);
fPairsView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
AddChild(fPairsView);
}
void
PairsWindow::NewGame()
{
fButtonClicks = 0;
fFinishPairs = 0;
fPairsView->CreateGameBoard();
}
void
PairsWindow::SetGameSize(int width, int height)
{
ResizeTo((kBitmapSize + kSpaceSize) * width + kSpaceSize,
(kBitmapSize + kSpaceSize) * height + kSpaceSize
+ fMenuBar->Bounds().Height());
RemoveChild(fPairsView);
delete fPairsView;
_MakeGameView(width, height);
NewGame();
}
void void
PairsWindow::MessageReceived(BMessage* message) PairsWindow::MessageReceived(BMessage* message)
{ {
switch (message->what) { switch (message->what) {
case MENU_NEW:
NewGame();
break;
case MENU_SIZE:
{
int32 width;
int32 height;
if (message->FindInt32("width", &width) == B_OK
&& message->FindInt32("height", &height) == B_OK) {
SetGameSize(width, height);
}
break;
}
case MENU_QUIT:
be_app->PostMessage(B_QUIT_REQUESTED);
break;
case kMsgCardButton: case kMsgCardButton:
if (fIsPairsActive) { if (fIsPairsActive) {
fButtonClicks++; fButtonClicks++;
@@ -67,16 +175,16 @@ PairsWindow::MessageReceived(BMessage* message)
break; break;
// look what Icon is behind a button // look what Icon is behind a button
for (int h = 0; h < 16; h++) { for (int h = 0; h < fPairsView->fNumOfCards; h++) {
if (fPairsView->GetIconFromPos(h) == num) { if (fPairsView->GetIconFromPos(h) == num) {
fPairCard = (h % 8); fPairCard = (h % fPairsView->fNumOfCards / 2);
fButton = fPairsView->GetIconFromPos(h); fButton = fPairsView->GetIconFromPos(h);
break; break;
} }
} }
// gameplay // gameplay
fPairsView->fDeckCard[fButton]->Hide(); ((TopButton*)fPairsView->fDeckCard.ItemAt(fButton))->Hide();
if (fIsFirstClick) { if (fIsFirstClick) {
fPairCardTmp = fPairCard; fPairCardTmp = fPairCard;
@@ -102,20 +210,20 @@ PairsWindow::MessageReceived(BMessage* message)
fIsPairsActive = true; fIsPairsActive = true;
if (fPairCard == fPairCardTmp) { if (fPairCard == fPairCardTmp)
fFinishPairs++; fFinishPairs++;
} else { else {
fPairsView->fDeckCard[fButton]->Show(); ((TopButton*)fPairsView->fDeckCard.ItemAt(fButton))->Show();
fPairsView->fDeckCard[fButtonTmp]->Show(); ((TopButton*)fPairsView->fDeckCard.ItemAt(fButtonTmp))->Show();
} }
// game end and results // game end and results
if (fFinishPairs == 8) { if (fFinishPairs == fPairsView->fNumOfCards / 2) {
BString strAbout; BString strAbout;
strAbout strAbout
<< "Pairs\n" << "Pairs\n"
<< "\twritten by Ralf Schülke\n" << "\twritten by Ralf Schülke\n"
<< "\tCopyright 2008, Haiku Inc.\n" << "\tCopyright 2008-2010, Haiku Inc.\n"
<< "\n" << "\n"
<< "You completed the game in " << fButtonClicks << "You completed the game in " << fButtonClicks
<< " clicks.\n"; << " clicks.\n";
@@ -136,9 +244,7 @@ PairsWindow::MessageReceived(BMessage* message)
if (alert->Go() == 0) { if (alert->Go() == 0) {
// New game // New game
fButtonClicks = 0; NewGame();
fFinishPairs = 0;
fPairsView->CreateGameBoard();
} else { } else {
// Quit game // Quit game
be_app->PostMessage(B_QUIT_REQUESTED); be_app->PostMessage(B_QUIT_REQUESTED);
+11 -3
View File
@@ -1,6 +1,7 @@
/* /*
* Copyright 2008 Ralf Schülke, [email protected]. All rights reserved. * Copyright 2008 Ralf Schülke, [email protected].
* Distributed under the terms of the MIT License. * Copyright 2010 Adam Smith <[email protected]>
* All rights reserved. Distributed under the terms of the MIT License.
*/ */
#ifndef PAIRS_WINDOW_H #ifndef PAIRS_WINDOW_H
@@ -19,15 +20,22 @@ public:
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
void NewGame();
void SetGameSize(int width, int height);
private: private:
void _MakeGameView(int width, int height);
void _MakeMenuBar();
BView* fBackgroundView; BView* fBackgroundView;
PairsView* fPairsView; PairsView* fPairsView;
BMenuBar* fMenuBar;
BMessageRunner* fPairComparing; BMessageRunner* fPairComparing;
bool fIsFirstClick; bool fIsFirstClick;
bool fIsPairsActive; bool fIsPairsActive;
int fPairCard; int fPairCard;
int fPairCardTmp; int fPairCardTmp;
int fButtonTmp; int fButtonTmp;
int fButton; int fButton;
int fButtonClicks; int fButtonClicks;
int fFinishPairs; int fFinishPairs;