0

I have tried for a long time so make a method which finds the Manhattan distance between two game boards (2d arrays), but I can't figure out how. I understand what it is supposed to do: say if tile nr 5 in self.board has the coordinates (2,2) and tile 5 in the other board has the coordinates (1,1), it takes x1-x2 + y1-y2 and we get a total of 2 (number of moves). I doesn't matter if we get a negative number since we are using absolute.

I am testing it with "print(EightGameNode().manhattan_distance([[6,4,7],[8,5,0],[3,2,1]]))"

def manhattan_distance(self,other):
    '''
    Returns the sum of the number of moves a tile must do to move from where it is in self to
    where it is in the other board if there were no other tiles on the board
    :param other: the other board to compare to
    :return: the sum of the number of moves for each tile
    '''
    dist = 0
    for i in range (3):
        for j in range (3):
            if self.board[i][j] == 0: # If it is the empty cell
                continue
            else:
                targetX = #The x-coordinate of the "other" board
                targetY = #The y-coordinate of the "other" board
                dx = i - targetX #The x-distance to expected coordinate
                dy = j - targetY #The y-distance to expected coordinate
                dist += abs(dx) + abs(dy)

FULL CODE:

DEFAULT_BOARD = [[1, 2, 3], [4, 5, 6], [7, 8, 0]]
'''
A default board if another board is not specified in the constructor
'''

def __init__(self, the_board = DEFAULT_BOARD):
    '''
    Makes a new node from an initial board
    :param the_board: the initial board
    '''
    if EightGameNode.legal_board(the_board):
        # if the board is legal go on
        self.board = the_board
    else:
        # otherwise use the default board
        self.board = EightGameNode.DEFAULT_BOARD
    self.empty = EightGameNode.get_empty(self.board)
    # set the empty space of the board        

def hamming_distance(self,other):
    '''
    Returns the number of tiles which are not correctly placed compared to other (which may be a goal)
    :param other: the other board to compare to
    :return: the number of tiles which are not correctly placed
    '''
    dist = 0
    for i in range (3):
        for j in range (3):
            if self.board[i][j] != other.board[i][j]:
                dist += 1
    return dist

**def manhattan_distance(self,other):**
    '''
    Returns the sum of the number of moves a tile must do to move from where it is in self to
    where it is in the other board if there were no other tiles on the board
    :param other: the other board to compare to
    :return: the sum of the number of moves for each tile
    '''
    dist = 0
    for i in range (3):
        for j in range (3):
            if self.board[i][j] == 0: # If it is the empty cell
                continue
            else:
                targetX = #The x-coordinate of the "other" board
                targetY = #The y-coordinate of the "other" board
                dx = i - targetX #The x-distance to expected coordinate
                dy = j - targetY #The y-distance to expected coordinate
                dist += abs(dx) + abs(dy) 
    return dist

I am testing it with print(EightGameNode().manhattan_distance([[6,4,7],[8,5,0],[3,2,1]]))

  • Does this answer your question? [Calculating Manhattan Distance in Python in an 8-Puzzle game](https://stackoverflow.com/questions/16318757/calculating-manhattan-distance-in-python-in-an-8-puzzle-game) – Liju Sep 13 '20 at 12:12

1 Answers1

1

Manhattan could using a reverse lookup table.

Code

def manhattan_distance(self, other):
    ' Distance between where tiles are and where they should be  '
    
    # Generate reverse lookup table so we know where each item should be located
    lookup_loc = {}
    if i in range(3):
        for j in range(3):
            # other.board[i][j] is the value
            # which has location at (i, j)
            lookup_loc[other.board[i][j]] = (i, j)
          
    dist = 0
    for i in range(3):
        for j in range(3):
            if self.board[i][j] != other.board[i][j]:
                # Find correct location for value self.board[i][j]
                correct_loc = lookup_loc[self.board[i][j]]

                # Manhattan distance between current location (i, j) and
                # correction location
                dist += abs(correct_loc[0]-i) + abs(correct_loc[1] - j)
    return dist
DarrylG
  • 16,732
  • 2
  • 17
  • 23