File indexing completed on 2024-04-14 03:59:23

0001 /***************************************************************************
0002 *   KBlocks, a falling blocks game by KDE                                *
0003 *   SPDX-FileCopyrightText: 2010 Zhongjie Cai <squall.leonhart.cai@gmail.com>       *
0004 *                                                                         *
0005 *   SPDX-License-Identifier: GPL-2.0-or-later
0006 ***************************************************************************/
0007 #include "KBlocksGameReplayer.h"
0008 
0009 #include <sstream>
0010 
0011 #include "kblocks_replay_debug.h"
0012 
0013 KBlocksGameReplayer::KBlocksGameReplayer(const char *fileName, bool isBinaryMode)
0014 {
0015     // Map data types to strings for reading text file
0016     for (int i = 0; i < RecordDataType_Max_Count; ++i) {
0017         mRTMap[ KBlocksRecordText[i] ] = i;
0018     }
0019     mRTMap[string("MaxCount")] = -1;
0020 
0021     // Set default variables in case loading the file fails
0022     mGameCount = 0;
0023     mGameSeed = 0;
0024     mSameSeed = false;
0025     mStepLength = 1;
0026 
0027     // Open replay file
0028     std::ifstream replayFile;
0029     if (isBinaryMode) {
0030         replayFile.open(fileName, std::ios::binary);
0031     } else {
0032         replayFile.open(fileName);
0033     }
0034 
0035     // Check that replay file was opened successfully
0036     if (!replayFile.is_open()) {
0037         qCWarning(KBReplay) << "Unable to open file " << fileName;
0038         return;
0039     }
0040 
0041     if (isBinaryMode) {
0042         loadBinary(replayFile);
0043     } else {
0044         loadText(replayFile);
0045     }
0046 
0047     // Check that more than two Replay steps have been loaded
0048     // The two first steps set the required variables.
0049     if (mReplayList.size() < 2) {
0050         qCWarning(KBReplay) << "Problem loading replay file" << fileName;
0051         return;
0052     }
0053 
0054     mGameCount = mReplayList.front().value;
0055     mReplayList.pop_front();
0056     mGameSeed = mReplayList.front().value;
0057     mSameSeed = (mReplayList.front().index == 1);
0058     mReplayList.pop_front();
0059 
0060     replayFile.close();
0061 }
0062 
0063 KBlocksGameReplayer::~KBlocksGameReplayer()
0064 {
0065 }
0066 
0067 int KBlocksGameReplayer::getGameCount()
0068 {
0069     return mGameCount;
0070 }
0071 
0072 int KBlocksGameReplayer::getGameSeed()
0073 {
0074     return mGameSeed;
0075 }
0076 
0077 bool KBlocksGameReplayer::isSameSeed()
0078 {
0079     return mSameSeed;
0080 }
0081 
0082 void KBlocksGameReplayer::setStepLength(int stepLen)
0083 {
0084     if (stepLen > 1) {
0085         mStepLength = stepLen;
0086     } else {
0087         mStepLength = 1;
0088     }
0089 }
0090 
0091 bool KBlocksGameReplayer::getNextRecords(vector<KBlocksReplayData> *data)
0092 {
0093     if (mReplayList.empty()) {
0094         return false;
0095     }
0096 
0097     KBlocksReplayData tmpData;
0098     int tmpLength = mStepLength;
0099     while (tmpLength > 0) {
0100         tmpData = mReplayList.front();
0101         tmpLength -= tmpData.time;
0102         if (tmpLength > 0) {
0103             data->push_back(tmpData);
0104             mReplayList.pop_front();
0105         } else {
0106             mReplayList.front().time = -tmpLength;
0107         }
0108         if (mReplayList.empty()) {
0109             return true;
0110         }
0111     }
0112 
0113     return true;
0114 }
0115 
0116 void KBlocksGameReplayer::loadText(std::ifstream &replayFile)
0117 {
0118     std::string line;
0119     std::istringstream inStream;
0120     std::string tmpString;
0121     KBlocksReplayData tmpData;
0122     mReplayList.clear();
0123     do {
0124         std::getline(replayFile, line);
0125         inStream.str(line);
0126         inStream >> tmpData.time >> tmpString >> tmpData.index >> tmpData.value;
0127         tmpData.type = mRTMap[tmpString];
0128         if ((tmpData.type == -1) || inStream.fail()) {
0129             break;
0130         }
0131         mReplayList.push_back(tmpData);
0132         inStream.clear();
0133     } while (!replayFile.eof());
0134 }
0135 
0136 void KBlocksGameReplayer::loadBinary(std::ifstream &replayFile)
0137 {
0138     KBlocksReplayData tmpData;
0139     mReplayList.clear();
0140 
0141     tmpData.time  = replayFile.get();
0142     tmpData.type  = replayFile.get();
0143     tmpData.index = replayFile.get();
0144     tmpData.value = replayFile.get();
0145 
0146     do {
0147         if (tmpData.type == RecordDataType_Skipped) {
0148             int tmpTime = tmpData.time;
0149             while (tmpData.type == RecordDataType_Skipped) {
0150                 tmpData.time  = replayFile.get();
0151                 tmpData.type  = replayFile.get();
0152                 tmpData.index = replayFile.get();
0153                 tmpData.value = replayFile.get();
0154 
0155                 tmpTime += tmpData.time;
0156             }
0157             tmpData.time = tmpTime;
0158         }
0159         mReplayList.push_back(tmpData);
0160         tmpData.time  = replayFile.get();
0161         tmpData.type  = replayFile.get();
0162         tmpData.index = replayFile.get();
0163         tmpData.value = replayFile.get();
0164     } while (!replayFile.eof());
0165 }
0166