Python通过鼠标点击找到最近的turtle

Python find closest turtle via mouse click

我正在使用基于海turtle的网格设置创建一个扫雷风格的游戏。我需要在网格中找到最近的单元格并显示位于其下方的图标,无论是炸弹还是数字图标。我不想让它准确,我只需要单击鼠标即可找到网格中最近的单元格,即使单击不是直接在板上。目前我的代码只显示了在板上创建的最后一个海turtle的图标,然后通过进一步点击什么也不做。

我该怎么做才能让它识别真正最近的点击并多次执行直到找到最后一个炸弹?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import random
import turtle
import cell

class Game:

def __init__(self, size):

    registershapes()
    self.__boardsize = size
    self.__boardlist = []
    self.__bombnum = 0
    self.__probe = 0
    self.__probelist = []
    offset = (size-1) * 17
    for x in range(size):
        for y in range(size):
            t = cell.Cell(x,y)
            t.up()
            t.shape('question.gif')
            t.goto(y*34-offset, offset-x*34)
            self.__boardlist.append(t)
def hideMines(self, num):
    if num > self.__boardsize ** 2:
        return False
    self.__bombnum = num
    self.__rnums = []
    i = 0
    while i < self.__bombnum:
        currentnum = random.randrange(0, (self.__boardsize**2) - 1)
        if currentnum not in self.__rnums:
            self.__rnums.append(currentnum)
            i += 1
    return True

def probe(self, x, y):
    for t in self.__boardlist:
        pos = t.position()
        distx = abs(x - pos[0])
        disty = abs(y - pos[1])
        distfinal = (distx ** 2 + disty ** 2) ** 0.5
        curdist = 0
        if curdist < distfinal:
            curdist = distfinal
            closest = t
    if closest in self.__probelist:
        return (self.__probe, self.__bombnum)
    elif closest in self.__rnums:
        closest.shape("bomb.gif")
        self.__bombnum -= 1
        self.__probe += 1
        self.__probelist.append(closest)
        return (self.__probe, self.__bombnum)

    else:
        closest.shape("0.gif")
        self.__probe += 1
        self.__probelist.append(closest)
        return (self.__probe, self.__bombnum)


def registershapes():
    wn = turtle.Screen()
    wn.register_shape('0.gif')
    wn.register_shape('1.gif')
    wn.register_shape('2.gif')
    wn.register_shape('3.gif')
    wn.register_shape('4.gif')
    wn.register_shape('5.gif')
    wn.register_shape('6.gif')
    wn.register_shape('7.gif')
    wn.register_shape('8.gif')
    wn.register_shape('9.gif')
    wn.register_shape('bomb.gif')
    wn.register_shape('question.gif')

我相信您以错误的方式处理此问题。您正在激活 screen.onclick() 并尝试将其映射到海turtle。相反,在单个海turtle上激活 turtle.onclick(),在选择海turtle时将其停用。那么你就不必搜索有问题的海turtle,也不必主动忽略已经被选中的海turtle。

下面是我将您的代码从这个问题和您之前的问题重新编写成一个您可以运行的示例。我不得不猜测 Cell 类的定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from turtle import Turtle, Screen
import random

class Cell(Turtle):

    def __init__(self, number):
        super().__init__("question.gif")
        self.__number = number
        self.penup()

    def number(self):
        return self.__number

class Game:

    def __init__(self, size):
        registershapes()
        self.__boardsize = size
        self.__boardlist = []
        self.__bombnum = 0
        self.__probe = 0
        self.__rnums = None

        offset = (size - 1) * 17

        for y in range(size):
            for x in range(size):
                t = Cell(x + y * size)
                t.goto(x * 34 - offset, offset - y * 34)
                t.onclick(lambda x, y, self=t: closure(self))
                self.__boardlist.append(t)

    def hideMines(self, num):
        if num > self.__boardsize ** 2:
            return False

        self.__bombnum = num
        self.__rnums = []
        i = 0

        while i < self.__bombnum:
            currentnum = random.randrange(0, self.__boardsize ** 2 - 1)

            if currentnum not in self.__rnums:
                self.__rnums.append(currentnum)
                i += 1
        return True

    def probe(self, closest):
        closest.onclick(None)

        if closest.number() in self.__rnums:
            closest.shape("bomb.gif")
            self.__bombnum -= 1
        else:
            closest.shape("0.gif")

        self.__probe += 1
        return (self.__probe, self.__bombnum)

def registershapes():
    screen.register_shape('0.gif')
    # ...
    screen.register_shape('bomb.gif')
    screen.register_shape('question.gif')

def closure(closest):
    _, rem = mine.probe(closest)

    if rem == 0:

        over = screen.textinput("Text Input","Would you like to play again? (Y)es or (N)o")

        if over.upper() == 'Y':
            main()
        else:
            screen.bye()

def main():
    global mine

    board = screen.numinput("Numeric Input","Enter desired board size:")
    mine = Game(int(board))

    nummine = screen.numinput("Numeric Input","Enter desired number of mines:")
    mine.hideMines(int(nummine))

screen = Screen()

mine = None
main()

screen.mainloop()

enter