Advertisement
Guest User

Untitled

a guest
Jun 19th, 2019
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.75 KB | None | 0 0
  1. #include "app.h"
  2.  
  3. int main() {
  4.  
  5. // Window aspect ratio is always 4:3, so it only takes
  6. // a value that is then used as the screen width.
  7. // The screen height is calculated in the Game::app class constructor.
  8. Game::app game(800, L"Test");
  9. game.start();
  10. }
  11.  
  12. #pragma once
  13.  
  14. #include <SFML/Graphics.hpp>
  15.  
  16. #include "Board.h"
  17.  
  18. namespace Game {
  19. class app : public sf::Drawable {
  20. public:
  21.  
  22. app(int windowWidth, const wchar_t* name);
  23. ~app() = default;
  24.  
  25. // Runs the app
  26. void start();
  27. void end();
  28.  
  29. private:
  30.  
  31. // MEMBER VARIABLES
  32.  
  33. const float common_divisor;
  34. bool m_iscrashed;
  35. Board board;
  36. sf::RenderWindow window;
  37. sf::Font arial;
  38.  
  39. // MEMBER FUNCTIONS
  40.  
  41. void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
  42. void handleEvents();
  43. void updateWindow();
  44. };
  45. }
  46.  
  47. #include "app.h"
  48.  
  49. #include <iostream>
  50. #include <thread>
  51. #include <chrono>
  52.  
  53. Game::app::app(int windowWidth, const wchar_t* name)
  54. : common_divisor{ static_cast<float>(windowWidth / Board::width) }, m_iscrashed{ false } {
  55.  
  56. const int windowHeight = windowWidth * 3 / 4;
  57. if (windowHeight % 3 != 0)
  58. std::wcout << L"Error! the window aspect ratio isn't 4:3.n";
  59.  
  60. const char* font_path{ "res/fonts/arial.ttf" };
  61.  
  62. // Had to make it a normal string because
  63. // the loadFromFile() func doesn't accept wide strings.
  64. if (!arial.loadFromFile(font_path)) {
  65. std::cout << "[ERROR]: Couldn't load fontnFile Path: " << font_path << 'nn';
  66. }
  67.  
  68. window.create(sf::VideoMode(windowWidth, windowHeight), name);
  69. window.setFramerateLimit(5);
  70. }
  71.  
  72. void Game::app::handleEvents() {
  73.  
  74. sf::Event event;
  75.  
  76. while (window.pollEvent(event)) {
  77. switch (event.type) {
  78.  
  79. case sf::Event::Closed:
  80. window.close();
  81. break;
  82.  
  83. case sf::Event::TextEntered:
  84. board.changeDirection(static_cast<char>(event.text.unicode));
  85. }
  86. }
  87. }
  88.  
  89. void Game::app::draw(sf::RenderTarget& target, sf::RenderStates states) const {
  90.  
  91. for (size_t i = 0, h = Board::height; i < h; ++i) {
  92. for (size_t j = 0, w = Board::width; j < w; ++j) {
  93.  
  94. Coord here{ j, i };
  95. sf::RectangleShape rect;
  96. rect.setSize({ common_divisor, common_divisor });
  97. rect.setPosition({ common_divisor * j, common_divisor * i });
  98.  
  99. switch (board.at(here)) {
  100. case Board::WALL:
  101. target.draw(rect, states);
  102. break;
  103.  
  104. case Board::SNAKE:
  105. rect.setFillColor(sf::Color::Green);
  106. target.draw(rect, states);
  107. break;
  108.  
  109. case Board::FOOD:
  110. rect.setFillColor(sf::Color::Red);
  111. target.draw(rect, states);
  112.  
  113. }
  114.  
  115. }
  116. }
  117.  
  118. // Draws the game score
  119. sf::Text text;
  120. text.setFont(arial);
  121. text.setCharacterSize(static_cast<unsigned int>(common_divisor));
  122. text.setPosition({ 0.0f, 0.0f });
  123. text.setString("Score: " + std::to_string(board.score()));
  124. text.setFillColor(sf::Color::Black);
  125.  
  126. target.draw(text, states);
  127. }
  128.  
  129. // Updates the render window
  130. void Game::app::updateWindow() {
  131. if (m_iscrashed)
  132. window.close();
  133.  
  134. window.clear(sf::Color::Black);
  135. window.draw(*this);
  136. window.display();
  137. }
  138.  
  139. // Starts the app
  140. void Game::app::start() {
  141.  
  142. while (window.isOpen()) {
  143. handleEvents();
  144. board.update(&m_iscrashed);
  145. updateWindow();
  146. }
  147.  
  148. end();
  149. }
  150.  
  151. void Game::app::end() {
  152.  
  153. std::wcout << L"Game over!nScore: " << board.score() << L'n';
  154. std::this_thread::sleep_for((std::chrono::milliseconds)3000);
  155. }
  156.  
  157. #pragma once
  158.  
  159. #include <SFML/Graphics.hpp>
  160. #include "Snake.h"
  161.  
  162. class Board {
  163. public:
  164.  
  165. Board();
  166. ~Board() = default;
  167.  
  168. void update(bool* iscrashed);
  169. void changeDirection(char input);
  170.  
  171. char operator[](int i) const;
  172. int score() const;
  173. int at(Coord coord) const;
  174.  
  175. static constexpr int width = 20;
  176. static constexpr int height = 15;
  177.  
  178. static enum Tile {
  179. OPEN = 1,
  180. WALL = 2,
  181. SNAKE = 3,
  182. FOOD = 4
  183. };
  184.  
  185. private:
  186.  
  187.  
  188. // MEMBER VARIABLES
  189. Snake snake;
  190. std::string map;
  191. int m_score = 0;
  192.  
  193. // MEMBER FUNCTIONS
  194.  
  195. Coord openRandom(); // Finds a random open cell
  196. bool place(Coord coord, Tile item); // Sets a cell a certain value
  197. bool isEmpty(Coord coord) const;
  198.  
  199. };
  200.  
  201. #include "Board.h"
  202.  
  203. #include <random>
  204.  
  205. Board::Board()
  206. : map(static_cast<size_t>(width * height), static_cast<char>(OPEN)) {
  207.  
  208. // Sets top and bottom walls
  209. for (size_t i = 0; i < width; ++i) {
  210. place({ i, 0 }, WALL);
  211. place({ i, height - 1 }, WALL);
  212. }
  213.  
  214. // Sets side walls
  215. for (size_t j = 1; j < height - 1; ++j) {
  216. place({ 0, j }, WALL);
  217. place({ width - 1, j }, WALL);
  218. }
  219.  
  220. place(snake.headLocation(), SNAKE);
  221. place(snake.add(), SNAKE);
  222.  
  223. place(openRandom(), FOOD);
  224. }
  225.  
  226. int Board::at(Coord coord) const {
  227. return map[coord.y * width + coord.x];
  228. }
  229.  
  230. bool Board::isEmpty(Coord coord) const {
  231. return at(coord) == OPEN;
  232. }
  233.  
  234. // Sets a cell a certain value
  235. bool Board::place(Coord coord, Tile item) {
  236. if (item != OPEN && !isEmpty(coord))
  237. return false;
  238.  
  239. map[coord.y * width + coord.x] = item;
  240. return true;
  241. }
  242.  
  243. Coord Board::openRandom() {
  244.  
  245. std::random_device rd;
  246. std::mt19937 gen(rd());
  247.  
  248. std::uniform_int_distribution<unsigned int> disX(1, width - 2);
  249. std::uniform_int_distribution<unsigned int> disY(1, height - 2);
  250.  
  251. Coord coord = { disX(gen), disY(gen) };
  252.  
  253. while (!isEmpty(coord)) {
  254. coord = { disX(gen), disY(gen) };
  255. }
  256.  
  257. return coord;
  258. }
  259.  
  260. void Board::update(bool* iscrashed) {
  261. auto newHead{ snake.moveHead() };
  262. place(snake.follow(), OPEN);
  263.  
  264. switch (at(snake.headLocation())) {
  265. case WALL:
  266. case SNAKE:
  267. *iscrashed = true;
  268. break;
  269.  
  270. case FOOD:
  271. place(snake.headLocation(), OPEN);
  272. place(snake.add(), SNAKE);
  273. m_score += 100;
  274.  
  275. place(openRandom(), FOOD);
  276. }
  277.  
  278. place(newHead, SNAKE);
  279. }
  280.  
  281. void Board::changeDirection(char input) {
  282. snake.changeDirection(input);
  283. }
  284.  
  285. char Board::operator[](int i) const { return map[i]; }
  286. int Board::score() const { return m_score; }
  287.  
  288. #pragma once
  289.  
  290. #include <vector>
  291.  
  292. #include "Coord.h"
  293.  
  294. class Snake {
  295. public:
  296.  
  297. Snake();
  298. ~Snake() = default;
  299.  
  300. // Changes the dir value based on the input
  301. void changeDirection(char input);
  302.  
  303. // Adds a piece to the snake and returns its location
  304. Coord add();
  305. size_t size();
  306.  
  307. /* Moves all pieces and returns
  308. the previous position of last piece */
  309. Coord follow();
  310. Coord moveHead(); // Moves and returns position of new head
  311. Coord headLocation() const;
  312.  
  313. private:
  314.  
  315. // MEMBER VARIABLES
  316. struct Snake_segment
  317. {
  318. Coord current, previous;
  319. };
  320.  
  321. enum direction {
  322. UP = 0,
  323. RIGHT,
  324. DOWN,
  325. LEFT
  326. };
  327.  
  328. std::vector<Snake_segment> snakeContainer;
  329. direction dir;
  330. };
  331.  
  332. #include "Snake.h"
  333.  
  334. // Initializes a two-piece snake
  335. Snake::Snake()
  336. : dir { RIGHT } {
  337.  
  338. Snake_segment head{ {10, 7}, {9, 7} };
  339. snakeContainer.push_back(head);
  340.  
  341. --head.current.x;
  342. snakeContainer.push_back(head);
  343. }
  344.  
  345. Coord Snake::add() {
  346. snakeContainer.push_back({
  347. snakeContainer.back().previous,
  348. snakeContainer.back().previous
  349. });
  350.  
  351. return snakeContainer.back().current;
  352. }
  353.  
  354. size_t Snake::size() {
  355. return snakeContainer.size();
  356. }
  357.  
  358. // Changes the direction based on input (BUGGED)
  359. void Snake::changeDirection(char input) {
  360. switch (input) {
  361. case 'w':
  362. if (dir != DOWN) dir = UP;
  363. break;
  364.  
  365. case 'd':
  366. if (dir != LEFT) dir = RIGHT;
  367. break;
  368.  
  369. case 's':
  370. if (dir != UP) dir = DOWN;
  371. break;
  372.  
  373. case 'a':
  374. if (dir != RIGHT) dir = LEFT;
  375.  
  376. }
  377. }
  378.  
  379. // All the pieces follow the head
  380. Coord Snake::follow() {
  381.  
  382. auto it = snakeContainer.begin();
  383. for (auto prev = it++; it != snakeContainer.end(); ++it, ++prev) {
  384. it->previous = it->current;
  385. it->current = prev->previous;
  386. }
  387.  
  388. return snakeContainer.back().previous;
  389. }
  390.  
  391.  
  392. Coord Snake::moveHead() {
  393.  
  394. snakeContainer[0].previous = snakeContainer[0].current;
  395.  
  396. switch (dir) {
  397. case UP:
  398. --snakeContainer.front().current.y;
  399. break;
  400.  
  401. case RIGHT:
  402. ++snakeContainer.front().current.x;
  403. break;
  404.  
  405. case DOWN:
  406. ++snakeContainer.front().current.y;
  407. break;
  408.  
  409. case LEFT:
  410. --snakeContainer.front().current.x;
  411.  
  412. }
  413.  
  414. return snakeContainer.front().current;
  415. }
  416.  
  417. Coord Snake::headLocation() const { return snakeContainer.front().current; }
  418.  
  419. #pragma once
  420.  
  421. struct Coord {
  422. unsigned int x, y;
  423. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement