Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saving game state #26

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ App::App()
Game *theGame = new Game(4, 4);
WindowBoard *win = new WindowBoard(theGame);
BMessenger gameMsg(NULL, theGame);
gameMsg.SendMessage(H2048_NEW_GAME);
gameMsg.SendMessage(H2048_LOAD_GAME);
}

int main()
Expand Down
80 changes: 78 additions & 2 deletions Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "Game.h"
#include "GameBoard.h"
#include "WindowBoard.h"

#include <algorithm>
#include <cstdlib>
Expand Down Expand Up @@ -35,7 +36,10 @@ Game::Game(uint32 sizeX, uint32 sizeY)
sprintf(fHighscore_path, "%s/%s", buffer, HAIKU2048_DIRECTORY);
result = create_directory(fHighscore_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
sprintf(fHighscore_path, "%s/%s", fHighscore_path, HIGHSCORE_FILENAME);


sprintf(fSaveFile_path, "%s/%s", buffer, HAIKU2048_DIRECTORY);
sprintf(fSaveFile_path, "%s/%s", fSaveFile_path, SAVEFILE_FILENAME);

std::ifstream highscore(fHighscore_path, std::ios::binary);
memset(fUsername, 0, sizeof(char) * 32);
memset(fPlayername, 0, sizeof(char) * 32);
Expand All @@ -47,7 +51,6 @@ Game::Game(uint32 sizeX, uint32 sizeY)
}
fBoard = new uint32[fSizeX * fSizeY];
fPreviousBoard = new uint32[fSizeX * fSizeY];

Run();
}

Expand All @@ -70,6 +73,18 @@ Game::MessageReceived(BMessage *message)
case H2048_NEW_GAME:
newGame();
break;
case H2048_LOAD_GAME:
if(!load()){
newGame();
}
break;
case H2048_SAVE_GAME:
{
BRect frame;
message->FindRect("frame",&frame);
save(frame);
break;
}
case H2048_NAME_REQUESTED:
{
sprintf(fPlayername, "%s", (const char*)message->FindString("playername"));
Expand Down Expand Up @@ -438,3 +453,64 @@ Game::undoMove() {
changed.AddBool("canUndo", false);
broadcastMessage(changed);
}

status_t
Game::save(BRect frame){
BFile saveFile(fSaveFile_path,B_WRITE_ONLY | B_CREATE_FILE);

BMessage saveMessage(H2048_SAVE_MESSAGE);

for(int i =0;i<fSizeX*fSizeY;i++){
saveMessage.AddUInt32("board",fBoard[i]);
saveMessage.AddUInt32("previousBoard", fPreviousBoard[i]);
}

saveMessage.AddUInt32("score",fScore);
saveMessage.AddUInt32("previousScore",fPreviousScore);

saveMessage.AddBool("canUndo",fCanUndo);
saveMessage.AddRect("windowFrame",frame);

return saveMessage.Flatten(&saveFile);
}
bool
Game::load(){
BFile saveFile(fSaveFile_path,B_READ_ONLY);

BMessage saveMessage(H2048_SAVE_MESSAGE);
status_t result = saveMessage.Unflatten(&saveFile);
if(result!= B_OK){
return false;
}

bool loadOK = true;

for(int i =0;i<fSizeX*fSizeY;i++){
loadOK = loadOK && saveMessage.FindUInt32("board",i,&fBoard[i]) == B_OK;
loadOK = loadOK && saveMessage.FindUInt32("previousBoard",i, &fPreviousBoard[i]) == B_OK;
}

loadOK = loadOK && saveMessage.FindUInt32("score",&fScore) == B_OK;
loadOK = loadOK && saveMessage.FindUInt32("previousScore",&fPreviousScore) == B_OK;
loadOK = loadOK && saveMessage.FindBool("canUndo",&fCanUndo) == B_OK;

BRect frame;
loadOK = loadOK && saveMessage.FindRect("windowFrame",&frame) == B_OK;

if(!loadOK) return false;

BMessage setFrameMessage(H2048_SET_FRAME);
setFrameMessage.AddRect("frame",frame);
broadcastMessage(setFrameMessage);

BMessage startNotification(H2048_GAME_STARTED);
broadcastMessage(startNotification);

//Notify the boards about fCanUndo state
BMessage changed(H2048_BOARD_CHANGED);
changed.AddBool("canUndo", fCanUndo);
broadcastMessage(changed);

fInGame = true;
return true;
}
9 changes: 8 additions & 1 deletion Game.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#define HIGHSCORE_FILENAME "Highscore"
#define HAIKU2048_DIRECTORY "Haiku2048"
#define SAVEFILE_FILENAME "Save"

class BMessage;
class BMessenger;
Expand All @@ -30,7 +31,10 @@ enum
H2048_NEW_GAME = '48NG',
H2048_NAME_REQUESTED= '48NR',
H2048_UNDO_MOVE = '48UM',
H2048_MAKE_MOVE = '48MM'
H2048_MAKE_MOVE = '48MM',
H2048_LOAD_GAME = '48LG',
H2048_SAVE_GAME = '48SG',
H2048_SAVE_MESSAGE = '48SM'
};

class Game : public BLooper
Expand All @@ -57,6 +61,8 @@ class Game : public BLooper
void undoMove();
void copyBoard(uint32 *from, uint32 *to);
void broadcastMessage(BMessage &msg);
status_t save(BRect frame);
bool load();
uint32 * boardAt(uint32 x, uint32 y);
uint32 newTile();
bool gameOver();
Expand All @@ -83,6 +89,7 @@ class Game : public BLooper
char fUsername[32];
char fPlayername[32];
char fHighscore_path[128];
char fSaveFile_path[128];
};

#endif // GAME_H
7 changes: 7 additions & 0 deletions GameBoard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ GameBoard::MessageReceived(BMessage *message)

boardChanged(canUndo);
break;
case H2048_SET_FRAME:
{
BRect frame;
message->FindRect("frame", &frame);
setFrame(frame);
break;
}
case H2048_REQUEST_NAME:
nameRequest();
default:
Expand Down
4 changes: 3 additions & 1 deletion GameBoard.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ enum
H2048_GAME_STARTED = '48GS',
H2048_GAME_ENDED = '48GE',
H2048_REQUEST_NAME = '48RN',
H2048_BOARD_CHANGED = '48BC'
H2048_BOARD_CHANGED = '48BC',
H2048_SET_FRAME = '48SB'
};

class GameBoard : public BLooper
Expand All @@ -33,6 +34,7 @@ class GameBoard : public BLooper
virtual void gameEnded() = 0;
virtual void nameRequest() = 0;
virtual void boardChanged(bool canUndo) = 0;
virtual void setFrame(BRect frame) = 0;

protected:
Game * fTarget;
Expand Down
24 changes: 24 additions & 0 deletions WindowBoard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ GameWindow::~GameWindow()
bool
GameWindow::QuitRequested()
{
BMessenger game(NULL, fMaster->fTarget);
BMessage saveMessage(H2048_SAVE_GAME);
saveMessage.AddRect("frame",Frame());
game.SendMessage(&saveMessage);
be_app_messenger.SendMessage(B_QUIT_REQUESTED);
return true;
}
Expand All @@ -127,6 +131,16 @@ GameWindow::MessageReceived(BMessage *message)
showBoard(canUndo);
break;
}
case H2048_SET_FRAME:
{
BRect frame;
message->FindRect("frame",&frame);
MoveTo(frame.LeftTop());
prevWidth = (int)frame.Width();
prevHeight = (int)frame.Height();
ResizeTo((int)frame.Width(),(int)frame.Height());
break;
}
case H2048_UNDO_MOVE:
{
if (!fMaster->fSending) {
Expand Down Expand Up @@ -315,3 +329,13 @@ WindowBoard::nameRequest()
BMessenger messenger(NULL, fWindow);
messenger.SendMessage(H2048_REQUEST_NAME);
}

void
WindowBoard::setFrame(BRect frame)
{
BMessage setFrame(H2048_SET_FRAME);
setFrame.AddRect("frame", frame);

BMessenger messenger(NULL, fWindow);
messenger.SendMessage(&setFrame);
}
1 change: 1 addition & 0 deletions WindowBoard.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ friend class GameWindow;
void gameEnded();
void nameRequest();
void boardChanged(bool canUndo);
void setFrame(BRect frame);

private:
bool fSending;
Expand Down