Python 3.6 определяемая пользователем проверка размера доски с 2 переменными - PullRequest
0 голосов
/ 30 апреля 2018

У меня несколько общий вопрос для более опытных программистов. Я немного новичок в программировании, но все же получаю от этого удовольствие. Я работал с 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 для всех случаев, но как правильно его запрограммировать?). Это единственная часть программы, которая еще не работает. Спасибо!

1 Ответ

0 голосов
/ 01 мая 2018

Размер доски можно получить из переменной 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 как список строк, транспонирование будет списком столбцов.

...