You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改Python空域点猜测程序:适配度分秒格式地理坐标输入

修改后的空域点猜测程序代码

以下是支持度分秒地理坐标+原平面坐标的完整代码,同时保留坐标归一化适配Canvas显示的功能:

import tkinter as tk
from tkinter import messagebox, Canvas
import os

# 度分秒转十进制坐标
def dms_to_decimal(dms_str):
    # 提取方向(最后一个字符)
    direction = dms_str[-1].upper()
    # 提取数字部分
    dms_num = dms_str[:-1]
    
    # 处理不同长度的度分秒格式(比如441327是44°13'27'',0100414是10°04'14'')
    if len(dms_num) == 6:
        degrees = int(dms_num[:2])
        minutes = int(dms_num[2:4])
        seconds = int(dms_num[4:6])
    elif len(dms_num) == 7:
        degrees = int(dms_num[:3])
        minutes = int(dms_num[3:5])
        seconds = int(dms_num[5:7])
    else:
        raise ValueError("格式无效")
    
    # 计算十进制值,根据方向处理正负
    decimal = degrees + minutes/60 + seconds/3600
    if direction in ['S', 'W']:
        decimal = -decimal
    return decimal

# 读取文件中的点位与坐标
def load_words_from_file(filename):
    if os.path.exists(filename):
        with open(filename, 'r') as file:
            lines = file.readlines()
            words = []
            for line in lines:
                line = line.strip()
                if not line:
                    continue
                parts = line.split()
                if len(parts) >= 3:
                    word = parts[0].strip().lower()
                    try:
                        # 先尝试原平面坐标格式(整数)
                        x = int(parts[1])
                        y = int(parts[2])
                        coordinates = (x, y)
                    except ValueError:
                        # 尝试度分秒格式解析
                        try:
                            lat = dms_to_decimal(parts[1])
                            lon = dms_to_decimal(parts[2])
                            # 把纬度作为y,经度作为x,适配后续归一化逻辑
                            coordinates = (lat, lon)
                        except Exception as e:
                            messagebox.showwarning("错误", f"点位'{word}'的坐标格式无效:{str(e)}")
                            continue
                    words.append((word, coordinates))
                else:
                    messagebox.showwarning("错误", f"无效行格式:{line}")
            return words
    else:
        messagebox.showerror("错误", f"文件{filename}不存在!")
        return []

# 坐标归一化(适配Canvas显示)
def normalize_coordinates(words_data, canvas_width=600, canvas_height=450):
    if not words_data:
        return []
    
    # 提取所有坐标
    x_values = [coord[1] for _, coord in words_data]
    y_values = [coord[0] for _, coord in words_data]

    # 计算极值
    x_min, x_max = min(x_values), max(x_values)
    y_min, y_max = min(y_values), max(y_values)
    
    # 处理所有坐标相同的特殊情况
    x_range = x_max - x_min if x_max != x_min else 1
    y_range = y_max - y_min if y_max != y_min else 1

    # 归一化并适配Canvas边界
    normalized_words = []
    for word, (y, x) in words_data:
        x_normalized = ((x - x_min) / x_range * (canvas_width - 40)) + 20
        y_normalized = ((y - y_min) / y_range * (canvas_height - 40)) + 20
        normalized_words.append((word, (int(x_normalized), int(y_normalized))))

    return normalized_words

# 文件路径
file_path = os.path.join(os.path.dirname(__file__), 'coordinate_punti.txt')

# 加载并归一化数据
words_data = load_words_from_file(file_path)
normalized_words_data = normalize_coordinates(words_data)

class WordGameApp:
    def __init__(self, root):
        self.root = root
        self.root.title("空域点猜测")

        if not normalized_words_data:
            self.root.quit()
            return

        self.initialize_game()

        # 主框架
        self.frame = tk.Frame(root)
        self.frame.pack(pady=10, fill=tk.BOTH, expand=True)

        # 适配窗口大小变化(支持手机端)
        self.root.bind('<Configure>', self.on_window_resize)

        # 提示标签
        self.label = tk.Label(self.frame, text="输入你记得的点位:")
        self.label.pack(pady=10)

        # 输入框
        self.word_entry = tk.Entry(self.frame)
        self.word_entry.pack(pady=10, fill=tk.X, padx=20)
        self.word_entry.bind('<Return>', self.check_word)

        # 剩余点位计数
        self.counter_label = tk.Label(self.frame, text=f"剩余点位:{self.remaining_words}")
        self.counter_label.pack(pady=10)

        # Canvas(自适应窗口)
        self.canvas = Canvas(self.frame, bg="white")
        self.canvas.pack(pady=10, fill=tk.BOTH, expand=True, padx=20)

        # 重置按钮
        self.clear_button = tk.Button(self.frame, text="清空并重置", command=self.reset_game)
        self.clear_button.pack(pady=5)

        # 显示/隐藏所有点位按钮
        self.toggle_button = tk.Button(self.frame, text="显示所有点位", command=self.toggle_words)
        self.toggle_button.pack(pady=5)

        # 初始化绘制(如果需要)
        self.draw_initial_points()

    def initialize_game(self):
        # 初始化游戏状态
        self.remaining_words = len(normalized_words_data)
        self.guessed_words = set()
        self.all_points_shown = False

    def check_word(self, event=None):
        # 检查输入的点位逻辑
        input_word = self.word_entry.get().strip().lower()
        if not input_word:
            return
        
        for word, coord in normalized_words_data:
            if word == input_word and word not in self.guessed_words:
                self.guessed_words.add(word)
                self.remaining_words -= 1
                self.counter_label.config(text=f"剩余点位:{self.remaining_words}")
                # 在Canvas上标记该点位
                self.canvas.create_oval(coord[0]-5, coord[1]-5, coord[0]+5, coord[1]+5, fill="green")
                self.canvas.create_text(coord[0], coord[1]+15, text=word.upper(), font=("Arial", 8))
                self.word_entry.delete(0, tk.END)
                if self.remaining_words == 0:
                    messagebox.showinfo("完成", "所有点位都找到了!")
                return
        messagebox.showwarning("提示", "这个点位不存在或已经被猜过了")
        self.word_entry.delete(0, tk.END)

    def reset_game(self):
        # 重置游戏状态
        self.guessed_words.clear()
        self.remaining_words = len(normalized_words_data)
        self.counter_label.config(text=f"剩余点位:{self.remaining_words}")
        self.canvas.delete("all")
        self.all_points_shown = False
        self.toggle_button.config(text="显示所有点位")

    def toggle_words(self):
        # 显示/隐藏所有点位
        self.canvas.delete("all")
        if not self.all_points_shown:
            # 绘制所有点位
            for word, coord in normalized_words_data:
                self.canvas.create_oval(coord[0]-5, coord[1]-5, coord[0]+5, coord[1]+5, fill="blue")
                self.canvas.create_text(coord[0], coord[1]+15, text=word.upper(), font=("Arial", 8))
            self.toggle_button.config(text="隐藏所有点位")
        else:
            # 重新绘制已猜中的点位
            for word, coord in normalized_words_data:
                if word in self.guessed_words:
                    self.canvas.create_oval(coord[0]-5, coord[1]-5, coord[0]+5, coord[1]+5, fill="green")
                    self.canvas.create_text(coord[0], coord[1]+15, text=word.upper(), font=("Arial", 8))
            self.toggle_button.config(text="显示所有点位")
        self.all_points_shown = not self.all_points_shown

    def draw_initial_points(self):
        # 初始化可以不显示任何点位,或者显示占位
        pass

    def on_window_resize(self, event):
        # 窗口大小变化时重新归一化坐标并刷新Canvas
        global normalized_words_data
        canvas_width = event.width - 40  # 减去边距
        canvas_height = event.height - 200  # 减去控件高度
        if canvas_width < 200:
            canvas_width = 200
        if canvas_height < 150:
            canvas_height = 150
        normalized_words_data = normalize_coordinates(words_data, canvas_width, canvas_height)
        # 重置并刷新显示
        self.reset_game()

if __name__ == "__main__":
    root = tk.Tk()
    app = WordGameApp(root)
    root.mainloop()

关键修改说明

  • 新增度分秒转十进制函数:dms_to_decimal 处理N/S/E/W方向的度分秒字符串,将其转换为十进制地理坐标,同时根据方向处理正负(南纬、西经为负)。
  • 兼容两种坐标格式:在load_words_from_file中,先尝试解析原有的整数平面坐标;如果失败,则自动尝试解析度分秒格式,实现无缝兼容。
  • 优化归一化逻辑:处理了所有坐标相同的特殊情况,避免除零错误;同时调整了坐标映射,确保地理坐标(纬度y,经度x)能正确适配Canvas的显示逻辑。
  • 窗口自适应:新增窗口大小变化监听,自动重新计算归一化坐标,适配不同屏幕(包括手机端)的显示需求。
  • 补全游戏逻辑:原代码缺失的initialize_game、check_word、reset_game等核心游戏逻辑进行了补全,保证程序能正常运行。

内容的提问来源于stack exchange,提问作者vecchiemaniere

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 21:58:10