在连接四局游戏中检查四行/列/对角线的更简单方法?

时间:2019-05-28 23:48:06

标签: python coding-efficiency

我正在用X和O进行四通游戏。用于在一行/列/对角线中检查四个的代码,但是我的代码中有很多if语句。游戏现在可以完全正常运行,但是我想知道是否有更简单的解决方案。下面,我包括了所有上下文代码。

我尝试使用坐标。不过,这似乎效率很低。用于检查的功能称为检查。

namex = input("Player X, enter your name. ") #asks for player 1 name
nameo = input("Player O, enter your name. ") #asks for player 2 name

game = [[".", ".", ".", ".", ".", "."], #gameboard
    [".", ".", ".", ".", ".", "."], 
    [".", ".", ".", ".", ".", "."], 
    [".", ".", ".", ".", ".", "."], 
    [".", ".", ".", ".", ".", "."], 
    [".", ".", ".", ".", ".", "."], 
    [".", ".", ".", ".", ".", "."]]

loop = True
def output(matrix):
    str1 = ""
    str2 = ""
    str3 = ""
    str4 = ""
    str5 = ""
    str6 = ""
    print("0 1 2 3 4 5 6 ") #print labels for columns in gameboard
    for a in matrix:
        row = 0
        for b in a: #"a" is a column and "b" is a ./x/o
            row += 1
            if row == 1:
                str1 += b
                str1 += " "
            if row == 2:
                str2 += b
                str2 += " "
            if row == 3:
                str3 += b
                str3 += " "
            if row == 4:
                str4 += b
                str4 += " "
            if row == 5:
                str5 += b
                str5 += " "
            if row == 6:
                str6 += b
                str6 += " "
    print(str1) #print string for row 1
    print(str2) #print string for row 2
    print(str3) #print string for row 3
    print(str4) #print string for row 4
    print(str5) #print string for row 5
    print(str6) #print string for row 6

def check(matrix): #function to check for four in row/column/diagonal to win
    positionx = []
    positiono = []
    x = 0
    for a in matrix:
        y = 5
        for b in a:
            if b == "X":
                positionx.append([x, y])
            if b == "O":
                positiono.append([x, y])
            y -= 1
        x += 1

    for c1 in positionx: 
        '''check four in row/column/diagonal for x'''
        for c2 in positionx:
            for c3 in positionx:
                for c4 in positionx: 
                    if c4[0]-c3[0] == 1:#check for four in row
                        if c3[0]-c2[0] == 1:
                            if c2[0]-c1[0] == 1:
                                return "xwin"
                    if c4[1]-c3[1] == 1: #check for four in column
                        if c3[1]-c2[1] == 1:
                            if c2[1]-c1[1] == 1:
                                return "xwin"
                    if c4[0]-c3[0] == 1: #check four in diagonal
                        if c4[1]-c3[1] == 1:
                            if c3[0]-c2[0] == 1:
                                if c3[1]-c2[1] == 1:
                                    if c2[0]-c1[0] == 1:
                                        if c2[1]-c1[1] == 1:
                                            return "xwin"                       
    for d1 in positiono:
        '''check four in row/column/diagonal for o'''
        for d2 in positiono:
            for d3 in positiono:
                for d4 in positiono: 
                    if d4[0]-d3[0] == 1: #check for four in row
                        if d3[0]-d2[0] == 1:
                            if d2[0]-d1[0] == 1:
                                return "owin"
                    if d4[1]-d3[1] == 1: #check for four in column
                        if d3[1]-d2[1] == 1:
                            if d2[1]-d1[1] == 1:
                                return "owin"
                    if d4[0]-d3[0] == 1: #check four in diagonal
                        if d4[1]-d3[1] == 1:
                            if d3[0]-d2[0] == 1:
                                if d3[1]-d2[1] == 1:
                                    if d2[0]-d1[0] == 1:
                                        if d2[1]-d1[1] == 1:
                                            return "owin"
while loop == True:

xinput = input(namex + ", you're X. What column do you want to play in? Please enter a number 0-6 ")
xcolumn = int(xinput)
xrow = 5
occupied1 = False
while occupied1 == False:
    if game[xcolumn][xrow] == ".": #if there is a "." change to "X"
        game[xcolumn][xrow] = "X"
        output(game)
        occupied1 = True
    xrow -= 1
if check(game) == "xwin":
    loop = False
    print(namex + " wins!")
    break
if check(game) == "owin":
    loop = False
    print(nameo + " wins!")
    break
oinput = input(nameo + ", you're O. What column do you want to play in? Please enter number 0-6 ")
ocolumn = int(oinput)
orow = 5
occupied2 = False
while occupied2 == False:
    if game[ocolumn][orow] == ".": #if there is a "." change to "O"
        game[ocolumn][orow] = "O"
        output(game)
        occupied2 = True
    orow -= 1
if check(game) == "xwin":
    loop = False
    print(namex + " wins!")
    break
if check(game) == "owin":
    loop = False
    print(nameo + " wins!")
    break

我也愿意接受任何其他建议,以使我的游戏代码更好。谢谢!

2 个答案:

答案 0 :(得分:0)

一个好的开始是编写一个通用函数来检查任意位置的对角线:

def diagonal(grid, x, y, piece):
    '''
    Return True if grid contains a four-in-a-row diagonal starting at coordinates
    (x, y) and traveling downwards and to the right.  Otherwise return False.
    '''

    for i in range(x, x+4):
        # if this square does not contain the desired piece, return False
        if grid[x+i][y+i] != piece
            return False
    # if we got all the way through the loop, this must be a diagonal
    return True

然后,您将为每个X和O玩家为一个四角形对角线的每个可能的起始坐标调用此函数。

为改进此功能,您可以添加一种方法来检查在其他方向(向上和向右)行进的对角线。

答案 1 :(得分:0)

我有一些业余时间,所以我重写了您的程序。现在,它的效率要高得多。阅读评论以了解其工作原理

cols = [[] for x in range(6)]
# I opted to have a matrix of COLUMNS rather than rows because you can easily
# append items to the end of the list to simulate a real tile being placed there
# it's more intuitive and saves us time, as you'll see


def checkWin(cols):
    for i in range(6): # Each column
        for j in range(6): # Each row
            try: #check if the element at these coordinates exists yet
                cols[i][j]
            except IndexError:
                break
                # go back to next i - impossible that there's anything with a higher
                # j because if a list is n items long, and we go to j (which is one
                # higher than n and doesn't exist) then there can't be an element at
                # index j + someNumber.
            ret = False
            try: #vertical: j is the index in each column, so this goes up the column
                if cols[i][j] == cols[i][j+1] == cols[i][j+2] == cols[i][j+3] is not None:
                    ret = True
            except IndexError: #one of the elements of the comparison doesn't exist
                pass #We can't be sure that none of the other trials will return True
            try: #horizontal
                if cols[i][j] == cols[i+1][j] == cols[i+2][j] == cols[i+3][j] is not None:
                    ret = True
            except IndexError:
                pass
            try: #diagonal
                if cols[i][j] == cols[i+1][j+1] == cols[i+2][j+2] == cols[i+3][j+3] is not None:
                    ret = True
            except IndexError:
                pass
            try: #other diagonal
                if cols[i][j] == cols[i-1][j+1] == cols[i-2][j+2] == cols[i-3][j+3] is not None:
                    ret = True
            except IndexError:
                pass
            if ret:
                return cols[i][j]
    return None # We've gone through every single possible element and there are NO matches
def printBoard(cols):
    # Pretty intuitive function IMO - we swap i and j to go through rows.
    returnstr = '\n1 2 3 4 5 6\n'
    for i in range(6):
        for j in range(6):
            try:
                cols[j][5-i]
            except IndexError:
                returnstr += '_ '
                continue
            returnstr += cols[j][5-i]+' '
        returnstr += '\n'
    print(returnstr)
playerX = input('Player X, input your name: ')
playerO = input('Player O, input your name: ')
if playerX == playerO:
    print("Cannot have the same name!")
    exit()
count = 0
while not checkWin(cols):
    printBoard(cols)
    i = input('{}, input your column (1-6): '.format(playerO if count else playerX))
    try:
        target = cols[int(i)-1]
        if len(target) == 6:
            print("Column {} is already full! Please pick another.".format(i))
            continue
        target.append('O' if count else 'X')
    except ValueError:
        print("'{}' is not a number! Try again.".format(i))
        continue
    except IndexError:
        print("{} is not a valid column number! Please pick another.".format(i))
        continue
    count = (count+1) % 2
printBoard(cols)
if checkWin(cols) == 'X':
    print('{} (Player X), you win!'.format(playerX))
else:
    print('{} (Player O), you win!'.format(playerO))