#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include "TXLib.h"
const int CELL_SIZE = 50; // Размер ячейки игрового поля
const int INVENTORY_SIZE = 5; // Размер инвентаря электрика
const int MAX_LEVELS = 10; // Количество уровней игры
struct Point
{
int x;
int y;
};
struct Wire
{
Point start;
Point end;
int length;
};
struct Socket
{
Point position;
int power;
};
struct Lamp
{
Point position;
int power;
};
class Game
{
public:
Game();
void run();
private:
void loadLevels();
void loadLevel(int level);
void drawGame();
void drawInventory();
void drawSettings();
void drawRating();
void handleInput();
void connectWires();
void checkWin();
void gameOver();
void saveRating();
void loadRating();
void showRating();
std::vector<std::vector<int>> levels;
std::vector<Wire> wires;
std::vector<Socket> sockets;
std::vector<Lamp> lamps;
std::vector<Wire> inventory;
std::string playerName;
int currentLevel;
int score;
bool gameRunning;
bool settingsOpen;
bool ratingOpen;
};
Game::Game()
{
currentLevel = 0;
score = 0;
gameRunning = false;
settingsOpen = false;
ratingOpen = false;
}
void Game::loadLevels()
{
std::ifstream file("levels.txt");
if (!file)
{
std::cout << "Failed to open levels file." << std::endl;
return;
}
std::string line;
while (std::getline(file, line))
{
std::vector<int> level;
for (char c : line)
{
level.push_back(c - '0');
}
levels.push_back(level);
}
file.close();
}
void Game::loadLevel(int level)
{
wires.clear();
sockets.clear();
lamps.clear();
inventory.clear();
std::vector<int> levelData = levels[level];
int width = levelData[0];
int height = levelData[1];
int index = 2;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int cell = levelData[index++];
if (cell == 1)
{
Socket socket;
socket.position = { x, y };
socket.power = levelData[index++];
sockets.push_back(socket);
}
else if (cell == 2)
{
Lamp lamp;
lamp.position = { x, y };
lamp.power = levelData[index++];
lamps.push_back(lamp);
}
}
}
}
void Game::drawGame()
{
txSetFillColor(TX_WHITE);
txClear();
// Отрисовка игрового поля
for (int y = 0; y < levels[currentLevel][1]; y++)
{
for (int x = 0; x < levels[currentLevel][0]; x++)
{
txRectangle(x * CELL_SIZE, y * CELL_SIZE, (x + 1) * CELL_SIZE, (y + 1) * CELL_SIZE);
}
}
// Отрисовка проводов
for (const Wire& wire : wires)
{
txSetColor(TX_BLACK);
txSetFillColor(TX_BLACK);
txRectangle(wire.start.x * CELL_SIZE, wire.start.y * CELL_SIZE, wire.end.x * CELL_SIZE, wire.end.y * CELL_SIZE);
}
// Отрисовка розеток
for (const Socket& socket : sockets)
{
txSetColor(TX_BLUE);
txSetFillColor(TX_BLUE);
txRectangle(socket.position.x * CELL_SIZE, socket.position.y * CELL_SIZE, (socket.position.x + 1) * CELL_SIZE, (socket.position.y + 1) * CELL_SIZE);
txTextOut(socket.position.x * CELL_SIZE + 5, socket.position.y * CELL_SIZE + 5, std::to_string(socket.power).c_str());
}
// Отрисовка лампочек
for (const Lamp& lamp : lamps)
{
txSetColor(TX_YELLOW);
txSetFillColor(TX_YELLOW);
txRectangle(lamp.position.x * CELL_SIZE, lamp.position.y * CELL_SIZE, (lamp.position.x + 1) * CELL_SIZE, (lamp.position.y + 1) * CELL_SIZE);
txTextOut(lamp.position.x * CELL_SIZE + 5, lamp.position.y * CELL_SIZE + 5, std::to_string(lamp.power).c_str());
}
// Отрисовка инвентаря
drawInventory();
// Отрисовка настроек
if (settingsOpen)
{
drawSettings();
}
// Отрисовка рейтинга
if (ratingOpen)
{
drawRating();
}
}
void Game::drawInventory()
{
int x = 0;
int y = levels[currentLevel][1] * CELL_SIZE + 10;
for (const Wire& wire : inventory)
{
txSetColor(TX_BLACK);
txSetFillColor(TX_BLACK);
txRectangle(x, y, x + wire.length * CELL_SIZE, y + CELL_SIZE);
txTextOut(x + 5, y + 5, std::to_string(wire.length).c_str());
x += wire.length * CELL_SIZE + 10;
}
}
void Game::drawSettings()
{
// Отрисовка окна настроек
txSetColor(TX_BLACK);
txSetFillColor(TX_WHITE);
txRectangle(100, 100, 500, 300);
// Отрисовка элементов окна настроек
txTextOut(150, 150, "Player Name:");
txTextOut(150, 200, "Difficulty:");
// Отрисовка кнопки сохранения настроек
txSetColor(TX_BLACK);
txSetFillColor(TX_LIGHTGRAY);
txRectangle(200, 250, 300, 280);
txTextOut(220, 260, "Save");
// Отрисовка текущих настроек
txTextOut(300, 150, playerName.c_str());
txTextOut(300, 200, "Normal");
}
void Game::drawRating()
{
// Отрисовка окна рейтинга
txSetColor(TX_BLACK);
txSetFillColor(TX_WHITE);
txRectangle(100, 100, 500, 300);
// Отрисовка элементов окна рейтинга
txTextOut(150, 150, "Player Name");
txTextOut(300, 150, "Games Played");
txTextOut(400, 150, "Score");
// Отрисовка кнопки закрытия рейтинга
txSetColor(TX_BLACK);
txSetFillColor(TX_LIGHTGRAY);
txRectangle(200, 250, 300, 280);
txTextOut(220, 260, "Close");
// Отрисовка рейтинга
txTextOut(150, 170, "Player 1");
txTextOut(300, 170, "10");
txTextOut(400, 170, "1000");
}
void Game::handleInput()
{
if (txMouseButtons() & 1)
{
POINT mousePos = txMousePos();
int mouseX = mousePos.x;
int mouseY = mousePos.y;
// Обработка клика по игровому полю
if (mouseY < levels[currentLevel][1] * CELL_SIZE)
{
int cellX = mouseX / CELL_SIZE;
int cellY = mouseY / CELL_SIZE;
// Проверка, что выбранная ячейка является розеткой
for (const Socket& socket : sockets)
{
if (socket.position.x == cellX && socket.position.y == cellY)
{
// Проверка, что есть выбранный провод в инвентаре
if (!inventory.empty())
{
Wire wire;
wire.start = { cellX, cellY };
wire.end = { cellX, cellY };
wire.length = inventory.back().length;
wires.push_back(wire);
inventory.pop_back();
}
break;
}
}
}
// Обработка клика по инвентарю
else if (mouseY < levels[currentLevel][1] * CELL_SIZE + CELL_SIZE)
{
int x = 0;
int y = levels[currentLevel][1] * CELL_SIZE + 10;
for (int i = 0; i < inventory.size(); i++)
{
int wireLength = inventory[i].length;
if (mouseX >= x && mouseX <= x + wireLength * CELL_SIZE && mouseY >= y && mouseY <= y + CELL_SIZE)
{
// Перемещение выбранного провода в конец инвентаря
Wire selectedWire = inventory[i];
inventory.erase(inventory.begin() + i);
inventory.push_back(selectedWire);
break;
}
x += wireLength * CELL_SIZE + 10;
}
}
// Обработка клика по кнопке настроек
else if (mouseY >= levels[currentLevel][1] * CELL_SIZE + CELL_SIZE && mouseY <= levels[currentLevel][1] * CELL_SIZE + 2 * CELL_SIZE)
{
settingsOpen = !settingsOpen;
}
// Обработка клика по кнопке рейтинга
else if (mouseY >= levels[currentLevel][1] * CELL_SIZE + 2 * CELL_SIZE && mouseY <= levels[currentLevel][1] * CELL_SIZE + 3 * CELL_SIZE)
{
ratingOpen = !ratingOpen;
}
// Обработка клика по кнопке сохранения настроек
else if (settingsOpen && mouseX >= 200 && mouseX <= 300 && mouseY >= 250 && mouseY <= 280)
{
playerName = "Player 1"; // Заглушка, сохранение настроек игрока
settingsOpen = false;
}
// Обработка клика по кнопке закрытия рейтинга
else if (ratingOpen && mouseX >= 200 && mouseX <= 300 && mouseY >= 250 && mouseY <= 280)
{
ratingOpen = false;
}
}
}
void Game::connectWires()
{
for (Wire& wire : wires)
{
for (const Socket& socket : sockets)
{
if (wire.start.x == socket.position.x && wire.start.y == socket.position.y)
{
wire.start = socket.position;
break;
}
}
for (const Lamp& lamp : lamps)
{
if (wire.end.x == lamp.position.x && wire.end.y == lamp.position.y)
{
wire.end = lamp.position;
break;
}
}
}
}
void Game::checkWin()
{
bool allConnected = true;
for (const Wire& wire : wires)
{
bool connected = false;
for (const Socket& socket : sockets)
{
if (wire.start.x == socket.position.x && wire.start.y == socket.position.y)
{
connected = true;
break;
}
}
if (!connected)
{
allConnected = false;
break;
}
}
if (allConnected)
{
score++;
currentLevel++;
if (currentLevel >= MAX_LEVELS)
{
gameRunning = false;
}
else
{
loadLevel(currentLevel);
}
}
}
void Game::gameOver()
{
gameRunning = false;
saveRating();
}
void Game::saveRating()
{
std::ofstream file("rating.txt", std::ios::app);
if (!file)
{
std::cout << "Failed to open rating file." << std::endl;
return;
}
file << playerName << " " << score << std::endl;
file.close();
}
void Game::loadRating()
{
std::ifstream file("rating.txt");
if (!file)
{
std::cout << "Failed to open rating file." << std::endl;
return;
}
std::string line;
while (std::getline(file, line))
{
std::cout << line << std::endl;
}
file.close();
}
void Game::showRating()
{
ratingOpen = true;
loadRating();
}
void Game::run()
{
txCreateWindow(400, 450);
//txSetFillColor(TX_WHITE);
loadLevels();
loadLevel(currentLevel);
gameRunning = true;
while (gameRunning)
{
drawGame();
handleInput();
connectWires();
checkWin();
txSleep(10);
}
showRating();
}
int main()
{
Game game;
game.run();
return 0;
}