python bfs code with explanation
To push a box, we need two steps\n- Check whether we could go to the neighbor cell of the box. Also the opposite side of this neighbor cell should be empty. Oth
To push a box, we need two steps\n- Check whether we could go to the neighbor cell of the box. Also the opposite side of this neighbor cell should be empty. Otherwise there is no point moving there.\n\t- E.g. `.B.` has two neighbor cells which we could check whether we could move there\n\t- `#B.` won\'t be checked. Although there is an empty cell, however there is wall on the other side of the box. Even if the player could move there, he couldn\'t push the box\n- Push the box by one step. Here, our player is moved to the place where the original box is.\n\nIn the above two steps, we both use breadth first search to implement.\n\n```\ndef minPushBox(self, grid):\n\tplayer = None\n\tbox = None\n\ttarget = None\n\n\tn = len(grid)\n\tif n == 0:\n\t\treturn -1\n\tm = len(grid[0])\n\tif m == 0:\n\t\treturn -1\n\tfor i in range(n):\n\t\tfor j in range(m):\n\t\t\tif grid[i][j] == \'S\':\n\t\t\t\tplayer = (i, j)\n\t\t\tif grid[i][j] == \'T\':\n\t\t\t\ttarget = (i, j)\n\t\t\tif grid[i][j] == \'B\':\n\t\t\t\tbox = (i, j)\n\t\t\tif player != None and target != None and box != None:\n\t\t\t\tbreak\n\t\tif player != None and target != None and box != None:\n\t\t\tbreak\n\n\tqueue = [(box, target, player, 0)]\n\tvisited = set([(box, player)])\n\twhile len(queue) > 0:\n\t\tbox, target, player, steps = queue.pop()\n\t\tif target == box:\n\t\t\treturn steps\n\t\ti, j = box\n\t\tif i > 0 and i < (n-1) and grid[i-1][j] != \'#\' and grid[i+1][j] != \'#\':\n\t\t\tif ((i+1, j), (i, j)) not in visited:\n\t\t\t\tif self.canGoToBox(grid, (i-1, j), player, box):\n\t\t\t\t\tqueue.insert(0, ((i+1, j), target, (i, j), steps + 1))\n\t\t\t\t\tvisited.add(((i+1, j), (i, j)))\n\t\t\tif ((i-1, j), (i, j)) not in visited:\n\t\t\t\tif self.canGoToBox(grid, (i+1, j), player, box):\n\t\t\t\t\tqueue.insert(0, ((i-1, j), target, (i, j), steps + 1))\n\t\t\t\t\tvisited.add(((i-1, j), (i, j)))\n\n\t\tif j > 0 and j < (m-1) and grid[i][j-1] != \'#\' and grid[i][j+1] != \'#\':\n\t\t\tif ((i, j-1), (i, j)) not in visited:\n\t\t\t\tif self.canGoToBox(grid, (i, j+1), player, box):\n\t\t\t\t\tqueue.insert(0, ((i, j-1), target, (i, j), steps + 1))\n\t\t\t\t\tvisited.add(((i, j-1), (i, j)))\n\t\t\tif ((i, j+1), (i, j)) not in visited:\n\t\t\t\tif self.canGoToBox(grid, (i, j-1), player, box):\n\t\t\t\t\tqueue.insert(0, ((i, j+1), target, (i, j), steps + 1))\n\t\t\t\t\tvisited.add(((i, j+1), (i, j)))\n\treturn -1\n\ndef canGoToBox(self, grid, loc, player, box):\n\tif loc == player:\n\t\treturn True\n\trows = len(grid)\n\tcols = len(grid[0])\n\tqueue = [player]\n\tvisited = [player]\n\n\twhile len(queue) != 0:\n\t\ti, j = queue.pop()\n\t\tif (i, j) == loc:\n\t\t\treturn True\n\t\tneighbors = [(i-1, j), (i+1, j), (i, j-1), (i, j+1)]\n\t\tfor x, y in neighbors:\n\t\t\tif x >= 0 and x < rows and y >= 0 and y < cols:\n\t\t\t\tif (x, y) != box and grid[x][y] != "#" and (x, y) not in visited:\n\t\t\t\t\tqueue.append((x, y))\n\t\t\t\t\tvisited.append((x, y))\n\treturn False\n```
[]