Python 3.6 用户定义的棋盘尺寸 win check with 2 variables

Python 3.6 user-defined board size win check with 2 variables

我有一些一般性的问题要问更有经验的程序员。我对编程有点陌生,但仍然很喜欢它。我一直在与 Python 合作,并决定尝试编写一个井字游戏,但棋盘大小可以由用户决定(一直到 26x26 棋盘)。到目前为止,这是我得到的:

    print("""Welcome to tic tac toe!
    You will begin by determining who goes first;
    Player 2 will decide on the board size, from 3 to 26.
    Depending on the size of the board, you will have to
    get a certain amount of your symbol (X/O) in a row to win.
    To place symbols on the board, input their coordinates;
    letter first, then number (e.g. a2, g10, or f18).
    That's it for the rules. Good luck!\n""")

    while True:
    ready = input("Are you ready? When you are, input 'yes'.")
    if ready.lower() == 'yes': break

    def printboard(n, board):
      print() #print board in ranks of n length; n given later
      boardbyrnk = [board[ind:ind+n] for ind in range(0,n**2,n)]
      for rank in range(n):
        rn = f"{n-rank:02d}" #pads with a 0 if rank number < 10
        print(f"{rn}|{'|'.join(boardbyrnk[rank])}|") #with rank#'s
      print("  ",end="") #files at bottom of board
      for file in range(97,n+97): print(" "+chr(file), end="")
      print()

    def sqindex(prompt, n, board, syms): #takes input & returns index
      #ss is a list/array of all possible square names
      ss = [chr(r+97)+str(f+1) for r in range(n) for f in range(n)]
      while True: #all bugs will cause input to be taken for same turn
        sq = input(prompt)
        if not(sq in ss): print("Square doesn't exist!"); continue
        #the index is found by multiplying rank and adding file #'s
        index = n*(n-int(sq[1:])) + ord(sq[0])-97
        if board[index] in syms: #ensure it contains ' '
          print("The square must be empty!"); continue
        return index

    def checkwin(n, w, board, sm): #TODO
      #check rows, columns and diagonals in terms of n and w;
      #presumably return True if each case is met
      return False

    ps = ["Player 1", "Player 2"]; syms = ['X', 'O']
    #determines number of symbols in a row needed to win later on
    c = {3:[3,3],4:[4,6],5:[7,13],6:[14,18],7:[19,24],8:[25,26]}
    goagain = True
    while goagain:
      #decide on board size
      while True:
        try: n=int(input(f"\n{ps[1]}, how long is the board side? "))
        except ValueError: print("Has to be an integer!"); continue
        if not(2<n<27): print("Has to be from 3 to 26."); continue
        break
      board = (n**2)*" " #can be rewritten around a square's index

      for num in c:
        if c[num][0] <= n <= c[num][1]: w = num; break
      print(f"You'll have to get {w} symbols in a row to win.")

      for tn in range(n**2): #tn%2 = 0 or 1, determining turn order
        printboard(n, board)
        pt = ps[tn%2]
        sm = syms[tn%2]
        prompt = f"{pt}, where do you place your {sm}? "
        idx = sqindex(prompt, n, board, syms)
        #the index found in the function is used to split the board string
        board = board[:idx] + sm + board[idx+1:]
        if checkwin(n, w, board, sm):
          printboard(n, board); print('\n' + pt + ' wins!!\n\n')
          break
        if board.count(" ") == 0:
          printboard(n, board); print("\nIt's a draw!")

      while True: #replay y/n; board size can be redetermined
        rstorq = input("Will you play again? Input 'yes' or 'no': ")
        if rstorq in ['yes', 'no']:
          if rstorq == 'no': goagain = False
          break
        else: print("Please only input lowercase 'yes' or 'no'.")

    print("Thanks for playing!")

所以我对那些知道自己在做什么的人的问题是,他们会建议如何确定当前玩家是否赢了(显然我必须在所有情况下检查 w,但如何正确编程? ).这是该程序中唯一尚未运行的部分。谢谢!

您可以从 board 变量中获取板的尺寸(假设是方形板)。

def winning_line(line, symbol):
    return all(cell == symbol for cell in line)

def diag(board):
    return (board[i][i] for i in range(len(board)))

def checkwin(board, symbol):
    if any(winning_line(row, symbol) for row in board):
        return True
    transpose = list(zip(*board))
    if any(winning_line(column, symbol) for column in transpose):
        return True
    return any(winning_line(diag(layout), symbol) for layout in (board, transpose))

zip(*board) 是获得电路板转置的好方法。如果您将原始 board 列表想象成一个行列表,那么转置将是一个列列表。