The Bomberman Game

Sort by

recency

|

36 Discussions

|

  • + 0 comments

    Observation: There is a pattern: --> The blast at 3rd second, 7th second, 11th second.... will be the same. --> Similarly, the blast at 5th second, 9th second, ... and so on will be the same. What we can do is to create a function that gets us the output grid for the 3rd second (1st blast). Now if we run that function again with the input of the 1st blast, we will get the output for the 5th second (2nd blast)

    My code:

    const filledGrid = (grid) => {
      return grid.map((row) =>
        row
          .split("")
          .map((ele) => "O")
          .join("")
      );
    };
    
    const secondPattern = (grid) => {
      let newGrid = grid.map((row) => row.split("").map((el) => "O"));
      for (let i = 0; i < grid.length; i++) {
        for (let j = 0; j < grid[0].length; j++) {
          if (grid[i][j] === "O") {
            newGrid[i][j] = ".";
            if (i > 0) {
              newGrid[i - 1][j] = ".";
            }
            if (j > 0) {
              newGrid[i][j - 1] = ".";
            }
            if (i < grid.length - 1) {
              newGrid[i + 1][j] = ".";
            }
            if (j < grid[0].length - 1) {
              newGrid[i][j + 1] = ".";
            }
          }
        }
      }
      return newGrid.map((row) => row.join(""));
    };
    
    function bomberMan(n, grid) {
        // Write your code here
        if (n === 1) return grid;
        if(n % 2 === 0) return filledGrid(grid);
        let secondPatternMatch = false;
        for(let i = 2; i <=n; i++)
        {
            if(i % 2 !== 0)
            {
                secondPatternMatch = !secondPatternMatch;
            }
        }
        return secondPatternMatch ? secondPattern(grid) : secondPattern(secondPattern(grid)); 
        
    
    }
    

    What I am doing is using a flag variable to check the seconds.

    
    

    `

  • + 0 comments

    Python3 short but horrible:

    adj = ((0, 0), (-1, 0), (1, 0), (0, -1), (0, 1))
    def detonate(grid, t, i, j):
        return any(t - grid[i + x][j + y] == 3 for x, y in adj if i + x >= 0 and j + y >= 0 and i + x < len(grid) and j + y < len(grid[0]))
        
    def bomberMan(n, grid):
        n = min(n, 2 + (n-2) % 4)
        grid = [[('.', 0)[c == 'O'] for c in r] for r in grid]
        
        for t in range(2, n+1, 2):
            grid = [[t if c == '.' else c for c in r] for r in grid]
            if t+1 <= n:
                grid = [['.' if detonate(grid, t+1, i, j) else grid[i][j] for j in range(len(grid[i]))] for i in range(len(grid))]
        
        return [''.join(('O', '.')[c == '.'] for c in r) for r in grid]
    
  • + 0 comments

    C#:

    public static List<string> bomberMan(int n, List<string> grid)
        {
            if(n == 1)
                return grid;
            List<string> stuffedGrid = new List<string>();
            List<string> detonationGrid = new List<string>();
            string str1 = "";
            for(int j = 0; j < grid[0].Length; j++)
            {
                str1+="O";
            }
            for(int i = 0; i < grid.Count; i++)
            {
                stuffedGrid.Add(str1);
            }
            if(n % 2 == 0)
                return stuffedGrid;
                
            else if(n % 4 == 3)
            {
                detonationGrid = getBombLocations(stuffedGrid, grid);
            }               
            else
            {
                detonationGrid = getBombLocations(stuffedGrid, getBombLocations(stuffedGrid,grid));
            }
            return detonationGrid;
        }
        public static List<string> getBombLocations(List<string> stuffedGrid, List<string> grid)
        {
            List<string> detonatingGrid = new List<string>();
            detonatingGrid.AddRange(stuffedGrid);
            char[] temp = new char[grid[0].Length];
            for(int i = 0; i < grid.Count; i++)
            {
                string str = grid[i];
                for(int  j = 0; j < str.Length; j++)
                {
                    if(str[j] == 'O')
                    {
                         temp = detonatingGrid[i].ToCharArray();
                         temp[j] = '.';
                         string replaceBomb = new string(temp);
                         detonatingGrid[i] = replaceBomb;
                        if(j != str.Length-1){
                            temp = detonatingGrid[i].ToCharArray();
                            temp[j+1] = '.';
                            string replaceRight = new string(temp);
                            detonatingGrid[i] = replaceRight;
                        }
                        if(i != grid.Count-1){
                            temp = detonatingGrid[i+1].ToCharArray();
                            temp[j] = '.';
                            string replaceDown = new string(temp);
                            detonatingGrid[i+1] = replaceDown;
                        }
                        if(j != 0){
                            temp = detonatingGrid[i].ToCharArray();
                            temp[j-1] = '.';
                            string replaceLeft = new string(temp);
                            detonatingGrid[i] = replaceLeft;
                        }
                        if(i != 0){
                            temp = detonatingGrid[i-1].ToCharArray();
                            temp[j] = '.';
                            string replaceUp = new string(temp);
                            detonatingGrid[i-1] = replaceUp;
                        }
                    }
                } 
            }
            return detonatingGrid;
        }
    
  • + 0 comments

    Python - uses a nice 'discard this bomb location if it exists' set operation so you can 'explode' the five bomb squares without worrying about bound checking.

    Classic HR 'hope you know this trick about the problem' feature where you have to know that the solution will bounce between two states in a stable pattern ... else trying to solve it by performing all the steps takes too long for the test cases and hits timeouts.

    def bomberMan(n, grid):
        rows = len(grid)
        cols = len(grid[0])
        
        bombs = set(
            (r_idx, c_idx) 
            for r_idx, row in enumerate(grid)
            for c_idx, element in enumerate(row)
            if element == 'O'
        )
        
        bombs_everywhere = set(
            (r_idx, c_idx) 
            for r_idx, row in enumerate(grid)
            for c_idx, element in enumerate(row)
        )
        
        def bomb(bomb_locations):
            next_state = bombs_everywhere.copy()
            for bomb in bomb_locations:
                r_idx, c_idx = bomb
                next_state.discard((r_idx, c_idx))
                next_state.discard((r_idx - 1, c_idx))
                next_state.discard((r_idx + 1, c_idx))
                next_state.discard((r_idx, c_idx + 1))
                next_state.discard((r_idx, c_idx - 1))
            return next_state
                
        def set_to_grid(inset):
            return [
                ''.join(['O' if (r, c) in inset else '.' for c in range(cols)]) 
                for r in range(rows)
            ]
        
        if n == 1:
            return grid
        if n % 2 == 0:
            return set_to_grid(bombs_everywhere)
        if n % 4 == 3:
            return set_to_grid(bomb(bombs))
        else:
            return set_to_grid(bomb(bomb(bombs)))
    
  • + 0 comments

    Python. Runs the clock and does explosions until a cycle is found. For explosion steps, grid for each t % 2 == 1 is kept in the memory. Once the cycle is found, number of steps to make through the graph is calculated, as well as the cycle length and with that final_t can be calculated.

    def removeBomb(row, idx):
        return row[:idx] + '.' + row[idx + 1:]
    
    
    def gridHash(grid):
        return "".join(grid)
    
    def createAllBombsGrid(r, c):
        return ["O" * c for _ in range(r)]
    
    def gridAfterExplode(grid, r, c):
        new_grid = createAllBombsGrid(r, c)
        
        for i in range(r):
            for j in range(c):
                if grid[i][j] == '.':
                    continue
                    
                # it's a bomb!
                for x in range(-1, 2):
                    # iter -1..1
                    
                    i_shifted = i + x
                    if i_shifted < 0 or i_shifted == r:
                        continue
                        
                    new_grid[i_shifted] = removeBomb(new_grid[i_shifted], j)
                    
                for y in range(-1, 2):
                    j_shifted = j + y
                    if j_shifted < 0 or j_shifted == c:
                        continue
                        
                    new_grid[i] = removeBomb(new_grid[i], j_shifted)
                    
        return new_grid
        
        
    def calculate_final_t(cycle_start, cycle_end, n):
        n_minus_cycle_start = n - cycle_start
        moves_to_make = n_minus_cycle_start // 2
        
        diff = cycle_end - cycle_start
        cycle_len = diff // 2 + 1
        
        remainder = moves_to_make % cycle_len
        
        final_t = cycle_start + remainder * 2
        
        return final_t
    
    def bomberMan(n, grid):
        r = len(grid)
        c = len(grid[0])
        
        grid_hash = gridHash(grid)
        grid_to_t = {grid_hash: 1}
        t_to_grid = {1: grid}
        
        if n == 1:
            return grid
            
        if n % 2 == 0:
            return createAllBombsGrid(r, c)
        
        for t in range(3, n + 1, 2):
            grid = gridAfterExplode(grid, r, c)
            
            if t == n:
                return grid
            
            grid_hash = gridHash(grid)
            
            if grid_hash in grid_to_t:
                break
            else:
                grid_to_t[grid_hash] = t
                t_to_grid[t] = grid
        
        cycle_start = grid_to_t[grid_hash]
        cycle_end = t - 2
        
        final_t = calculate_final_t(cycle_start, cycle_end, n)
    
        return t_to_grid[final_t]