259 lines
8.1 KiB
Python
259 lines
8.1 KiB
Python
import os
|
||
import pandas as pd
|
||
from openpyxl import load_workbook
|
||
|
||
columns_to_preview = 3 # 保留你原来的配置
|
||
|
||
# 绿色填充的颜色值(先按常见 Excel 绿填充写一个,你可以打印确认后再调整)
|
||
GREEN_COLORS = {
|
||
"FF92D050", # 常见的浅绿色
|
||
"FF00B050", # 另一种绿色,必要时可以删掉/增加
|
||
}
|
||
|
||
BLUE_COLORS = {
|
||
"FF00B0F0", # 常见的浅蓝色
|
||
"FF0070C0", # 另一种蓝色,必要时可以删掉/增加
|
||
}
|
||
|
||
# c55c10
|
||
ORANGE_COLORS = {
|
||
"FFC55B11",
|
||
"FFC55C10", # 常见的橙色
|
||
"FFB45F06", # 另一种橙色,必要时可以删掉/增加
|
||
}
|
||
|
||
PINK_COLORS = {
|
||
"FFEF949F", # 常见的粉色
|
||
"FFFF99FF", # 另一种粉色,必要时可以删掉/增加
|
||
}
|
||
|
||
|
||
def _load_map_dataframe(file_path, sheet_name, start_i):
|
||
if not os.path.exists(file_path):
|
||
print(f"错误:文件未找到,请检查路径。Path: {file_path}")
|
||
return None
|
||
|
||
try:
|
||
df = pd.read_excel(file_path, sheet_name=sheet_name, engine="openpyxl")
|
||
except Exception as e:
|
||
print(f"读取 XLSX 文件时发生错误: {e}")
|
||
if "No module named 'openpyxl'" in str(e):
|
||
print("\n请确保您已经安装了 openpyxl 库:pip install openpyxl")
|
||
return None
|
||
|
||
if len(df.columns) < 2:
|
||
print("错误:表格至少需要两列 (地图编号与 Y 坐标)。")
|
||
return None
|
||
|
||
map_col = df.columns[0]
|
||
y_col = df.columns[1]
|
||
grid_columns = df.columns[1:27]
|
||
|
||
i = start_i
|
||
for row in df.itertuples():
|
||
if pd.isna(row[1]):
|
||
df.at[row.Index, map_col] = i
|
||
else:
|
||
i = row[1]
|
||
|
||
return df, map_col, y_col, grid_columns
|
||
|
||
|
||
def _write_color_output(filename, rows, columns, success_msg, empty_msg):
|
||
if os.path.exists(filename):
|
||
os.remove(filename)
|
||
if rows:
|
||
pd.DataFrame(rows, columns=columns).to_excel(filename, index=False)
|
||
print(success_msg)
|
||
else:
|
||
print(empty_msg)
|
||
|
||
|
||
def find_cells_with_currency_xlsx(file_path, sheet_name="Sheet1", start_i=90091, search_term="币"):
|
||
"""
|
||
读取 XLSX 文件,查找包含指定词语(默认为“币”)的单元格,
|
||
并返回这些单元格的 (地图号, X, Y[, 方向]),结果同时保存为 found_xxx.xlsx。
|
||
"""
|
||
print(f"--- 正在处理文件: {os.path.basename(file_path)} ---")
|
||
|
||
df_info = _load_map_dataframe(file_path, sheet_name, start_i)
|
||
if df_info is None:
|
||
return []
|
||
|
||
df, map_col, y_col, grid_columns = df_info
|
||
results = []
|
||
|
||
# 2. 遍历 B~AA 每一列,在地图区域里搜索 币 / p / v
|
||
for column in grid_columns:
|
||
column_series = df[column].astype(str).fillna("")
|
||
|
||
if search_term in ["p", "v"]:
|
||
# p/v 支持后缀方向
|
||
suffixes = ["W", "S", "N", "E", "w", "s", "n", "e"]
|
||
search_terms = [search_term] + [search_term + s for s in suffixes]
|
||
matching_rows = column_series.apply(
|
||
lambda x: any(term in x for term in search_terms)
|
||
)
|
||
else:
|
||
search_terms = [search_term]
|
||
matching_rows = column_series.str.contains(search_term, regex=False, na=False)
|
||
|
||
matching_indices = df[matching_rows].index.tolist()
|
||
|
||
if not matching_indices:
|
||
continue
|
||
|
||
# 为了打印调试信息,预览前几列(至少包含 A、B 两列)
|
||
current_col_index = df.columns.get_loc(column)
|
||
end_preview_index = max(2, min(current_col_index, columns_to_preview))
|
||
preview_cols = df.columns[:end_preview_index].tolist()
|
||
|
||
for idx in matching_indices:
|
||
# 地图号和坐标:直接从 A、B 列取值
|
||
map_no = df.at[idx, map_col] # A 列 = 地图编号
|
||
y_no = df.at[idx, y_col] # B 列 = Y 坐标
|
||
x_no = column # 列名本身 = X 坐标(-12 ~ 12)
|
||
|
||
# 提取方向(只对 p / v 有意义)
|
||
direction = ""
|
||
if search_term in ["p", "v"]:
|
||
cell_text = str(df.loc[idx, column])
|
||
direction = cell_text[len(search_term):] if len(cell_text) > len(search_term) else ""
|
||
|
||
if search_term in ["p", "v"]:
|
||
results.append((map_no, x_no, y_no, direction))
|
||
else:
|
||
results.append((map_no, x_no, y_no))
|
||
|
||
# 4. 保存币 / p / v 结果到 Excel
|
||
output_file = f"found_{search_term}.xlsx"
|
||
if search_term in ["p", "v"]:
|
||
results_df = pd.DataFrame(
|
||
results,
|
||
columns=["地图号 (Map No)", "X坐标 (X No)", "Y坐标 (Y No)", "方向 (Direction)"]
|
||
)
|
||
else:
|
||
results_df = pd.DataFrame(
|
||
results,
|
||
columns=["地图号 (Map No)", "X坐标 (X No)", "Y坐标 (Y No)"]
|
||
)
|
||
|
||
results_df.to_excel(output_file, index=False)
|
||
print(f"\n🔖 已将结果保存到文件: {output_file}")
|
||
|
||
return results
|
||
|
||
|
||
def scan_color_blocks(file_path, sheet_name="Sheet1", start_i=90091):
|
||
"""扫描地图区域内的颜色格子,并把结果写入对应的 Excel 文件。"""
|
||
|
||
print("\n开始扫描颜色图案格子…")
|
||
|
||
df_info = _load_map_dataframe(file_path, sheet_name, start_i)
|
||
if df_info is None:
|
||
return {}
|
||
|
||
df, map_col, y_col, grid_columns = df_info
|
||
|
||
try:
|
||
wb = load_workbook(file_path, data_only=True)
|
||
except Exception as e:
|
||
print(f"读取 XLSX 文件时发生错误: {e}")
|
||
return {}
|
||
|
||
try:
|
||
ws = wb[sheet_name]
|
||
except KeyError:
|
||
active_sheet = wb.active
|
||
print(f"未找到工作表 {sheet_name},使用活动表 {active_sheet.title}。")
|
||
ws = active_sheet
|
||
|
||
block_results = []
|
||
water_results = []
|
||
wall_results = []
|
||
jump_results = []
|
||
|
||
excel_row_offset = 2 # DataFrame 行索引 0 对应 Excel 的第 2 行
|
||
|
||
|
||
for idx in df.index:
|
||
map_no = df.at[idx, map_col]
|
||
y_val = df.at[idx, y_col]
|
||
|
||
try:
|
||
y_int = int(y_val)
|
||
except (TypeError, ValueError):
|
||
continue
|
||
|
||
if y_int < -12 or y_int > 12:
|
||
continue
|
||
|
||
excel_row = idx + excel_row_offset
|
||
|
||
for col in grid_columns[1:]: # 从 C 列开始(跳过 Y 轴列)
|
||
col_idx = df.columns.get_loc(col) + 1 # openpyxl 的列号从 1 开始
|
||
cell = ws.cell(row=excel_row, column=col_idx)
|
||
fill = cell.fill
|
||
|
||
if fill is None or fill.patternType in (None, "none"):
|
||
continue
|
||
|
||
fg = fill.fgColor
|
||
rgb = getattr(fg, "rgb", None)
|
||
index = getattr(fg, "index", None)
|
||
color_code = rgb or index
|
||
|
||
if color_code is None:
|
||
continue
|
||
|
||
c = str(color_code).upper()
|
||
if c in GREEN_COLORS:
|
||
block_results.append((map_no, col, y_val))
|
||
if c in BLUE_COLORS:
|
||
water_results.append((map_no, col, y_val))
|
||
if c in ORANGE_COLORS:
|
||
wall_results.append((map_no, col, y_val))
|
||
if c in PINK_COLORS:
|
||
jump_results.append((map_no, col, y_val))
|
||
|
||
columns = ["地图号 (Map No)", "X坐标 (X No)", "Y坐标 (Y No)"]
|
||
|
||
_write_color_output(
|
||
"found_方块.xlsx",
|
||
block_results,
|
||
columns,
|
||
"🔖 已将所有绿色图案格子的坐标保存到文件: found_方块.xlsx",
|
||
"未发现任何绿色图案格子。",
|
||
)
|
||
|
||
_write_color_output(
|
||
"found_water.xlsx",
|
||
water_results,
|
||
columns,
|
||
"🔖 已将蓝色 (water) 格子保存到文件: found_water.xlsx",
|
||
"未发现蓝色 (water) 格子。",
|
||
)
|
||
|
||
_write_color_output(
|
||
"found_wall.xlsx",
|
||
wall_results,
|
||
columns,
|
||
"🔖 已将橙色 (wall) 格子保存到文件: found_wall.xlsx",
|
||
"未发现橙色 (wall) 格子。",
|
||
)
|
||
|
||
_write_color_output(
|
||
"found_jump.xlsx",
|
||
jump_results,
|
||
columns,
|
||
"🔖 已将粉色 (jump) 格子保存到文件: found_jump.xlsx",
|
||
"未发现粉色 (jump) 格子。",
|
||
)
|
||
|
||
return {
|
||
"block": block_results,
|
||
"water": water_results,
|
||
"wall": wall_results,
|
||
"jump": jump_results,
|
||
}
|