Advertisement
sigmachto

Untitled

May 31st, 2024
34
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.47 KB | None | 0 0
  1. #include <SFML/Graphics.hpp>
  2. #include <iostream>
  3. #include <vector>
  4. #include <iomanip>
  5. #include <fstream>
  6.  
  7. const int SIZE = 8;
  8. const int TILE_SIZE = 80;
  9. const int WINDOW_SIZE = SIZE * TILE_SIZE;
  10. const sf::Color LIGHT_COLOR = sf::Color(0xFA, 0xFA, 0xFA); // light purple
  11. const sf::Color DARK_COLOR = sf::Color(0xE6, 0xB0, 0xE6); // dark purple
  12. const sf::Color HIGHLIGHT_COLOR = sf::Color(0x93, 0x70, 0xDB, 128); // semi-transparent purple
  13. const sf::Color KNIGHT_COLOR = sf::Color(0x80, 0x00, 0x80); // dark purple
  14.  
  15. sf::Vector2i knightPosition = { -1, -1 };
  16. std::vector<sf::Vector2i> knightMoves;
  17. std::vector<sf::Vector2i> moveHistory;
  18. bool visited[SIZE][SIZE] = { false };
  19. int moveCounter[SIZE][SIZE] = { 0 };
  20. int moveNumber = 1;
  21. float bestTime = -1.0f;
  22. bool gameStarted = false;
  23. bool gameOver = false;
  24.  
  25. bool isMoveValid(int x, int y) {
  26. return x >= 0 && x < SIZE && y >= 0 && y < SIZE && !visited[x][y];
  27. }
  28.  
  29. std::vector<sf::Vector2i> getValidMoves(sf::Vector2i pos) {
  30. std::vector<sf::Vector2i> moves;
  31. int dx[] = { 1, 2, 2, 1, -1, -2, -2, -1 };
  32. int dy[] = { 2, 1, -1, -2, -2, -1, 1, 2 };
  33.  
  34. for (int i = 0; i < 8; ++i) {
  35. int newX = pos.x + dx[i];
  36. int newY = pos.y + dy[i];
  37. if (isMoveValid(newX, newY)) {
  38. moves.push_back({ newX, newY });
  39. }
  40. }
  41. return moves;
  42. }
  43.  
  44. bool isMoveInValidMoves(const sf::Vector2i& pos) {
  45. for (const auto& move : knightMoves) {
  46. if (move == pos) {
  47. return true;
  48. }
  49. }
  50. return false;
  51. }
  52.  
  53. bool isGameOver() {
  54. for (int i = 0; i < SIZE; ++i) {
  55. for (int j = 0; j < SIZE; ++j) {
  56. if (!visited[i][j]) {
  57. return false;
  58. }
  59. }
  60. }
  61. return true;
  62. }
  63. void drawKnight(sf::RenderWindow& window, sf::Vector2i position) {
  64. sf::RectangleShape body(sf::Vector2f(TILE_SIZE * 0.6f, TILE_SIZE * 0.3f));
  65. body.setFillColor(KNIGHT_COLOR);
  66. body.setPosition(position.x * TILE_SIZE + TILE_SIZE * 0.2f, position.y * TILE_SIZE + TILE_SIZE * 0.4f);
  67.  
  68. sf::CircleShape head(TILE_SIZE * 0.2f);
  69. head.setFillColor(KNIGHT_COLOR);
  70. head.setPosition(position.x * TILE_SIZE + TILE_SIZE * 0.4f, position.y * TILE_SIZE + TILE_SIZE * 0.1f);
  71.  
  72. sf::RectangleShape ear1(sf::Vector2f(TILE_SIZE * 0.05f, TILE_SIZE * 0.1f));
  73. ear1.setFillColor(KNIGHT_COLOR);
  74. ear1.setPosition(position.x * TILE_SIZE + TILE_SIZE * 0.35f, position.y * TILE_SIZE + TILE_SIZE * 0.1f);
  75.  
  76. sf::RectangleShape ear2(sf::Vector2f(TILE_SIZE * 0.05f, TILE_SIZE * 0.1f));
  77. ear2.setFillColor(KNIGHT_COLOR);
  78. ear2.setPosition(position.x * TILE_SIZE + TILE_SIZE * 0.6f, position.y * TILE_SIZE + TILE_SIZE * 0.1f);
  79.  
  80. window.draw(body);
  81. window.draw(head);
  82. window.draw(ear1);
  83. window.draw(ear2);
  84. }
  85.  
  86. void drawBoard(sf::RenderWindow& window, sf::Font& font, float timer) {
  87. window.clear();
  88.  
  89. for (int i = 0; i < SIZE; ++i) {
  90. for (int j = 0; j < SIZE; ++j) {
  91. sf::RectangleShape tile(sf::Vector2f(TILE_SIZE, TILE_SIZE));
  92. tile.setPosition(i * TILE_SIZE, j * TILE_SIZE);
  93. tile.setFillColor((i + j) % 2 == 0 ? LIGHT_COLOR : DARK_COLOR);
  94. window.draw(tile);
  95.  
  96. if (visited[i][j]) {
  97. sf::Text text;
  98. text.setFont(font);
  99. text.setString(std::to_string(moveCounter[i][j]));
  100. text.setCharacterSize(24);
  101. text.setFillColor(sf::Color::Red);
  102. text.setPosition(i * TILE_SIZE + TILE_SIZE / 3, j * TILE_SIZE + TILE_SIZE / 5);
  103. window.draw(text);
  104. }
  105. }
  106. }
  107.  
  108. for (const auto& move : knightMoves) {
  109. sf::RectangleShape highlight(sf::Vector2f(TILE_SIZE, TILE_SIZE));
  110. highlight.setPosition(move.x * TILE_SIZE, move.y * TILE_SIZE);
  111. highlight.setFillColor(HIGHLIGHT_COLOR);
  112. window.draw(highlight);
  113. }
  114.  
  115. if (knightPosition.x >= 0 && knightPosition.y >= 0) {
  116. sf::CircleShape knight(TILE_SIZE / 2);
  117. knight.setPosition(knightPosition.x * TILE_SIZE, knightPosition.y * TILE_SIZE);
  118. knight.setFillColor(KNIGHT_COLOR);
  119. window.draw(knight);
  120. }
  121.  
  122. sf::Text timerText;
  123. timerText.setFont(font);
  124. timerText.setString("Time: " + std::to_string(static_cast<int>(timer)));
  125. timerText.setCharacterSize(24);
  126. timerText.setFillColor(sf::Color::Black);
  127. timerText.setPosition(10, 10);
  128. window.draw(timerText);
  129.  
  130. if (bestTime > 0.0f) {
  131. sf::Text bestTimeText;
  132. bestTimeText.setFont(font);
  133. bestTimeText.setString("Best Time: " + std::to_string(static_cast<int>(bestTime)));
  134. bestTimeText.setCharacterSize(24);
  135. bestTimeText.setFillColor(sf::Color::Black);
  136. bestTimeText.setPosition(10, 40);
  137. window.draw(bestTimeText);
  138. }
  139.  
  140. if (gameOver) {
  141. sf::Text gameOverText;
  142. gameOverText.setFont(font);
  143. gameOverText.setString(isGameOver() ? "You Win!" : "Game Over!");
  144. gameOverText.setCharacterSize(48);
  145. gameOverText.setFillColor(sf::Color::Red);
  146. gameOverText.setPosition(WINDOW_SIZE / 4, WINDOW_SIZE / 2);
  147. window.draw(gameOverText);
  148. }
  149.  
  150. window.display();
  151. }
  152.  
  153. void saveBestTime(float time) {
  154. std::ofstream outFile("best_time.txt");
  155. if (outFile.is_open()) {
  156. outFile << std::fixed << std::setprecision(2) << time;
  157. outFile.close();
  158. bestTime = time;
  159. std::cout << "Best time updated: " << bestTime << " seconds\n";
  160. }
  161. else {
  162. std::cerr << "Error: Unable to open best_time.txt for writing\n";
  163. }
  164. }
  165.  
  166. float loadBestTime() {
  167. std::ifstream inFile("best_time.txt");
  168. float time;
  169. if (inFile.is_open()) {
  170. inFile >> time;
  171. inFile.close();
  172. return time;
  173. }
  174. else {
  175. std::cerr << "Error: Unable to open best_time.txt for reading\n";
  176. return -1.0f;
  177. }
  178. }
  179.  
  180. void undoMove() {
  181. if (moveHistory.size() > 1) {
  182. sf::Vector2i lastMove = moveHistory.back();
  183. moveHistory.pop_back();
  184. visited[lastMove.x][lastMove.y] = false;
  185. moveCounter[lastMove.x][lastMove.y] = 0;
  186. knightPosition = moveHistory.back();
  187. moveNumber--;
  188. knightMoves = getValidMoves(knightPosition);
  189. }
  190. }
  191.  
  192. void resetGame() {
  193. knightPosition = { -1, -1 };
  194. knightMoves.clear();
  195. moveHistory.clear();
  196. std::fill(&visited[0][0], &visited[0][0] + sizeof(visited) / sizeof(bool), false);
  197. std::fill(&moveCounter[0][0], &moveCounter[0][0] + sizeof(moveCounter) / sizeof(int), 0);
  198. moveNumber = 1;
  199. gameStarted = false;
  200. gameOver = false;
  201. }
  202.  
  203. int main() {
  204. sf::RenderWindow window(sf::VideoMode(WINDOW_SIZE, WINDOW_SIZE), "Knight's Tour");
  205. sf::Clock clock;
  206. float timer = 0.0f;
  207. bestTime = loadBestTime();
  208.  
  209.  
  210. sf::Font font;
  211. if (!font.loadFromFile("arial.ttf")) {
  212. std::cerr << "Error loading arial.ttf\n";
  213. return -1;
  214. }
  215.  
  216. while (window.isOpen()) {
  217. sf::Event event;
  218. while (window.pollEvent(event)) {
  219. if (event.type == sf::Event::Closed) {
  220. window.close();
  221. }
  222. if (event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left) {
  223. int mouseX = event.mouseButton.x / TILE_SIZE;
  224. int mouseY = event.mouseButton.y / TILE_SIZE;
  225. if (mouseX >= 0 && mouseX < SIZE && mouseY >= 0 && mouseY < SIZE) {
  226. if (!gameStarted) {
  227. knightPosition = { mouseX, mouseY };
  228. visited[mouseX][mouseY] = true;
  229. moveCounter[mouseX][mouseY] = moveNumber++;
  230. moveHistory.push_back(knightPosition);
  231. knightMoves = getValidMoves(knightPosition);
  232. gameStarted = true;
  233. gameOver = false;
  234. clock.restart();
  235. }
  236. else if (isMoveInValidMoves({ mouseX, mouseY })) {
  237. knightPosition = { mouseX, mouseY };
  238. visited[mouseX][mouseY] = true;
  239. moveCounter[mouseX][mouseY] = moveNumber++;
  240. moveHistory.push_back(knightPosition);
  241. knightMoves = getValidMoves(knightPosition);
  242.  
  243. if (isGameOver()) {
  244. std::cout << "You Win!\n";
  245. if (bestTime < 0.0f || timer < bestTime) {
  246. saveBestTime(timer);
  247. }
  248. gameOver = true;
  249. gameStarted = false;
  250. }
  251. }
  252. }
  253. }
  254. if (event.type == sf::Event::KeyPressed) {
  255. if (event.key.code == sf::Keyboard::U) {
  256. undoMove();
  257. }
  258. if (event.key.code == sf::Keyboard::R) {
  259. resetGame();
  260. }
  261. }
  262. }
  263.  
  264. if (gameStarted) {
  265. timer += clock.restart().asSeconds();
  266. }
  267. else {
  268. clock.restart();
  269. }
  270.  
  271. drawBoard(window, font, timer);
  272.  
  273. if (gameStarted && knightMoves.empty() && !isGameOver()) {
  274. std::cout << "No valid moves left. Game Over!\n";
  275. gameOver = true;
  276. gameStarted = false;
  277. }
  278. }
  279.  
  280. return 0;
  281. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement