Повторяющиеся для циклов в игре 2048 года

У меня есть следующая функция, определенная в программе, которая реализует игру 2048. Я попытался сконденсировать повторяющуюся часть кода в один цикл, содержащий +1 смещение переменных для индексов, которые либо установлены в 0 или 1 в зависимости от направления, переданного в функцию, но внешние и внутренние переменные цикла меняются в зависимости от направления , Может ли кто-нибудь дать мне несколько указаний о том, как сконденсировать этот код и сделать его более чистым, пуфоническим и кратким?

def merge(direction):
    #if adjacent cells are equal, they are merged into one with twice the value and then moved.
    if direction == "up":
        for col in range(nColumns):
            for row in range(nRows-1):
                if grid[row][col] == grid[row+1][col]:
                    grid[row][col] = grid[row+1][col]*2
                    grid[row+1][col] = 0
                    move(direction)

    if direction == "down":
        for col in range(nColumns):
            for row in range(nRows-1):
                if grid[row][col] == grid[row+1][col]:
                    grid[row+1][col] = grid[row][col]*2
                    grid[row][col] = 0
                    move(direction)

    if direction == "left":
        for row in range(nRows):
            for col in range(nColumns-1):
                if grid[row][col] == grid[row][col+1]:
                    grid[row][col] = grid[row][col]*2
                    grid[row][col+1] = 0
                    move(direction)

    if direction == "right":
        for row in range(nRows):
            for col in range(nColumns-1):
                if grid[row][col] == grid[row][col+1]:
                    grid[row][col+1] = grid[row][col]*2
                    grid[row][col] = 0
                    move(direction)
11 голосов | спросил ohBoy 28 MarpmFri, 28 Mar 2014 18:23:52 +04002014-03-28T18:23:52+04:0006 2014, 18:23:52

2 ответа


6

Итерация более гибко может упростить ваши циклы.

Для начала запустите этот автономный пример и убедитесь, что выражение izip(…) создает полезные пары координат:

from itertools import product, izip
nRows, nColumns = 3, 5
for dest, src in izip(product(range(nRows - 1), range(nColumns)),
                      product(range(1, nRows), range(nColumns))):
    print(dest, src)

Затем вы можете повторно использовать цикл, просто изменив диапазоны, в которые вы проходите.

from itertools import product, izip

def merge(direction):
    def merge(dest_iterator, src_iterator):
        for (dr, dc), (sr, sc) in izip(dest_iterator, src_iterator):
            if grid[dr][dc] == grid[sr][sc]:
                 grid[dr][dc] == 2 * grid[sr][sc]
                 grid[sr][sc] = 0
                 move(direction)

    if direction == "up":
        merge(product(range(nRows - 1), range(nColumns)),
              product(range(1, nRows), range(nColumns)))
    elif direction == "down":
        merge(product(range(1, nRows), range(nColumns)),
              product(range(nRows - 1), range(nColumns)))
    elif direction == "left":
        merge(product(range(nRows), range(nColumns - 1)),
              product(range(nRows), range(1, nColumns)))
    elif direction == "down":
        merge(product(range(nRows), range(1, nColumns)),
              product(range(nRows), range(nColumns - 1)))
ответил 200_success 28 MarpmFri, 28 Mar 2014 19:34:50 +04002014-03-28T19:34:50+04:0007 2014, 19:34:50
3

Вы можете использовать dictionary of lambda s, чтобы найти места принятия и пожертвования ячеек в сетке. Затем поместите операции в try /except, который просто выйдет из строя, если вы выйдете за пределы

GetLocations = dict(
    up = lambda r,c: (r,c,r+1,c ),
    down = lambda r,c: (r+1,c,r,c ),
    right = lambda r,c: (r,c,r,c+1),
    left = lambda r,c: (r,c+1,r,c ))

def merge(direction):
    for col in range(nColumns):
        for row in range(nRows):
            #get acceptor and doner locations
            ar,ac,dr,dc = GetLocations[direction](row,col)
            try:
                #if the evaluation doesn't fail, nothing will fail
                if grid[ar][ac] == grid[dr][dc]:
                    grid[ar][ac] = grid[dr][dc]*2
                    grid[dr][dc] = 0
                    move(direction)
            except IndexError:
                pass
ответил flakes 28 MarpmFri, 28 Mar 2014 19:37:20 +04002014-03-28T19:37:20+04:0007 2014, 19:37:20

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132