delete函数中的hasrecipe变量似乎并没有用到。
修理好报错后的代码:
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <set>
#include <string>
#include <windows.h>
#include <filesystem>
#include <shlobj.h>
#include <iomanip>
#include <algorithm>
#include <queue>
#include <cctype>
#include <cmath>
#include <climits>
#include <sstream>
#include <functional>
using namespace std;
namespace fs = filesystem;
// 类型别名简化
using CraftGrid = pair<string, short>[3][3];
using MaterialMap = map<string, long long>;
// 计算模式枚举
enum CalculationMode {
EXACT // 精确计算
};
// 全局配置
const string CONFIG_FILE = "save_path.cfg";
fs::path savePath;
map<string, int> minPathLengthCache; // 缓存最小路径长度
// 前置声明
class ItemTable;
class Item;
class ItemCollection;
void LoadSavePath(), SaveSavePath();
void ShowSaveInfo(), SetSavePath(), CreateItem();
void SaveItems(bool);
void LoadItems(), clear(), pause();
bool CreateCraftTable(Item&);
void ShowItemList(), ShowItemRecipe();
void AddRecipeToItem(), TraceMaterials();
void DeleteItem();
void CalcMaterialsWithMerge(const string&, long long, MaterialMap&, set<string>&,
CalculationMode, map<string, const ItemTable*>&);
int calculatePathLength(const string& id, set<string>& visited, int currentDepth, int minDepth);
vector<const ItemTable*> getShortestPathTables(const string& id);
// 获取程序所在目录
fs::path GetProgramDirectory() {
wchar_t buffer[MAX_PATH] = {0};
GetModuleFileNameW(nullptr, buffer, MAX_PATH);
fs::path exePath(buffer);
return exePath.parent_path();
}
// 获取用户文档目录
fs::path GetDocumentsPath() {
wchar_t path[MAX_PATH];
if (SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_MYDOCUMENTS, nullptr, SHGFP_TYPE_CURRENT, path))) {
return path;
}
return GetProgramDirectory();
}
class ItemTable {
CraftGrid grid;
short count;
public:
ItemTable() : count(0) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
grid[i][j] = make_pair("", 0);
}
}
}
void setItem(short x, short y, const string& id, short c) { grid[x][y] = make_pair(id, c); }
void setCount(short c) { count = c; }
short getCount() const { return count; }
pair<string, short> getItem(short x, short y) const { return grid[x][y]; }
// 从合成表中移除对指定物品的引用
void removeReferencesTo(const string& id) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (grid[i][j].first == id) {
grid[i][j] = make_pair("", 0);
}
}
}
}
// 获取合成表的路径描述
string getPathDescription() const {
stringstream ss;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (grid[i][j].second > 0 && !grid[i][j].first.empty()) {
if (!ss.str().empty()) ss << ", ";
ss << grid[i][j].first << " x" << grid[i][j].second;
}
}
}
return ss.str();
}
};
class Item {
string id;
short maxStack;
vector<ItemTable> tables;
public:
Item(string id = "", short stack = 0) : id(id), maxStack(stack) {}
void addTable(const ItemTable& t) { tables.push_back(t); }
string getID() const { return id; }
short getStack() const { return maxStack; }
const vector<ItemTable>& getTables() const { return tables; }
bool hasRecipe() const { return !tables.empty(); }
// 删除指定索引的合成表
void removeTable(size_t index) {
if (index < tables.size()) {
tables.erase(tables.begin() + index);
}
}
// 从所有合成表中移除对指定物品的引用
void removeReferencesTo(const string& id) {
for (auto& table : tables) {
table.removeReferencesTo(id);
}
}
};
class ItemCollection {
map<string, Item> items;
public:
void add(const Item& it) {
if (!contains(it.getID())) items[it.getID()] = it;
}
Item& operator[](const string& id) {
if (items.find(id) == items.end()) {
items[id] = Item(id, 64);
}
return items[id];
}
bool contains(const string& id) const { return items.find(id) != items.end(); }
size_t size() const { return items.size(); }
void clear() { items.clear(); }
const map<string, Item>& getAll() const { return items; }
// 获取排序后的物品ID列表
vector<string> getSortedIDs() const {
vector<string> ids;
for (const auto& pair : items) {
ids.push_back(pair.first);
}
sort(ids.begin(), ids.end());
return ids;
}
// 删除物品及其所有引用
bool removeItem(const string& id) {
if (!contains(id)) return false;
// 首先从所有物品的合成表中移除对该物品的引用
for (auto& [itemID, item] : items) {
item.removeReferencesTo(id);
}
// 然后删除该物品
items.erase(id);
return true;
}
} itemDB;
// 计算物品的路径长度(带剪枝优化)
int calculatePathLength(const string& id, set<string>& visited,
int currentDepth = 0, int minDepth = INT_MAX) {
// 剪枝:如果当前深度已超过最小深度,直接返回
if (currentDepth > minDepth) {
return INT_MAX;
}
// 检查循环依赖
if (visited.find(id) != visited.end()) {
return 0;
}
visited.insert(id);
if (!itemDB.contains(id)) {
visited.erase(id);
return 0;
}
const Item& item = itemDB.getAll().at(id);
if (item.getTables().empty()) {
visited.erase(id);
return 0;
}
int maxDepth = 0;
for (const auto& table : item.getTables()) {
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
auto [ing, cnt] = table.getItem(x, y);
if (cnt > 0 && !ing.empty()) {
int depth = calculatePathLength(ing, visited, currentDepth + 1, minDepth);
if (depth > maxDepth) {
maxDepth = depth;
}
}
}
}
}
visited.erase(id);
return maxDepth + 1;
}
// 获取所有最短路径的合成表
vector<const ItemTable*> getShortestPathTables(const string& id) {
if (!itemDB.contains(id)) {
return {};
}
const Item& item = itemDB.getAll().at(id);
if (item.getTables().empty()) {
return {};
}
// 计算最小路径长度(带缓存)
if (minPathLengthCache.find(id) == minPathLengthCache.end()) {
set<string> visited;
minPathLengthCache[id] = calculatePathLength(id, visited);
}
int minPathLength = minPathLengthCache[id];
// 收集所有路径长度等于最小值的合成表
vector<const ItemTable*> result;
for (const auto& table : item.getTables()) {
set<string> visited;
int pathLength = 1; // 当前合成表本身算一级
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
auto [ing, cnt] = table.getItem(x, y);
if (cnt > 0 && !ing.empty()) {
int depth = calculatePathLength(ing, visited);
if (depth >= pathLength) {
pathLength = depth + 1;
}
}
}
}
if (pathLength == minPathLength) {
result.push_back(&table);
}
}
return result;
}
// 辅助函数实现
void clear() { system("cls"); }
void pause() { system("pause"); }
void wait(double sec) { Sleep(static_cast<DWORD>(sec * 1000)); }
// 显示网格的辅助函数
void DisplayGrid(const CraftGrid& grid) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
const auto& [id, count] = grid[i][j];
if (count > 0 && !id.empty()) {
cout << setw(15) << left << (id + " x" + to_string(count));
} else {
cout << setw(15) << left << "[空]";
}
}
cout << endl;
}
}
void LoadSavePath() {
ifstream in(CONFIG_FILE);
if (in) {
string pathStr;
getline(in, pathStr);
savePath = fs::u8path(pathStr);
}
if (savePath.empty()) {
savePath = GetProgramDirectory() / "items.dat";
}
}
void SaveSavePath() {
ofstream out(CONFIG_FILE);
if (out) out << savePath.u8string();
}
void ShowSaveInfo() {
clear();
cout << "当前路径: " << savePath.u8string() << "\n物品总数: " << itemDB.size() << endl;
pause();
}
void SetSavePath() {
clear();
cout << "当前路径: " << savePath.u8string() << "\n新路径: ";
cin.ignore();
string newPathStr;
getline(cin, newPathStr);
fs::path newPath = fs::u8path(newPathStr);
if (savePath != newPath) {
if (fs::exists(savePath)) {
cout << "正在移动文件: " << savePath.u8string() << " -> " << newPath.u8string() << endl;
try {
fs::rename(savePath, newPath);
} catch (fs::filesystem_error& e) {
cerr << "移动文件失败: " << e.what() << endl;
}
}
savePath = newPath;
SaveSavePath();
}
cout << "路径已更新!" << endl;
wait(1);
}
// 文件I/O优化(修复编译错误)
void SaveItems(bool showMsg) {
if (showMsg) {
clear();
cout << "保存数据到: " << savePath.u8string() << "..." << endl;
}
try {
if (!savePath.parent_path().empty() && !fs::exists(savePath.parent_path())) {
fs::create_directories(savePath.parent_path());
}
} catch (fs::filesystem_error& e) {
if (showMsg) {
cout << "创建目录失败: " << e.what() << endl;
pause();
}
return;
}
ofstream out(savePath, ios::binary);
if (out) {
size_t count = itemDB.size();
out.write(reinterpret_cast<char*>(&count), sizeof(count));
for (const auto& [id, item] : itemDB.getAll()) {
size_t len = id.size();
out.write(reinterpret_cast<char*>(&len), sizeof(len));
out.write(id.c_str(), len);
short stack = item.getStack();
out.write(reinterpret_cast<const char*>(&stack), sizeof(stack)); // 修复此行
size_t tableCount = item.getTables().size();
out.write(reinterpret_cast<char*>(&tableCount), sizeof(tableCount));
for (const auto& table : item.getTables()) {
short craftCnt = table.getCount();
out.write(reinterpret_cast<const char*>(&craftCnt), sizeof(craftCnt));
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
auto [ing, cnt] = table.getItem(x, y);
// 跳过空槽位
if (cnt <= 0 || ing.empty()) continue;
size_t ingLen = ing.size();
out.write(reinterpret_cast<char*>(&ingLen), sizeof(ingLen));
out.write(ing.c_str(), ingLen);
out.write(reinterpret_cast<const char*>(&cnt), sizeof(cnt));
}
}
}
}
if (showMsg) {
cout << "保存成功! 物品数: " << count << endl;
pause();
}
} else if (showMsg) {
cout << "保存失败! 错误: " << strerror(errno) << endl;
pause();
}
}
void LoadItems() {
clear();
cout << "加载数据: " << savePath.u8string() << "..." << endl;
itemDB.clear();
minPathLengthCache.clear(); // 清除缓存
ifstream in(savePath, ios::binary);
if (in) {
try {
size_t itemCount;
in.read(reinterpret_cast<char*>(&itemCount), sizeof(itemCount));
for (size_t i = 0; i < itemCount; i++) {
size_t len;
in.read(reinterpret_cast<char*>(&len), sizeof(len));
string id(len, ' ');
in.read(&id[0], len);
short stack;
in.read(reinterpret_cast<char*>(&stack), sizeof(stack));
Item item(id, stack);
size_t tableCount;
in.read(reinterpret_cast<char*>(&tableCount), sizeof(tableCount));
for (size_t j = 0; j < tableCount; j++) {
short craftCnt;
in.read(reinterpret_cast<char*>(&craftCnt), sizeof(craftCnt));
ItemTable table;
table.setCount(craftCnt);
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
size_t ingLen;
in.read(reinterpret_cast<char*>(&ingLen), sizeof(ingLen));
string ing(ingLen, ' ');
if (ingLen > 0) {
in.read(&ing[0], ingLen);
}
short cnt;
in.read(reinterpret_cast<char*>(&cnt), sizeof(cnt));
// 处理空槽位
if (ingLen == 0 || ing.empty()) {
table.setItem(x, y, "", 0);
} else {
table.setItem(x, y, ing, cnt);
}
}
}
item.addTable(table);
}
itemDB.add(item);
}
cout << "加载成功! 物品数: " << itemDB.size() << endl;
} catch (...) {
cout << "文件损坏!" << endl;
}
} else {
cout << "加载失败! 错误: " << strerror(errno) << endl;
}
pause();
}
// 合成表创建优化
bool CreateCraftTable(Item& item) {
short tableCount;
cout << "合成表数量: ";
cin >> tableCount;
short success = 0;
for (short i = 0; i < tableCount; i++) {
clear();
cout << "合成表 #" << i+1 << " (输入3行,每行3组'名称 数量',空槽位输入0):\n";
CraftGrid grid;
vector<string> missing;
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
cin >> grid[x][y].first >> grid[x][y].second;
// 处理空槽位:如果数量为0,清空材料名称
if (grid[x][y].second == 0) {
grid[x][y].first = "";
}
// 只检查数量大于0且物品不存在的情况
if (grid[x][y].second > 0 && !itemDB.contains(grid[x][y].first)) {
missing.push_back(grid[x][y].first);
}
}
}
if (!missing.empty()) {
cout << "缺失物品: ";
for (size_t j = 0; j < missing.size(); j++) {
cout << missing[j];
if (j < missing.size() - 1) cout << ", ";
}
cout << "\n重试? (Y/N): ";
char ans;
cin >> ans;
if (ans == 'Y' || ans == 'y') i--;
continue;
}
short outputCnt;
cout << "产出数量: ";
cin >> outputCnt;
ItemTable table;
table.setCount(outputCnt);
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
table.setItem(x, y, grid[x][y].first, grid[x][y].second);
}
}
item.addTable(table);
success++;
cout << "添加成功!" << endl;
wait(1);
}
return success > 0;
}
void CreateItem() {
clear();
string id;
short stack;
char hasTable;
cout << "物品名称: ";
cin >> id;
cout << "最大堆叠: ";
cin >> stack;
cout << "有合成表? (Y/N): ";
cin >> hasTable;
Item item(id, stack);
bool success = true;
if (hasTable == 'Y' || hasTable == 'y') {
success = CreateCraftTable(item);
}
if (success) {
itemDB.add(item);
SaveItems(false);
cout << "物品创建成功! 已保存" << endl;
} else {
cout << "创建失败!" << endl;
}
wait(1);
}
// 支持材料需求合并的计算函数(支持多条最短路径选择)
void CalcMaterialsWithMerge(const string& id, long long count,
MaterialMap& globalMats, set<string>& globalVisited,
CalculationMode mode, map<string, const ItemTable*>& choices) {
// 检查循环依赖
if (globalVisited.find(id) != globalVisited.end()) {
cerr << "循环依赖: " << id << endl;
return;
}
globalVisited.insert(id);
if (!itemDB.contains(id)) {
cerr << "未知物品: " << id << endl;
globalVisited.erase(id);
return;
}
const Item& item = itemDB.getAll().at(id);
if (item.getTables().empty()) {
globalMats[id] += count;
globalVisited.erase(id);
return;
}
// 检查是否已有选择
const ItemTable* tablePtr = nullptr;
if (choices.find(id) != choices.end()) {
tablePtr = choices[id];
} else {
// 获取所有最短路径的合成表
vector<const ItemTable*> shortestTables = getShortestPathTables(id);
if (shortestTables.empty()) {
globalMats[id] += count;
globalVisited.erase(id);
return;
} else if (shortestTables.size() == 1) {
tablePtr = shortestTables[0];
} else {
// 让用户选择合成路径
clear();
cout << "物品 " << id << " 有多个最短路径的合成表:\n";
for (int i = 0; i < (int)shortestTables.size(); i++) {
cout << "路径 " << (i+1) << ": "
<< shortestTables[i]->getPathDescription() << endl;
}
cout << "\n请选择合成路径 (1-" << shortestTables.size() << "): ";
int choice;
cin >> choice;
if (choice < 1 || choice > (int)shortestTables.size()) {
choice = 1;
}
tablePtr = shortestTables[choice-1];
choices[id] = tablePtr;
}
}
if (!tablePtr) {
globalMats[id] += count;
globalVisited.erase(id);
return;
}
const ItemTable& table = *tablePtr;
short craftCnt = table.getCount() > 0 ? table.getCount() : 1;
// 根据模式选择计算方法
long long batches = 0;
if (mode == EXACT) {
double exact = static_cast<double>(count) / craftCnt;
batches = static_cast<long long>(ceil(exact));
}
// 临时存储当前材料的子需求
MaterialMap localMats;
set<string> localVisited;
// 先计算所有子材料需求
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
auto [ing, cnt] = table.getItem(x, y);
if (cnt <= 0 || ing.empty()) continue;
CalcMaterialsWithMerge(ing, batches * cnt, localMats, localVisited, mode, choices);
}
}
// 合并子材料需求到全局映射
for (const auto& [matId, amount] : localMats) {
globalMats[matId] += amount;
}
globalVisited.erase(id);
}
// 查看物品列表
void ShowItemList() {
clear();
if (itemDB.size() == 0) {
cout << "物品数据库为空!" << endl;
pause();
return;
}
vector<string> itemIDs = itemDB.getSortedIDs();
const int nameWidth = 25;
const int stackWidth = 10;
const int recipeWidth = 10;
cout << setw(nameWidth) << left << "物品名称"
<< setw(stackWidth) << left << "最大堆叠"
<< setw(recipeWidth) << left << " 有配方"
<< endl;
cout << string(nameWidth + stackWidth + recipeWidth, '-') << endl;
for (const auto& id : itemIDs) {
const Item& item = itemDB.getAll().at(id);
cout << setw(nameWidth) << left << id
<< setw(stackWidth) << left << item.getStack()
<< setw(recipeWidth) << left << (item.hasRecipe() ? "是" : "否")
<< endl;
}
cout << "\n共 " << itemDB.size() << " 个物品" << endl;
pause();
}
// 查看物品配方
void ShowItemRecipe() {
clear();
if (itemDB.size() == 0) {
cout << "物品数据库为空!" << endl;
pause();
return;
}
string target;
cout << "查看配方的物品: ";
cin >> target;
if (!itemDB.contains(target)) {
cout << "物品不存在!" << endl;
pause();
return;
}
Item& item = itemDB[target];
if (!item.hasRecipe()) {
cout << "该物品没有合成配方!" << endl;
pause();
return;
}
vector<ItemTable>& tables = const_cast<vector<ItemTable>&>(item.getTables());
size_t currentIndex = 0;
const int totalTables = tables.size();
while (true) {
clear();
cout << "配方 #" << currentIndex+1 << "/" << totalTables
<< " - 产出: " << target << " x" << tables[currentIndex].getCount()
<< "\n\n";
CraftGrid grid;
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
grid[x][y] = tables[currentIndex].getItem(x, y);
}
}
DisplayGrid(grid);
cout << "\n所需材料:\n";
map<string, short> materials;
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
const auto& [id, cnt] = grid[x][y];
if (cnt > 0 && !id.empty()) materials[id] += cnt;
}
}
for (const auto& [id, cnt] : materials) {
cout << " - " << id << " x" << cnt << endl;
}
cout << "\n操作: (N)下一页, (P)上一页, (D)删除, (Q)退出";
if (totalTables > 1) {
cout << ", (S)跳转到";
}
cout << ": ";
char choice;
cin >> choice;
choice = toupper(choice);
switch (choice) {
case 'N':
if ((int)currentIndex < totalTables - 1) currentIndex++;
break;
case 'P':
if (currentIndex > 0) currentIndex--;
break;
case 'S':
if (totalTables > 1) {
int index;
cout << "输入配方编号(1-" << totalTables << "): ";
cin >> index;
if (index >= 1 && index <= static_cast<int>(totalTables)) {
currentIndex = index - 1;
}
}
break;
case 'D':
cout << "确认删除当前合成表? (Y/N): ";
char confirm;
cin >> confirm;
if (toupper(confirm) == 'Y') {
tables.erase(tables.begin() + currentIndex);
SaveItems(false);
cout << "合成表已删除!" << endl;
wait(1);
if (tables.empty()) {
cout << "该物品已无合成表,返回主菜单" << endl;
wait(1);
return;
}
if (currentIndex >= tables.size()) {
currentIndex = tables.size() - 1;
}
}
break;
case 'Q':
return;
default:
cout << "无效选项!" << endl;
wait(1);
}
}
}
// 为已有物品添加合成表
void AddRecipeToItem() {
clear();
if (itemDB.size() == 0) {
cout << "物品数据库为空!" << endl;
pause();
return;
}
string target;
cout << "为哪个物品添加合成表: ";
cin >> target;
if (!itemDB.contains(target)) {
cout << "物品不存在!" << endl;
pause();
return;
}
Item& item = itemDB[target];
// 显示现有合成表数量
cout << "当前已有 " << item.getTables().size() << " 个合成表" << endl;
// 创建新合成表
ItemTable newTable;
CraftGrid grid;
vector<string> missing;
cout << "输入新合成表 (3行,每行3组'名称 数量',空槽位输入0):\n";
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
cin >> grid[x][y].first >> grid[x][y].second;
// 处理空槽位
if (grid[x][y].second == 0) {
grid[x][y].first = "";
}
// 只检查有效材料
if (grid[x][y].second > 0 && !itemDB.contains(grid[x][y].first)) {
missing.push_back(grid[x][y].first);
}
}
}
if (!missing.empty()) {
cout << "缺失物品: ";
for (size_t j = 0; j < missing.size(); j++) {
cout << missing[j];
if (j < missing.size() - 1) cout << ", ";
}
cout << "\n添加失败!" << endl;
pause();
return;
}
short outputCnt;
cout << "产出数量: ";
cin >> outputCnt;
newTable.setCount(outputCnt);
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
newTable.setItem(x, y, grid[x][y].first, grid[x][y].second);
}
}
item.addTable(newTable);
SaveItems(false);
cout << "成功为 " << target << " 添加新合成表!" << endl;
wait(1);
}
// 追根求源的材料计算(支持多条最短路径选择)
void TraceMaterials() {
clear();
string target;
long long count;
cout << "目标物品: ";
cin >> target;
cout << "合成数量: ";
cin >> count;
if (!itemDB.contains(target)) {
cout << "物品不存在!" << endl;
pause();
return;
}
// 使用合并计算机制
MaterialMap globalMaterials;
set<string> globalVisited;
map<string, const ItemTable*> choices; // 存储用户选择的合成表
// 使用精确计算模式
CalculationMode mode = EXACT;
CalcMaterialsWithMerge(target, count, globalMaterials, globalVisited, mode, choices);
// 显示结果
clear();
cout << "追根求源 - 合成 " << count << " 个 " << target << " 需要:\n";
cout << "================================\n";
for (const auto& [id, amt] : globalMaterials) {
short stack = itemDB.contains(id) ? itemDB[id].getStack() : 64;
if (stack <= 0) stack = 64;
long long groups = (amt + stack - 1) / stack;
cout << id << ": " << amt << " (" << groups << "组)\n";
}
cout << "================================\n";
pause();
}
// 删除方块功能
void DeleteItem() {
clear();
if (itemDB.size() == 0) {
cout << "物品数据库为空!" << endl;
pause();
return;
}
string target;
cout << "输入要删除的物品名称: ";
cin >> target;
if (!itemDB.contains(target)) {
cout << "物品不存在!" << endl;
pause();
return;
}
// 获取目标物品信息
const Item& item = itemDB[target];
bool hasRecipes = item.hasRecipe();
int recipeCount = item.getTables().size();
// 显示警告信息
cout << "警告: 删除物品 " << target << " 将永久移除以下内容:"
<< "\n- 物品基本信息 (堆叠大小: " << item.getStack() << ")"
<< "\n- " << recipeCount << " 个合成表";
// 检查是否有其他物品依赖此物品
int referenceCount = 0;
for (const auto& [id, otherItem] : itemDB.getAll()) {
for (const auto& table : otherItem.getTables()) {
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
if (table.getItem(x, y).first == target) {
referenceCount++;
}
}
}
}
}
if (referenceCount > 0) {
cout << "\n- " << referenceCount << " 个其他物品的合成表引用";
}
// 确认删除
cout << "\n\n确认删除? (Y/N): ";
char confirm;
cin >> confirm;
if (toupper(confirm) != 'Y') {
cout << "删除操作已取消" << endl;
wait(1);
return;
}
// 执行删除
if (itemDB.removeItem(target)) {
minPathLengthCache.clear(); // 清除路径缓存
SaveItems(false);
cout << "物品 " << target << " 已成功删除!" << endl;
} else {
cout << "删除失败!" << endl;
}
pause();
}
int main() {
LoadSavePath();
clear();
cout << "启动中...\n路径: " << savePath.u8string() << endl;
wait(1);
LoadItems();
while (true) {
clear();
cout << "===== 合成系统 =====\n"
<< "1. 创建物品\n"
<< "2. 追根求源\n"
<< "3. 手动保存\n"
<< "4. 设置路径\n"
<< "5. 保存信息\n"
<< "6. 查看物品列表\n"
<< "7. 查看物品配方\n"
<< "8. 添加合成表\n"
<< "9. 删除物品\n"
<< "10. 退出\n"
<< "路径: " << savePath.u8string() << "\n物品: " << itemDB.size() << "\n选项: ";
int choice;
cin >> choice;
switch (choice) {
case 1: CreateItem(); break;
case 2: TraceMaterials(); break;
case 3: SaveItems(true); break;
case 4: SetSavePath(); break;
case 5: ShowSaveInfo(); break;
case 6: ShowItemList(); break;
case 7: ShowItemRecipe(); break;
case 8: AddRecipeToItem(); break;
case 9: DeleteItem(); break;
case 10:
clear();
cout << "退出中...\n自动保存...";
SaveItems(false);
wait(1);
return 0;
default:
cout << "无效选项!" << endl;
wait(1);
}
}
}
最新发布