1 /*
2 ===========================================================================
3 blockattack - Block Attack - Rise of the Blocks
4 Copyright (C) 2005-2015 Poul Sander
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see http://www.gnu.org/licenses/
18
19 Source information and contacts persons can be found at
20 http://blockattack.net
21 ===========================================================================
22 */
23
24 #include "puzzlehandler.hpp"
25 #include <vector>
26 #include <iostream>
27 #include "stats.h"
28 #include <physfs.h> //Abstract file system. To use containers
29 #include "cereal/cereal.hpp"
30 #include "cereal/types/vector.hpp"
31 #include "cereal/archives/json.hpp"
32 #include "sago/SagoMisc.hpp"
33
34 const int maxNrOfPuzzleStages = 50; //Maximum number of puzzle stages
35
36 static std::string puzzleSavePath;
37 static std::string puzzleName; //The filename of
38 static std::vector<bool> puzzleCleared(maxNrOfPuzzleStages); //vector that tells if puzzle cleared
39 static std::vector<int> nrOfMovesAllowed(maxNrOfPuzzleStages); //Moves to clear
40 static int puzzleLevels[maxNrOfPuzzleStages][6][12]; //Contains board layout;
41 static int nrOfPuzzles; //How many are there actually?
42
PuzzleNumberOfMovesAllowed(int level)43 int PuzzleNumberOfMovesAllowed(int level) {
44 return nrOfMovesAllowed.at(level);
45 }
46
PuzzleGetBrick(int level,int x,int y)47 int PuzzleGetBrick(int level, int x, int y) {
48 return puzzleLevels[level][x][y];
49 }
50
PuzzleGetNumberOfPuzzles()51 int PuzzleGetNumberOfPuzzles() {
52 return nrOfPuzzles;
53 }
54
PuzzleIsCleared(int level)55 bool PuzzleIsCleared(int level) {
56 return puzzleCleared.at(level);
57 }
58
PuzzleGetName()59 const std::string& PuzzleGetName() {
60 return puzzleName;
61 }
62
PuzzleSetName(const std::string & name)63 void PuzzleSetName(const std::string& name) {
64 puzzleName = name;
65 puzzleSavePath = name + ".json.save";
66 }
67
LoadClearData()68 void LoadClearData() {
69 std::string readFileContent = sago::GetFileContent(puzzleSavePath.c_str());
70 if (readFileContent.length() > 0) {
71 std::stringstream ss(readFileContent);
72 {
73 try {
74 cereal::JSONInputArchive archive(ss);
75 archive(cereal::make_nvp("cleared", puzzleCleared));
76 }
77 catch (cereal::Exception& e) {
78 std::cerr << "Failed to read \"" << puzzleSavePath << "\". File will be regenerated. Reason: " << e.what() << "\n";
79 puzzleCleared.clear();
80 }
81 }
82 }
83 else {
84 puzzleCleared.clear();
85 }
86 puzzleCleared.resize(nrOfPuzzles);
87 }
88
SaveClearData()89 void SaveClearData() {
90 std::stringstream ss;
91 {
92 cereal::JSONOutputArchive archive(ss);
93 archive(cereal::make_nvp("cleared", puzzleCleared));
94 }
95 sago::WriteFileContent(puzzleSavePath.c_str(), ss.str());
96 }
97
PuzzleSetClear(int Level)98 void PuzzleSetClear(int Level) {
99 if (puzzleCleared[Level]==false) {
100 Stats::getInstance()->addOne("puzzlesSolved");
101 }
102 puzzleCleared[Level] = true;
103 SaveClearData();
104 }
105
106 /*Loads all the puzzle levels*/
LoadPuzzleStages()107 int LoadPuzzleStages( ) {
108 if (!PHYSFS_exists(((std::string)("puzzles/"+puzzleName)).c_str())) {
109 std::cerr << "Warning: File not in blockattack.data: " << ("puzzles/"+puzzleName) << "\n";
110 return -1; //file doesn't exist
111 }
112 std::string fileContent = sago::GetFileContent(((std::string)("puzzles/"+puzzleName)).c_str());
113 std::stringstream inFile(fileContent);
114
115 inFile >> nrOfPuzzles;
116 if (nrOfPuzzles>maxNrOfPuzzleStages) {
117 nrOfPuzzles=maxNrOfPuzzleStages;
118 }
119 if (nrOfPuzzles < 0) {
120 nrOfPuzzles = 0;
121 }
122 for (int k=0; k<nrOfPuzzles ; k++) {
123 inFile >> nrOfMovesAllowed.at(k);
124 for (int i=11; i>=0; i--)
125 for (int j=0; j<6; j++) {
126 inFile >> puzzleLevels[k][j][i];
127 }
128 }
129 LoadClearData();
130 return 0;
131 }
132