Python 为什么我的程序匹配了错误的值?

Python 为什么我的程序匹配了错误的值?,python,for-loop,Python,For Loop,我在做一个战舰游戏。我不明白为什么,当你在不同的位置重叠一艘船时,我的程序会要求你输入不同的起始位置n次 def make_ships(name, length, position, orientation): ships[name] = {"length": length, "Coordinates": {}} x = ord(position[:1]) y = int(position[1:]) coords = {} if orientation.l

我在做一个战舰游戏。我不明白为什么,当你在不同的位置重叠一艘船时,我的程序会要求你输入不同的起始位置n

def make_ships(name, length, position, orientation):
    ships[name] = {"length": length, "Coordinates": {}}
    x = ord(position[:1])
    y = int(position[1:])
    coords = {}
    if orientation.lower() == "y":
        for i in range(0, length):
            place = ''.join([chr(x), str(y)])
            coords[place] = "-"
            x = x + 1
    elif orientation.lower() == "n":
        for i in range(0, length):
            place = ''.join([chr(x), str(y)])
            coords[place] = "|"
            y = y + 1
    print("Coordinates of incoming ship: {}".format(list(coords.keys())))
    names = []
    for item in ships:
        names.append(item)
        # a.append(list(self.ships[item]["Coordinates"].keys()))
    for var in names:
        for item in coords.keys():
            if item in list(ships[var]["Coordinates"].keys()) and ships[name] != ships[var]:
                print("Coordinates of {}: {}".format(var, list(ships[var]["Coordinates"].keys())))
                new_position = input("There is an overlap at {}. Please enter a different starting position: ".format(item)).replace(" ","")
                new_orientation = input("Is it horizontal? (Y/N): ").replace(" ","")
                make_ships(name, length, new_position, new_orientation)
    ships[name]["Coordinates"] = coords

ships = {}
ships["Aircraft Carrier"] = {}
ships["Aircraft Carrier"] = {"length": 5, "Coordinates": {'a1':'|', 'a2':'|', 'a3':'|', 'a4':'|', 'a5':'|'}}
make_ships("Battleship", 4, 'a1', 'n')
最初呼叫中的战列舰在4个位置与现有航母重叠。 程序要求您输入新的位置和方向。
如果您选择,比如说,b1,程序将声明重叠,并显示承运人的坐标,a1-a5,这显然不会在b1-b4问题中重叠船舶

您的错误是使用了对make_ships的递归调用,而不是简单的迭代(while loop)。当第一个条目在空格a4上匹配失败时,您将获得新船的信息,并将其很好地添加。但是,然后从递归调用返回到第一个调用,此时仍处于检查循环中。迭代到a列检查中的下一个空格,发现原始调用的a1也匹配(如果你很固执,你会得到四次,每次来自原始战舰的碰撞一次)

修理

干净的方法是用while循环中的“read-till-good”替换这个过程。其伪代码为:

获取第一个输入 而输入是不可接受的 获取替换输入

便宜的方法是在递归调用之后简单地放置一个返回。下面是我的代码,包括调试工具。当我测试这一点时,我把替换的战列舰放在广场q7:-),这表明问题与战舰接触无关

def make_ships(name, length, position, orientation):
    print ("===> ENTER make_ships", name, length, position, orientation)
    ships[name] = {"length": length, "Coordinates": {}}
    x = ord(position[:1])
    y = int(position[1:])
    coords = {}

    if orientation.lower() == "y":
        for i in range(0, length):
            place = ''.join([chr(x), str(y)])
            coords[place] = "-"
            x = x + 1
    elif orientation.lower() == "n":
        for i in range(0, length):
            place = ''.join([chr(x), str(y)])
            coords[place] = "|"
            y = y + 1
    print("Coordinates of incoming ship: {}".format(list(coords.keys())))

    # Validating for ship overlap
    names = []
    for item in ships:
        names.append(item)
        # a.append(list(self.ships[item]["Coordinates"].keys()))
    for var in names:
        # print ("coords.keys=", coords.keys())
        for item in coords.keys():
            print ("\ncoords.keys=", coords.keys())
            print ("var=", var, "\tname=", name, "\titem=", item)
            print (ships[var]["Coordinates"].keys())
            if item in list(ships[var]["Coordinates"].keys()) and ships[name] != ships[var]:
                print("Coordinates of {}: {}".format(var, list(ships[var]["Coordinates"].keys())))
                new_position = input("There is an overlap at {}. Please enter a different starting position: ".format(item)).replace(" ","")
                new_orientation = input("Is it horizontal? (Y/N): ").replace(" ","")
                make_ships(name, length, new_position, new_orientation)
                return

    ships[name]["Coordinates"] = coords

    print ("===> EXIT make_ships", coords)


ships = {}
ships["Aircraft Carrier"] = {}
ships["Aircraft Carrier"] = {"length": 5, "Coordinates": {'a1':'|', 'a2':'|', 'a3':'|', 'a4':'|', 'a5':'|'}}

make_ships("Battleship", 4, 'a1', 'n')

问题

您的错误是使用了对make_ships的递归调用,而不是简单的迭代(while loop)。当第一个条目在空格a4上匹配失败时,您将获得新船的信息,并将其很好地添加。但是,然后从递归调用返回到第一个调用,此时仍处于检查循环中。迭代到a列检查中的下一个空格,发现原始调用的a1也匹配(如果你很固执,你会得到四次,每次来自原始战舰的碰撞一次)

修理

干净的方法是用while循环中的“read-till-good”替换这个过程。其伪代码为:

获取第一个输入 而输入是不可接受的 获取替换输入

便宜的方法是在递归调用之后简单地放置一个返回。下面是我的代码,包括调试工具。当我测试这一点时,我把替换的战列舰放在广场q7:-),这表明问题与战舰接触无关

def make_ships(name, length, position, orientation):
    print ("===> ENTER make_ships", name, length, position, orientation)
    ships[name] = {"length": length, "Coordinates": {}}
    x = ord(position[:1])
    y = int(position[1:])
    coords = {}

    if orientation.lower() == "y":
        for i in range(0, length):
            place = ''.join([chr(x), str(y)])
            coords[place] = "-"
            x = x + 1
    elif orientation.lower() == "n":
        for i in range(0, length):
            place = ''.join([chr(x), str(y)])
            coords[place] = "|"
            y = y + 1
    print("Coordinates of incoming ship: {}".format(list(coords.keys())))

    # Validating for ship overlap
    names = []
    for item in ships:
        names.append(item)
        # a.append(list(self.ships[item]["Coordinates"].keys()))
    for var in names:
        # print ("coords.keys=", coords.keys())
        for item in coords.keys():
            print ("\ncoords.keys=", coords.keys())
            print ("var=", var, "\tname=", name, "\titem=", item)
            print (ships[var]["Coordinates"].keys())
            if item in list(ships[var]["Coordinates"].keys()) and ships[name] != ships[var]:
                print("Coordinates of {}: {}".format(var, list(ships[var]["Coordinates"].keys())))
                new_position = input("There is an overlap at {}. Please enter a different starting position: ".format(item)).replace(" ","")
                new_orientation = input("Is it horizontal? (Y/N): ").replace(" ","")
                make_ships(name, length, new_position, new_orientation)
                return

    ships[name]["Coordinates"] = coords

    print ("===> EXIT make_ships", coords)


ships = {}
ships["Aircraft Carrier"] = {}
ships["Aircraft Carrier"] = {"length": 5, "Coordinates": {'a1':'|', 'a2':'|', 'a3':'|', 'a4':'|', 'a5':'|'}}

make_ships("Battleship", 4, 'a1', 'n')

什么缩进需要修正?我修正了。您未能缩进该功能。“战列舰”实际上设置为从
a1
开始,这与“航空母舰”相同。你能查一下吗?或者我可能误解了什么。问题是当两艘船重叠时。所以我一开始就设置好了。当您运行代码时,它会要求您选择一个新的起始位置。无论你选择什么,它都会要求你至少选择4次新的起始位置。这就是我要解决的问题。什么缩进需要修正?我修正了。您未能缩进该功能。“战列舰”实际上设置为从
a1
开始,这与“航空母舰”相同。你能查一下吗?或者我可能误解了什么。问题是当两艘船重叠时。所以我一开始就设置好了。当您运行代码时,它会要求您选择一个新的起始位置。无论你选择什么,它都会要求你至少选择4次新的起始位置。这就是我试图解决的问题。好吧,在我遇到这个问题之前,我研究了这个问题,我的程序的其余部分已经从递归循环切换到while循环,似乎更容易离开这个循环。但这显然是一个坏习惯。是的,这是一个坏习惯——更重要的是,它让你的思维在区分递归和迭代过程时变得不那么敏锐。用这种方式编程可以学习递归,但从长远来看,继续使用它会让我的几个学生绊倒。好的,在我遇到这个问题之前,我研究了这个问题,我的程序的其余部分已经从递归切换到while循环,似乎更容易离开这个循环。但这显然是一个坏习惯。是的,这是一个坏习惯——更重要的是,它让你的思维在区分递归和迭代过程时变得不那么敏锐。用这种方式编程可以学习递归,但从长远来看,继续使用它会让我的几个学生绊倒。