井字游戏–输出打印额外的一行

时间:2019-05-14 08:23:11

标签: python python-3.x

  

写游戏井字游戏。该游戏涉及两名玩家,每个玩家轮流将X或O(取决于玩家)放置在二维网格中。 x和y坐标在[0-2](含)范围内。如果玩家(X或O)连续,直列或对角线有3个,则可以获胜。

该程序几乎是正确的,当'X'或'O'获胜时,程序会给出正确的输出,该输出不会在'X获胜!或'O wins',但是,在绘制时,程序在打印'Draw'之前先打印一个空行,预期的输出不应在打印'Draw'之前打印空行。我不知道如何解决。

def print_matric(eri):
    for j in range(0,3):
        for i in range(0,3):
            if eri[i][j]==-1:
                print(" ",end="")
            if eri[i][j]==0:
                print("O",end="");
            if eri[i][j]==1:
                print("X",end="");
            if not i==2:
                print("|",end="");
        print()
        # prints ("_ _ _") two times only not third time
        if not j==2:
            print("-----",end="")
        print()
def compute(eri):
    if eri[0][0]== eri[0][1] and eri[0][1] == eri[0][2] and eri[0][0] != -1:
        return eri[0][0]
    if eri[1][0]== eri[1][1] and eri[1][1] == eri[1][2] and eri[1][0] != -1:
        return eri[1][0]
    if eri[2][0]== eri[2][1] and eri[2][1] == eri[2][2] and eri[2][0] != -1:
        return eri[2][0]
    if eri[0][0]== eri[1][0] and eri[1][0] == eri[2][0] and eri[0][0] != -1:
        return eri[0][0]
    if eri[0][1]== eri[1][1] and eri[1][1] == eri[2][1] and eri[0][1] != -1:
        return eri[0][1]
    if eri[0][2]== eri[1][2] and eri[1][2] == eri[2][2] and eri[0][2] != -1:
        return eri[0][2]
    if eri[0][0]== eri[1][1] and eri[1][1] == eri[2][2] and eri[0][0] != -1:
        return eri[0][0]
    if eri[0][2]== eri[1][1] and eri[1][1] == eri[2][0] and eri[0][2] != -1:
        return eri[0][2]
    return -1
def find_whether_empty(eri):
    for j in range(0,3):
        for i in range(0,3):
            if eri[j][i]==-1:
                return 1
    return 0
eri = [[-1,-1,-1],[-1,-1,-1],[-1,-1,-1]]
count=0
while True:
    a,b = input().split()
    a=int(a)
    b=int(b)  
    if a<0 or a>2 or b<0 or b>2:
        print("\ncheck your coordinates and enter again")
        continue
    if not eri[a][b]==-1:
        print("\nposition already occupied, please enter again")
        continue
    if count%2==0:
        eri[a][b]=1
    else:
        eri[a][b]=0
    count=count+1
    if compute(eri)==-1:
        print()  
    x=compute(eri)
    if not x==-1:
        if x==0:
            print("O wins!\n")
        else:
            print("X wins!\n")
    if not find_whether_empty(eri):
        print("Draw\n")
        print_matric(eri)
        break
    print_matric(eri)
    if not x==-1:
        break

预期输出:

0 0               

X| |
-----
 | |
-----
 | |

1 1

X| |
-----
 |O|
-----
 | |

1 0

X|X|
-----
 |O|
-----
 | |

2 0

X|X|O
-----
 |O|
-----
 | |

0 2

X|X|O
-----
 |O|
-----
X| |

0 1

X|X|O
-----
O|O|
-----
X| |

2 1

X|X|O
-----
O|O|X
-----
X| |

2 2

X|X|O
-----
O|O|X
-----
X| |O

1 2
Draw

X|X|O
-----
O|O|X
-----
X|X|O

实际输出:

0 0

X| | 
-----
 | | 
-----
 | | 

1 1

X| | 
-----
 |O| 
-----
 | | 

1 0

X|X| 
-----
 |O| 
-----
 | | 

2 0

X|X|O
-----
 |O| 
-----
 | | 

0 2

X|X|O
-----
 |O| 
-----
X| | 

0 1

X|X|O
-----
O|O| 
-----
X| | 

2 1

X|X|O
-----
O|O|X
-----
X| | 

2 2

X|X|O
-----
O|O|X
-----
X| |O

1 2

Draw

X|X|O
-----
O|O|X
-----
X|X|O

2 个答案:

答案 0 :(得分:4)

只需删除这2条注释行,并添加print()使其仅在游戏未结束时运行:

if count%2==0:
    eri[a][b]=1
else:
    eri[a][b]=0
count=count+1
# if compute(eri)==-1:  # REMOVED THESE
#     print()           # REMOVED THESE
x=compute(eri)
if not x==-1:
    if x==0:
        print("O wins!\n")
    else:
        print("X wins!\n")
elif not find_whether_empty(eri):  # CHANGED if -> elif
    print("Draw\n")
    print_matric(eri)
    break
else:        # ADDED THESE
    print()  # ADDED THESE
  

然后它将在绘制时给出正确的输出:

......
......
O|X| 
-----
X|O|O
-----
X| |X

1 2

O|X| 
-----
X|O|O
-----
X|O|X

2 0
Draw

O|X|X
-----
X|O|O
-----
X|O|X

答案 1 :(得分:3)

此答案的存在是为了提供进一步的建议,以期(希望)在您需要编写和调试代码时持续下去。

清晰的逻辑和结构流程将提高您直接思考代码和推理代码的整体能力。

当前,您的代码可能在逻辑上起作用,但是流程很难遵循。我指的是以下部分。添加了注释,以便您遵循我的思考过程。

    if compute(eri)==-1:             # ok, compute the matrix and check for no winner    
        print()
    x=compute(eri)                   # compute the matrix... again?
    if not x==-1:                    # check for winner, why not "x != -1"?
        if x==0:
            print("O wins!\n")
        else:
            print("X wins!\n")       # didn't jump out?
    if not find_whether_empty(eri):  # check matrix is full
        print("Draw\n")
        print_matric(eri)
        break                        # jump out, but not before?
    print_matric(eri)                # ok, you wanted to print the matrix here
    if not x==-1:                    # check for winner
        break                        # jump out

在这里,解析个别案例有些困难。如果玩家1获胜,它将进入not x == -1 -> x == 0 -> print,那么代码的 reader 必须先跳过几行,依次到达print_matricnot x == -1 -> break。不需要任何代码就可以跳入if语句,跳出并跳回到另一个语句。如果可能的话,请尽量避免这种情况,因为这样做会使阅读变得困难。

(最重要的是,您的代码错过了一个极端的情况,并且表现出很可能与您的意图相冲突的行为。请尝试找出该极端情况。)

这是我写逻辑的方式:

...

finished = False           # a sentry variable
while not finished:

    ...

    winner = compute(eri)

    # is there a winner?
    if winner == -1:    # no winner

        # is the board empty?
        if not find_whether_empty(eri):
            print("Draw\n")
            finished = True
        else:
            print()         # only executed when there is no winner
                            # and board isn't empty

    else:               # there is a winner

        # which winner is it?
        if winner == 0:
            print("O wins!\n")
        elif winner == 1:
            print("X wins!\n")

        finished = True

    print_matric(eri)       # matrix printed regardless of winner state

在这里,很清楚代码的哪一部分针对矩阵处于哪种状态运行。如果玩家1获胜,它将仅运行else -> winner == 0 -> print。如果有平局,它将仅运行winner == -1 -> not find_whether_empty(eri) -> print, finished。此外,compute仅被调用一次(节省时间),并且将为所有获胜者状态打印矩阵。

请注意,我使用哨兵变量break来控制程序的流程,而不是finished。与break(会立即退出循环)不同,使用sentry变量仍将运行print_matric行。

希望这对您有所启发。