Compare commits
2 Commits
f641112a2d
...
fd8c091872
| Author | SHA1 | Date | |
|---|---|---|---|
| fd8c091872 | |||
| 49dc1aecd1 |
23
README.md
23
README.md
@@ -1,3 +1,22 @@
|
||||
# ASCII-G
|
||||
# ASCII-G - The Cookies Edition
|
||||
|
||||
A Super Cool Initial (not so) Interesting Game. Simple and turn-based.
|
||||
Текстовый квест в терминале. Игрок исследует подземный лабиринт, решает головоломки, открывает сундуки, взаимодействует с NPC и участвует в боях.
|
||||
|
||||
## Возможности
|
||||
|
||||
- 5 ASCII-локаций
|
||||
- головоломки
|
||||
- сундуки
|
||||
- инвентарь
|
||||
- зелья лечения
|
||||
- оружие
|
||||
- NPC и диалоги
|
||||
- боевая система
|
||||
- сохранение и загрузка
|
||||
- логирование событий
|
||||
|
||||
## Сборка
|
||||
|
||||
```bash
|
||||
make run
|
||||
```
|
||||
26
docs/classes.md
Normal file
26
docs/classes.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Документация классов
|
||||
|
||||
## Game
|
||||
|
||||
Основной класс игры. Управляет игровым циклом, загрузкой данных, обработкой команд игрока, перемещением, взаимодействием с сундуками, NPC и боевой системой.
|
||||
|
||||
### Поля
|
||||
|
||||
| Поле | Тип | Описание |
|
||||
|---|---|---|
|
||||
| player | Player | Игрок |
|
||||
| locations | vector<Location> | Список игровых локаций |
|
||||
| itemDatabase | vector<Item> | База предметов |
|
||||
| isRunning | bool | Флаг работы игры |
|
||||
|
||||
### Методы
|
||||
|
||||
| Метод | Описание |
|
||||
|---|---|
|
||||
| run() | Запускает игру |
|
||||
| loadLocations() | Загружает локации из файлов |
|
||||
| loadItems() | Загружает предметы |
|
||||
| processCommand() | Обрабатывает команды игрока |
|
||||
| movePlayer() | Перемещает игрока |
|
||||
| openChest() | Открывает сундук |
|
||||
| startCombat() | Запускает бой |
|
||||
29
docs/methods.md
Normal file
29
docs/methods.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Описание методов
|
||||
|
||||
## Game::movePlayer(int dx, int dy)
|
||||
|
||||
Перемещает игрока на указанное смещение.
|
||||
|
||||
### Входные данные
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
|---|---|---|
|
||||
| dx | int | Смещение по X |
|
||||
| dy | int | Смещение по Y |
|
||||
|
||||
### Возвращаемое значение
|
||||
|
||||
Метод ничего не возвращает.
|
||||
|
||||
---
|
||||
|
||||
## Player::usePotion(int itemId, const vector<Item>& itemDatabase)
|
||||
|
||||
Использует зелье из инвентаря игрока.
|
||||
|
||||
### Входные данные
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
|---|---|---|
|
||||
| itemId | int | ID предмета |
|
||||
| itemDatabase | vector<Item> | База всех предметов |
|
||||
9
docs/user_manual.md
Normal file
9
docs/user_manual.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Инструкция пользователя
|
||||
|
||||
## Запуск игры
|
||||
|
||||
### Windows / Linux
|
||||
|
||||
```bash
|
||||
make run
|
||||
```
|
||||
8
include/logger.h
Normal file
8
include/logger.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
static void log(const std::string& message);
|
||||
};
|
||||
5
logs/game.log
Normal file
5
logs/game.log
Normal file
@@ -0,0 +1,5 @@
|
||||
[2026-06-11 15:28:07] Game started
|
||||
[2026-06-11 15:28:09] New game started. Player name: Zero
|
||||
[2026-06-11 15:28:12] Player opened chest in location: Entrance Hall
|
||||
[2026-06-11 15:28:12] Player received item ID: 101
|
||||
[2026-06-11 15:28:12] Player received item ID: 101
|
||||
18
src/game.cpp
18
src/game.cpp
@@ -1,10 +1,12 @@
|
||||
#include "../include/game.h"
|
||||
#include "../include/save_manager.h"
|
||||
#include "../include/logger.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
void Game::run() {
|
||||
Logger::log("Game started");
|
||||
loadItems();
|
||||
loadLocations();
|
||||
showMainMenu();
|
||||
@@ -13,6 +15,8 @@ void Game::run() {
|
||||
render();
|
||||
processCommand();
|
||||
}
|
||||
|
||||
Logger::log("Game closed");
|
||||
}
|
||||
|
||||
void Game::loadLocations() {
|
||||
@@ -69,11 +73,13 @@ void Game::showMainMenu() {
|
||||
}
|
||||
|
||||
std::cout << ">>> Created new character " << player.name << "!\n";
|
||||
Logger::log("New game started. Player name: " + player.name);
|
||||
break;
|
||||
}
|
||||
else if (str == "2") {
|
||||
if (SaveManager::loadGame(player, "saves/save.txt")) {
|
||||
std::cout << ">>> Game loaded.\n";
|
||||
Logger::log("New game started. Player name: " + player.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -149,6 +155,7 @@ void Game::processCommand() {
|
||||
else if (command == "save") {
|
||||
if (SaveManager::saveGame(player, "saves/save.txt")) {
|
||||
std::cout << "Game saved.\n";
|
||||
Logger::log("Game saved");
|
||||
}
|
||||
}
|
||||
else if (command == "load") {
|
||||
@@ -233,6 +240,7 @@ void Game::handleTile(char tile) {
|
||||
if (newLocation != nullptr) {
|
||||
player.position = newLocation->startPosition;
|
||||
std::cout << "You entered: " << newLocation->title << "\n";
|
||||
Logger::log("Player entered location: " + newLocation->title);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -252,9 +260,10 @@ bool Game::solveRiddle(Location& location) {
|
||||
if (answer == location.riddle.answer) {
|
||||
std::cout << "Correct.\n";
|
||||
location.riddle.isSolved = true;
|
||||
Logger::log("Riddle solved in location: " + location.title);
|
||||
return true;
|
||||
}
|
||||
|
||||
Logger::log("Wrong riddle answer in location: " + location.title);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -318,10 +327,12 @@ void Game::openChest(Location& location) {
|
||||
}
|
||||
|
||||
std::cout << "You opened the chest.\n";
|
||||
Logger::log("Player opened chest in location: " + location.title);
|
||||
|
||||
for (int itemId : chest.itemIds) {
|
||||
player.inventory.addItem(itemId);
|
||||
std::cout << "Received item ID: " << itemId << "\n";
|
||||
Logger::log("Player received item ID: " + std::to_string(itemId));
|
||||
}
|
||||
|
||||
chest.opened = true;
|
||||
@@ -363,6 +374,7 @@ void Game::applyDialogResult(NPC& npc, const DialogOption& option) {
|
||||
|
||||
void Game::startCombat(NPC& npc) {
|
||||
std::cout << "\nCombat started with " << npc.name << "!\n";
|
||||
Logger::log("Combat started with NPC: " + npc.name);
|
||||
|
||||
while (player.hp > 0 && npc.hp > 0) {
|
||||
std::cout << "\nYour HP: " << player.hp << "\n";
|
||||
@@ -385,6 +397,7 @@ void Game::startCombat(NPC& npc) {
|
||||
if (npc.hp <= 0) {
|
||||
npc.defeated = true;
|
||||
std::cout << "You defeated " << npc.name << ".\n";
|
||||
Logger::log("NPC defeated: " + npc.name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -393,6 +406,7 @@ void Game::startCombat(NPC& npc) {
|
||||
}
|
||||
else if (choice == 3) {
|
||||
std::cout << "You ran away.\n";
|
||||
Logger::log("Player escaped from combat with: " + npc.name);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@@ -405,6 +419,7 @@ void Game::startCombat(NPC& npc) {
|
||||
|
||||
if (player.hp <= 0) {
|
||||
std::cout << "You died.\n";
|
||||
Logger::log("Player died in combat with: " + npc.name);
|
||||
isRunning = false;
|
||||
return;
|
||||
}
|
||||
@@ -437,6 +452,7 @@ void Game::interactWithNPC(Location& location) {
|
||||
|
||||
int choice;
|
||||
std::cin >> choice;
|
||||
Logger::log("Player selected dialog option with NPC: " + npc.name);
|
||||
|
||||
if (choice < 1 || choice > npc.options.size()) {
|
||||
std::cout << "Invalid dialog option.\n";
|
||||
|
||||
22
src/logger.cpp
Normal file
22
src/logger.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "../include/logger.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
|
||||
void Logger::log(const std::string& message) {
|
||||
std::ofstream file("logs/game.log", std::ios::app);
|
||||
|
||||
if (!file.is_open()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::time_t now = std::time(nullptr);
|
||||
std::tm* localTime = std::localtime(&now);
|
||||
|
||||
file << "["
|
||||
<< std::put_time(localTime, "%Y-%m-%d %H:%M:%S")
|
||||
<< "] "
|
||||
<< message
|
||||
<< "\n";
|
||||
}
|
||||
Reference in New Issue
Block a user