如果棋盘已满,如何使嵌套的 while 循环结束?

问题描述 投票:0回答:1

我已经尝试了很多解决方案,所以我的程序有点混乱,但我仍然无法找到一种方法来检查“_”并在没有剩余的情况下结束游戏。实际上,我宁愿让它们在董事会填满时就打破,但到目前为止似乎没有任何效果,我不再明白了。

这是我的程序:

grid = [['0','1','2','3'],['1','_','_','_'], ['2','_','_','_'],['3','_','_','_']]
print("Tic-Tac-Toe")
for row in grid:
    print(row)


for row in grid:
    for cell in row:
        if cell != '_':


            valid_input = False
            while not valid_input:
                x_x = int(input("Choose x-coordinate for x: "))
                x_y = int(input("Choose y-coordinate for x: "))

                if x_x < 1 or x_x > 3 or x_y < 1 or x_y > 3:
                    print("Invalid input for x. Please try again.")
                elif grid[x_x][x_y] != '_':
                    if '_' in grid == False:
                        break
                    else:
                        print("The place is occupied. Choose another place for x.")
                else:
                    grid[x_x][x_y] = 'x'
                    for row in grid:
                        print(row)
                    valid_input = True

            valid_input = False
            while not valid_input:
                o_x = int(input("Choose x-coordinate for o: "))
                o_y = int(input("Choose y-coordinate for o: "))

                if o_x < 1 or o_x > 3 or o_y < 1 or o_y > 3:
                    print("Invalid input for o. Please try again.")
                elif grid[o_x][o_y] != '_':
                    if '_' in grid == False:
                        break
                    else:
                        print("The place is occupied. Choose another place for o.")
                else:
                    grid[o_x][o_y] = 'o'
                    for row in grid:
                        print(row)
                    valid_input = True

我认为这需要你在游戏“完成”后仍然尝试另一个回合,但然后打破整个循环。事实并非如此。它无限期地要求我另一个“o”点。

python while-loop break tic-tac-toe
1个回答
0
投票

我希望你准备好阅读一个很长的答案:)

它无限期地要求你换一个位置的原因是因为你的循环的工作方式。你外面有这个:

for row in grid:
    for cell in row:
        if cell != '_':

这意味着对于每个不是

_
的位置,您都将运行代码。仅有 7 个位置适用此规定,但有 9 个位置是空的。但在您的代码中,您既有
x
的输入,也有
o
的输入。这意味着您的代码实际上期望接受 7 x 2(7 个循环,然后 2 个输入,一个用于
x
,一个用于
o
)输入,但是当您达到 9 个输入时,您的板已满,并且所以它永远不会接受所有 14 个输入,因此永远不会结束程序。

但是为什么棋盘满了还没有结束呢?这是因为在外面有两层循环。即使您在代码内部调用
break
,您也只能跳出内部循环。此外,您检查
_
的方式是错误的。由于您有一个多层列表(列表内部的列表),因此它不会找到任何
_
,因为它只在第一层中查找,除了列表之外没有任何值。

这是我的程序版本的一些示例代码,并附有解释注释:

grid = [['0','1','2','3'],
        ['1','_','_','_'],
        ['2','_','_','_'],
        ['3','_','_','_']] #Put each row of the grid on new lines to better visualize. As you can see, your x and y inputs are swapped in the code


print("Tic-Tac-Toe")
for row in grid:
    print(row)


turn = 'x' #store whose turn it is
for _ in range(3*3): #your grid is 3 by 3, so that's 9. I put 3*3 because it's easier to see (when you start writing more code you'll want to be able to read through code easily when checking for errors)
    valid_input = False
    while not valid_input:
        try: #Use a try and except statement. This is because if a person enters without typing anything, it will cause an error because you can't convert a "nothing" into an integer.
            x = int((input(f"Choose x-coordinate for {turn}: "))) #Use "f" for format to put the variable in the text. Ex. "Choose x-coordinate for x: "
            y = int((input(f"Choose y-coordinate for {turn}: ")))
        except:
            print(f"Invalid input for {turn}. Please try again.")

        if x not in [1, 2, 3] or y not in [1, 2, 3]: #Checks if x or y values are in the list of valid positions. Doing this makes sure people can't input something like "2.5"
            print(f"Invalid input for {turn}. Please try again.")
        elif grid[y][x] != '_': #Swap x and y (Read the comment about your grid variable)
            print(f"The place is occupied. Choose another place for {turn}.")
        else:
            grid[y][x] = turn
            for row in grid:
                print(row)
            valid_input = True
            turn = 'o' if turn == 'x' else 'x' #change the turn to the next player through a one line conditional (You can make this more than one line if you want. It's read as "turn will be x unless turn is already x in which case it will be o")
print("The board is full!")

此外,您还可以将变量设置为 False 并使用

for
循环,而不是外部的
while
循环:

grid = [['0','1','2','3'],
        ['1','_','_','_'],
        ['2','_','_','_'],
        ['3','_','_','_']]


print("Tic-Tac-Toe")
for row in grid:
    print(row)


def fullBoard(): #function to check if the board is full so we can separate code from the main code chunk for better legibility
    for row in grid: #goes through each row in the grid
        for space in row: #goes from each space in the row
            if space == '_': #check if the space is empty
                return False #if any space is empty in the grid, then the board is not full so return False
    return True #if no spaces in the grid are empty, then the board is full so return True


turn, filledBoard = 'x', False #Assign two variables at once. filledBoard is used for the while loop
while not filledBoard: 
    valid_input = False
    while not valid_input:
        try:
            x = int((input(f"Choose x-coordinate for {turn}: ")))
            y = int((input(f"Choose y-coordinate for {turn}: ")))
        except:
            print(f"Invalid input for {turn}. Please try again.")

        if x not in [1, 2, 3] or y not in [1, 2, 3]: 
            print(f"Invalid input for {turn}. Please try again.")
        elif grid[int(y)][int(x)] != '_':
            print(f"The place is occupied. Choose another place for {turn}.")
        else:
            grid[int(y)][int(x)] = turn
            for row in grid:
                print(row)
            valid_input = True
            turn = 'o' if turn == 'x' else 'x'
    filledBoard = fullBoard() #Call our function to check if the board is full every single time a player makes a move

print("The board is full!")
© www.soinside.com 2019 - 2024. All rights reserved.