/Map/map.cpp

https://github.com/TeamQuadForce/Comp345RPG · C++ · 605 lines · 502 code · 76 blank · 27 comment · 132 complexity · 75945c24d4aa6bc921bd2057b774e027 MD5 · raw file

  1. #include "map.h"
  2. #include <QIntValidator>
  3. #include <QFile>
  4. #include <QTextStream>
  5. #include <QString>
  6. #include <QStringList>
  7. #include <QDataStream>
  8. #include <QFileDialog>
  9. #include <QObject>
  10. // Constructors
  11. Map::Map()
  12. {
  13. mIsCharacterPlaced = false;
  14. mIsExitPlaced = false;
  15. mIsDungeonCompleted = false;
  16. }
  17. Map::Map(int aWidth, int aHeight)
  18. {
  19. mWidth = aWidth;
  20. mHeight = aHeight;
  21. mIsCharacterPlaced = false;
  22. mIsExitPlaced = false;
  23. mIsDungeonCompleted = false;
  24. }
  25. // Destructor
  26. Map::~Map()
  27. {
  28. }
  29. void Map::clearMapGrid()
  30. {
  31. for (int row=0; row<mMapGrid.size() ; row++)
  32. {
  33. mMapGrid[row].clear();
  34. }
  35. mMapGrid.clear();
  36. }
  37. void Map::displayMap()
  38. {
  39. QTextStream cout(stdout, QIODevice::WriteOnly);
  40. for (int row=0; row<mMapGrid.size() ; row++)
  41. {
  42. for (int column=0; column<mMapGrid[row].size(); column++)
  43. {
  44. cout << mMapGrid[row][column].getGamePiece();
  45. }
  46. cout << endl;
  47. }
  48. }
  49. void Map::createMapGrid()
  50. {
  51. for (int row = 0; row < mHeight; row++)
  52. {
  53. mMapGrid.append(QList<TileSet>() );
  54. for (int column = 0; column < mWidth; column++)
  55. {
  56. mMapGrid[row].append(TileSet(row, column, true, QString("")));
  57. }
  58. }
  59. }
  60. void Map::saveMap(bool aIsArena)
  61. {
  62. QString fileName = QFileDialog::getSaveFileName();
  63. QString mapDetails;
  64. QString mapInformation = QString("%1,%2,%3").arg(aIsArena).arg(mWidth).arg(mHeight);
  65. QFile file(fileName);
  66. if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
  67. return;
  68. QTextStream out(&file);
  69. if (file.isOpen())
  70. {
  71. out << mapInformation << endl;
  72. for (int row = 0; row < mMapGrid.size(); row++)
  73. {
  74. for (int column = 0; column < mMapGrid[row].size(); column++)
  75. {
  76. mapDetails += mMapGrid[row][column].getGamePiece() + ",";
  77. }
  78. mapDetails.truncate(mapDetails.size()-1);
  79. out << mapDetails << endl;
  80. mapDetails = "";
  81. }
  82. file.flush();
  83. file.close();
  84. }
  85. }
  86. bool Map::loadMap()
  87. {
  88. bool isArena = false;
  89. int first = 0;
  90. int row = 0;
  91. QString line;
  92. QString fileName = QFileDialog::getOpenFileName();
  93. QFile file(fileName);
  94. QStringList mapTileSet;
  95. if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
  96. return false;
  97. QTextStream in(&file);
  98. while (!in.atEnd())
  99. {
  100. line = in.readLine();
  101. mapTileSet = line.split(",");
  102. if (first == 0)
  103. {
  104. isArena = mapTileSet.takeFirst().toInt();
  105. mWidth = mapTileSet.takeFirst().toInt();
  106. mHeight = mapTileSet.takeFirst().toInt();
  107. first = 1;
  108. }
  109. else
  110. {
  111. mMapGrid.append(QList<TileSet>() );
  112. for (int column = 0; column < mHeight; column++)
  113. {
  114. mMapGrid[row].append(TileSet(row, column, true, mapTileSet.takeFirst()));
  115. if (mMapGrid[row][column].getGamePiece().compare("You") == 0)
  116. {
  117. setCharacterTileSet(mMapGrid[row][column]);
  118. setIsCharacterPlaced(true);
  119. }
  120. if (mMapGrid[row][column].getGamePiece().compare("Exit") == 0)
  121. {
  122. setExitTileSet(mMapGrid[row][column]);
  123. setIsExitPlaced(true);
  124. }
  125. if (mMapGrid[row][column].getGamePiece().compare("Monster") == 0)
  126. {
  127. addMonsterTileSet(mMapGrid[row][column]);
  128. }
  129. }
  130. row++;
  131. }
  132. }
  133. file.flush();
  134. file.close();
  135. displayMap();
  136. return isArena;
  137. }
  138. // Accessors
  139. QList<QList<TileSet> > Map::mapGrid()
  140. {
  141. return mMapGrid;
  142. }
  143. TileSet Map::lastModifiedTileSet()
  144. {
  145. return mLastModifiedTile;
  146. }
  147. TileSet Map::mapGridTileSet(int aRowPosition, int aColumnPosition)
  148. {
  149. return mMapGrid[aRowPosition][aColumnPosition];
  150. }
  151. int Map::mapWidth()
  152. {
  153. return mWidth;
  154. }
  155. int Map::mapHeight()
  156. {
  157. return mHeight;
  158. }
  159. // Mutators
  160. void Map::setLastModifiedTile(TileSet aTileSet)
  161. {
  162. mLastModifiedTile = aTileSet;
  163. }
  164. void Map::setTileSet(TileSet aTileSet, int aRowPosition, int aColumnPosition)
  165. {
  166. mMapGrid[aRowPosition][aColumnPosition] = aTileSet;
  167. }
  168. void Map::setMapWidth(int aWidth)
  169. {
  170. mWidth = aWidth;
  171. }
  172. void Map::setMapHeight(int aHeight)
  173. {
  174. mHeight = aHeight;
  175. }
  176. // Observer methods
  177. void Map::addObserver(Observer *aObserver)
  178. {
  179. if (!observerList.contains(aObserver))
  180. {
  181. observerList.append(aObserver);
  182. }
  183. }
  184. void Map::removeObserver(Observer *aObserver)
  185. {
  186. if (observerList.contains(aObserver))
  187. {
  188. observerList.removeOne(aObserver);
  189. }
  190. }
  191. void Map::notifyObservers()
  192. {
  193. foreach (Observer * obs, observerList)
  194. {
  195. obs->update(this);
  196. }
  197. }
  198. bool Map::moveCharacter(QString aMovement, bool &aIsChest)
  199. {
  200. int oldRowPosition = mCharacterTileSet.rowPosition();
  201. int oldColPosition = mCharacterTileSet.columnPosition();
  202. int newRowPosition = -1;
  203. int newColPosition = -1;
  204. //If the character isn't place or the movement ID is invalid
  205. if (!mIsCharacterPlaced)
  206. {
  207. return false;
  208. }
  209. else
  210. {
  211. //Character wants to move up
  212. if(aMovement.compare("Up") == 0 && (oldRowPosition - 1) >= 0)
  213. {
  214. //if the cell to move to is empty terrain or a chest
  215. if(mMapGrid[oldRowPosition - 1][oldColPosition].getGamePiece().compare("") == 0 ||
  216. mMapGrid[oldRowPosition - 1][oldColPosition].getGamePiece().compare("Chest") == 0 ||
  217. mMapGrid[oldRowPosition - 1][oldColPosition].getGamePiece().compare("Exit") == 0)
  218. {
  219. if (mMapGrid[oldRowPosition - 1][oldColPosition].getGamePiece().compare("Chest") == 0)
  220. {
  221. aIsChest = true;
  222. }
  223. newRowPosition = oldRowPosition - 1;
  224. newColPosition = oldColPosition;
  225. }
  226. else
  227. {
  228. return false;
  229. }
  230. }
  231. //Character wants to move down
  232. else if(aMovement.compare("Down") == 0 && (oldRowPosition + 1) < mHeight)
  233. {
  234. //if the cell to move to is empty terrain or a chest
  235. if(mMapGrid[oldRowPosition + 1][oldColPosition].getGamePiece().compare("") == 0 ||
  236. mMapGrid[oldRowPosition + 1][oldColPosition].getGamePiece().compare("Chest") == 0 ||
  237. mMapGrid[oldRowPosition + 1][oldColPosition].getGamePiece().compare("Exit") == 0)
  238. {
  239. if (mMapGrid[oldRowPosition + 1][oldColPosition].getGamePiece().compare("Chest") == 0)
  240. {
  241. aIsChest = true;
  242. }
  243. newRowPosition = oldRowPosition + 1;
  244. newColPosition = oldColPosition;
  245. }
  246. else
  247. {
  248. return false;
  249. }
  250. }
  251. //Character wants to move left
  252. else if(aMovement.compare("Left") == 0 && (oldColPosition - 1) >= 0)
  253. {
  254. //if the cell to move to is empty terrain or a chest
  255. if(mMapGrid[oldRowPosition][oldColPosition - 1].getGamePiece().compare("") == 0 ||
  256. mMapGrid[oldRowPosition][oldColPosition - 1].getGamePiece().compare("Chest") == 0 ||
  257. mMapGrid[oldRowPosition][oldColPosition - 1].getGamePiece().compare("Exit") == 0)
  258. {
  259. if (mMapGrid[oldRowPosition][oldColPosition - 1].getGamePiece().compare("Chest") == 0)
  260. {
  261. aIsChest = true;
  262. }
  263. newRowPosition = oldRowPosition;
  264. newColPosition = oldColPosition - 1;
  265. }
  266. else
  267. {
  268. return false;
  269. }
  270. }
  271. //Character wants to move right
  272. else if(aMovement.compare("Right") == 0 && (oldColPosition + 1) < mWidth)
  273. {
  274. //if the cell to move to is empty terrain or a chest
  275. if(mMapGrid[oldRowPosition][oldColPosition + 1].getGamePiece().compare("") == 0 ||
  276. mMapGrid[oldRowPosition][oldColPosition + 1].getGamePiece().compare("Chest") == 0 ||
  277. mMapGrid[oldRowPosition][oldColPosition + 1].getGamePiece().compare("Exit") == 0)
  278. {
  279. if (mMapGrid[oldRowPosition][oldColPosition + 1].getGamePiece().compare("Chest") == 0)
  280. {
  281. aIsChest = true;
  282. }
  283. newRowPosition = oldRowPosition;
  284. newColPosition = oldColPosition + 1;
  285. }
  286. else
  287. {
  288. return false;
  289. }
  290. }
  291. else
  292. {
  293. return false;
  294. }
  295. mCharacterTileSet.setRowPosition(newRowPosition);
  296. mCharacterTileSet.setColumnPosition(newColPosition);
  297. mMapGrid[newRowPosition][newColPosition].setGamePiece("You");
  298. TileSet aLastModifiedTileSet = mMapGrid[newRowPosition][newColPosition];
  299. setLastModifiedTile(aLastModifiedTileSet);
  300. notifyObservers();
  301. mMapGrid[oldRowPosition][oldColPosition].setGamePiece("");
  302. aLastModifiedTileSet = mMapGrid[oldRowPosition][oldColPosition];
  303. setLastModifiedTile(aLastModifiedTileSet);
  304. notifyObservers();
  305. if(mCharacterTileSet.rowPosition() == mExitTileSet.rowPosition() &&
  306. mCharacterTileSet.columnPosition() == mExitTileSet.columnPosition())
  307. {
  308. setIsDungeonCompleted(true);
  309. }
  310. return true;
  311. }
  312. }
  313. bool Map::moveMonster(int aIndex, bool &aHasAttacked)
  314. {
  315. const int numberOfMovements = 6;
  316. //try to attack, if successful dont move
  317. if (!aHasAttacked)
  318. {
  319. int rowPos = mMonsters[aIndex].rowPosition();
  320. int colPos = mMonsters[aIndex].columnPosition();
  321. if (rowPos + 1 < mapWidth() && rowPos - 1 >= 0 && colPos + 1 < mapHeight() && colPos - 1 > 0)
  322. {
  323. if (mMapGrid[rowPos][colPos + 1].getGamePiece().compare("You") == 0 ||
  324. mMapGrid[rowPos][colPos - 1].getGamePiece().compare("You") == 0 ||
  325. mMapGrid[rowPos + 1][colPos].getGamePiece().compare("You") == 0 ||
  326. mMapGrid[rowPos - 1][colPos + 1].getGamePiece().compare("You") == 0)
  327. {
  328. aHasAttacked = true;
  329. return true;
  330. }
  331. }
  332. }
  333. for (int i = 0; i < numberOfMovements; ++i)
  334. {
  335. int randomMove = qrand() % 4;
  336. int oldRowPosition = mMonsters[aIndex].rowPosition();
  337. int oldColPosition = mMonsters[aIndex].columnPosition();
  338. int newRowPosition = -1;
  339. int newColPosition = -1;
  340. //Character wants to move up
  341. if(randomMove == 0 && (oldRowPosition - 1) >= 0)
  342. {
  343. //if the cell to move to is empty terrain or a chest
  344. if(mMapGrid[oldRowPosition - 1][oldColPosition].getGamePiece().compare("") == 0)
  345. {
  346. newRowPosition = oldRowPosition - 1;
  347. newColPosition = oldColPosition;
  348. }
  349. else
  350. {
  351. return false;
  352. }
  353. }
  354. //Character wants to move down
  355. else if(randomMove == 1 && (oldRowPosition + 1) < mHeight)
  356. {
  357. //if the cell to move to is empty terrain or a chest
  358. if(mMapGrid[oldRowPosition + 1][oldColPosition].getGamePiece().compare("") == 0)
  359. {
  360. newRowPosition = oldRowPosition + 1;
  361. newColPosition = oldColPosition;
  362. }
  363. else
  364. {
  365. return false;
  366. }
  367. }
  368. //Character wants to move left
  369. else if(randomMove == 2 && (oldColPosition - 1) >= 0)
  370. {
  371. //if the cell to move to is empty terrain or a chest
  372. if(mMapGrid[oldRowPosition][oldColPosition - 1].getGamePiece().compare("") == 0)
  373. {
  374. newRowPosition = oldRowPosition;
  375. newColPosition = oldColPosition - 1;
  376. }
  377. else
  378. {
  379. return false;
  380. }
  381. }
  382. //Character wants to move right
  383. else if(randomMove == 3 && (oldColPosition + 1) < mWidth)
  384. {
  385. //if the cell to move to is empty terrain or a chest
  386. if(mMapGrid[oldRowPosition][oldColPosition + 1].getGamePiece().compare("") == 0)
  387. {
  388. newRowPosition = oldRowPosition;
  389. newColPosition = oldColPosition + 1;
  390. }
  391. else
  392. {
  393. return false;
  394. }
  395. }
  396. else
  397. {
  398. return false;
  399. }
  400. mMonsters[aIndex].setRowPosition(newRowPosition);
  401. mMonsters[aIndex].setColumnPosition(newColPosition);
  402. mMapGrid[newRowPosition][newColPosition].setGamePiece("Monster");
  403. TileSet aLastModifiedTileSet = mMapGrid[newRowPosition][newColPosition];
  404. setLastModifiedTile(aLastModifiedTileSet);
  405. notifyObservers();
  406. mMapGrid[oldRowPosition][oldColPosition].setGamePiece("");
  407. aLastModifiedTileSet = mMapGrid[oldRowPosition][oldColPosition];
  408. setLastModifiedTile(aLastModifiedTileSet);
  409. notifyObservers();
  410. //Check to see if there is a player around, if so attack him once
  411. if (!aHasAttacked)
  412. {
  413. int rowPos = mMonsters[aIndex].rowPosition();
  414. int colPos = mMonsters[aIndex].columnPosition();
  415. if (rowPos + 1 < mapWidth() && rowPos - 1 >= 0 && colPos + 1 < mapHeight() && colPos - 1 > 0)
  416. {
  417. if (mMapGrid[rowPos][colPos + 1].getGamePiece().compare("You") == 0 ||
  418. mMapGrid[rowPos][colPos - 1].getGamePiece().compare("You") == 0 ||
  419. mMapGrid[rowPos + 1][colPos].getGamePiece().compare("You") == 0 ||
  420. mMapGrid[rowPos - 1][colPos + 1].getGamePiece().compare("You") == 0)
  421. {
  422. aHasAttacked = true;
  423. }
  424. }
  425. }
  426. }
  427. }
  428. //Moves the title to a new postion and notifies any observers
  429. void Map::moveTile(TileSet aTile, int aRow, int aColumn)
  430. {
  431. mMapGrid[aRow][aColumn] = aTile;
  432. notifyObservers();
  433. }
  434. //Sets the dungeon as completed and notifies any observers
  435. void Map::setIsDungeonCompleted(bool aCleared)
  436. {
  437. mIsDungeonCompleted = aCleared;
  438. notifyObservers();
  439. }
  440. //Return if the dungeon is completed
  441. bool Map::isDungeonCompleted()
  442. {
  443. return mIsDungeonCompleted;
  444. }
  445. bool Map::isCharacterPlaced()
  446. {
  447. return mIsCharacterPlaced;
  448. }
  449. bool Map::isExitPlaced()
  450. {
  451. return mIsExitPlaced;
  452. }
  453. void Map::setCharacterTileSet(TileSet aTileSet)
  454. {
  455. mCharacterTileSet = aTileSet;
  456. }
  457. void Map::setExitTileSet(TileSet aTileSet)
  458. {
  459. mExitTileSet = aTileSet;
  460. }
  461. TileSet Map::characterTileSet()
  462. {
  463. return mCharacterTileSet;
  464. }
  465. TileSet Map::exitTileSet()
  466. {
  467. return mExitTileSet;
  468. }
  469. void Map::setIsCharacterPlaced(bool aIsCharacterPlaced)
  470. {
  471. mIsCharacterPlaced = aIsCharacterPlaced;
  472. }
  473. void Map::setIsExitPlaced(bool aIsExitPlaced)
  474. {
  475. mIsExitPlaced = aIsExitPlaced;
  476. }
  477. int Map::level()
  478. {
  479. return mLevel;
  480. }
  481. void Map::setLevel(int aLevel)
  482. {
  483. mLevel = aLevel;
  484. }
  485. void Map::addMonsterTileSet(TileSet aTileSet)
  486. {
  487. mMonsters.append(aTileSet);
  488. }
  489. bool Map::isAMonsterThere(QString aDirection)
  490. {
  491. if (aDirection == "Attack Up")
  492. {
  493. if (mCharacterTileSet.columnPosition() == mMonsters[0].columnPosition() &&
  494. mCharacterTileSet.rowPosition() - 1 == mMonsters[0].rowPosition())
  495. {
  496. return true;
  497. }
  498. }
  499. else if (aDirection == "Attack Right")
  500. {
  501. if (mCharacterTileSet.columnPosition() + 1 == mMonsters[0].columnPosition() &&
  502. mCharacterTileSet.rowPosition() == mMonsters[0].rowPosition())
  503. {
  504. return true;
  505. }
  506. }
  507. else if (aDirection == "Attack Down")
  508. {
  509. if (mCharacterTileSet.columnPosition() == mMonsters[0].columnPosition() &&
  510. mCharacterTileSet.rowPosition() + 1 == mMonsters[0].rowPosition())
  511. {
  512. return true;
  513. }
  514. }
  515. else if (aDirection == "Attack Left")
  516. {
  517. if (mCharacterTileSet.columnPosition() - 1 == mMonsters[0].columnPosition() &&
  518. mCharacterTileSet.rowPosition() == mMonsters[0].rowPosition())
  519. {
  520. return true;
  521. }
  522. }
  523. return false;
  524. }
  525. void Map::killMonsters()
  526. {
  527. mMapGrid[mMonsters[0].rowPosition()][mMonsters[0].columnPosition()].setGamePiece("");
  528. notifyObservers();
  529. }