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

如何实现Python中Viki AI类生成不重复的Dot坐标?

解决Viki类生成不重复Dot坐标的方案

核心思路是给AI角色Viki维护一个已使用坐标集合,每次生成新坐标时先检查是否已被使用,直到找到未被占用的单元格,再将该坐标标记为已使用。以下是完整的可运行代码实现:

1. 基础类定义

首先完善Dot类,确保它可以被正确比较和存入集合:

class Dot:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    # 定义两个Dot相等的条件:x和y都相同
    def __eq__(self, other):
        if not isinstance(other, Dot):
            return False
        return self.x == other.x and self.y == other.y

    # 实现哈希方法,让Dot可以存入集合
    def __hash__(self):
        return hash((self.x, self.y))

    def __repr__(self):
        return f"Dot({self.x}, {self.y})"

然后定义Player父类,规范子类的方法接口:

from abc import ABC, abstractmethod
import random

class Player(ABC):
    @abstractmethod
    def make_move(self, board_size):
        # board_size是棋盘的尺寸,比如(10,10)表示10x10的棋盘
        pass

2. Viki类实现(AI角色)

在Viki类中维护已使用坐标的集合,生成坐标时循环校验:

class Viki(Player):
    def __init__(self):
        self.used_dots = set()  # 存储已选过的Dot

    def make_move(self, board_size):
        max_x, max_y = board_size
        while True:
            # 生成随机坐标(假设坐标从0开始)
            x = random.randint(0, max_x - 1)
            y = random.randint(0, max_y - 1)
            new_dot = Dot(x, y)
            # 检查是否未被使用
            if new_dot not in self.used_dots:
                self.used_dots.add(new_dot)
                return new_dot
            # 可选:添加棋盘已满的判断,防止死循环
            if len(self.used_dots) == max_x * max_y:
                raise ValueError("棋盘已无可用单元格")

3. Human类实现(人类玩家)

作为对比,实现简单的人类玩家输入逻辑:

class Human(Player):
    def make_move(self, board_size):
        max_x, max_y = board_size
        while True:
            try:
                x = int(input("请输入X坐标:"))
                y = int(input("请输入Y坐标:"))
                if 0 <= x < max_x and 0 <= y < max_y:
                    return Dot(x, y)
                else:
                    print(f"坐标超出范围,请输入0到{max_x-1}之间的X,0到{max_y-1}之间的Y")
            except ValueError:
                print("请输入有效的整数坐标")

4. 测试验证

运行以下代码可以验证Viki生成的坐标不会重复:

if __name__ == "__main__":
    viki = Viki()
    board_size = (5, 5)  # 5x5的棋盘
    # 生成10个坐标,检查是否重复
    moves = [viki.make_move(board_size) for _ in range(10)]
    print("Viki生成的坐标:")
    print(moves)
    # 验证是否有重复
    unique_moves = set(moves)
    print(f"生成的10个坐标中,唯一坐标数量:{len(unique_moves)}")

关键细节说明

  • Dot类的__eq__和__hash__:这两个方法是让Dot可以被集合正确识别的核心,集合依赖哈希值判断元素是否存在,__eq__定义相等逻辑,__hash__生成唯一哈希值。
  • 使用集合而非列表:集合的in操作是O(1)时间复杂度,比列表的O(n)效率高得多,尤其是棋盘较大时,性能差异会很明显。
  • 循环终止条件:添加了棋盘已满的判断,避免当棋盘没有可用单元格时进入无限循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 05:35:28