Similar Problems

Similar Problems not available

Cat And Mouse Ii - Leetcode Solution

Companies:

LeetCode:  Cat And Mouse Ii Leetcode Solution

Difficulty: Hard

Topics: dynamic-programming math matrix array graph  

Problem Statement:

You are given a string s representing a game board where '*' means a maze block, '.' means a dot in an empty space, and '#' means a wall in an empty space. There are also two players: "cat" and "mouse". Both cat and mouse start at the position of the respective character.

Players take turns, with the cat going first. During each turn, one player moves to an empty adjacent block (up, down, left, or right). When the mouse is adjacent to a wall, it cannot move. If either Cat or Mouse occupies the same position as the destination after the move, they win.

The game ends after n moves if the mouse has not been caught.

Return true if the game is won by any player, and false if the game is a draw.

Assumptions:

  • "cat" and "mouse" are valid strings of length 1.
  • "cat" and "mouse" do not occur in the game board.
  • Each move must take a different block position otherwise the game is invalid.

Sample input: board = ["####F","#C...","M...."]

board[0] = "####F" board[1] = "#C..." board[2] = "M...."

Explanation:

Starting from the given maze, where '#' is a wall, '*' is a block, '.' is an empty space, 'C' represents the cat, and 'M' represents the mouse.

The cat is positioned at (1, 1), and the mouse is positioned at (2, 0).

Cat's first move: (1, 1) -> (0, 1) [["####F","C#...","M...."]]

Mouse's first move: (2, 0) -> (1, 0) [["####F","C#...",".M..."]]

Cat's second move: (0, 1) -> (0, 0) [["####F","C#...","CM..."]]

Mouse's second move: (1, 0) -> (0, 0) [["####F","C#...","M...."]]

Mouse has been caught by the cat, so the game is won by the cat.

Solution:

The solution to the problem can be achieved by implementing the simulation of the game as follows:

Step 1: Create a matrix to represent the game board.

Step 2: Find the start positions of the cat and mouse.

Step 3: Initialize the current player to the cat.

Step 4: Loop through the game moves for a maximum of n moves.

Step 5: Identify the valid possible moves for the current player and randomly choose one of them.

Step 6: Implement the move and set the current player to the opposite player.

Step 7: Check if the game is won by any player, if so return the corresponding result.

Step 8: If the maximum number of moves is reached without one of the players winning, return false.

Below is the implementation of the above algorithm.

Implementation of the solution

import random

class Solution: def canMouseWin(self, grid: List[str], catJump: int, mouseJump: int) -> bool: rows = len(grid) cols = len(grid[0]) MAX_MOVES = 70 grid = [list(s) for s in grid] walls = set() for i in range(rows): for j in range(cols): if grid[i][j] == '#': walls.add((i, j))

    def get_neighbors(i, j):
        neighbors = [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]
        result = []
        for x, y in neighbors:
            if (x, y) not in walls and 0 <= x < rows and 0 <= y < cols:
                result.append((x, y))
        return result

    start = {}
    for i in range(rows):
        for j in range(cols):
            if grid[i][j] == 'C':
                start['C'] = (i, j)
            elif grid[i][j] == 'M':
                start['M'] = (i, j)

    def is_reachable(source, target, jump):
        queue = [source]
        visited = set(queue)
        steps = 0
        while queue:
            queue_size = len(queue)
            for i in range(queue_size):
                x, y = queue.pop(0)
                if (x, y) == target:
                    return steps
                for nx, ny in get_neighbors(x, y):
                    if (nx, ny) not in visited:
                        distance = (nx - source[0])**2 + (ny - source[1])**2
                        if distance <= jump**2:
                            queue.append((nx, ny))
                            visited.add((nx, ny))
            steps += 1
        return -1

    for i in range(rows):
        for j in range(cols):
            if grid[i][j] == '.':
                cat_distance = is_reachable(start['C'], (i, j), catJump)
                mouse_distance = is_reachable(start['M'], (i, j), mouseJump)
                if cat_distance != -1 and (cat_distance < mouse_distance or mouse_distance == -1):
                    grid[i][j] = 'C'
                elif mouse_distance != -1:
                    grid[i][j] = 'M'

    def simulate(board, player, moves):
        cat = board[start['C'][0]][start['C'][1]]
        mouse = board[start['M'][0]][start['M'][1]]
        count = 0
        while count < moves:
            count += 1
            if player == 'C':
                options = []
                ci, cj = start['C']
                for ni, nj in get_neighbors(ci, cj):
                    if board[ni][nj] != '#':
                        options.append((ni, nj))
                if not options:
                    return False
                move = random.choice(options)

                board[start['C'][0]][start['C'][1]] = '.'
                start['C'] = move
                if board[move[0]][move[1]] == 'M':
                    return False
                board[move[0]][move[1]] = 'C'

                player = 'M'
                cat = board[start['C'][0]][start['C'][1]]

            else:
                options = []
                mi, mj = start['M']
                for ni, nj in get_neighbors(mi, mj):
                    if board[ni][nj] != '#':
                        options.append((ni, nj))
                if not options:
                    return True
                move = random.choice(options)

                board[start['M'][0]][start['M'][1]] = '.'
                start['M'] = move
                if board[move[0]][move[1]] == 'C':
                    return True
                board[move[0]][move[1]] = 'M'

                player = 'C'
                mouse = board[start['M'][0]][start['M'][1]]

        return False

    return simulate(grid, 'C', MAX_MOVES)

Cat And Mouse Ii Solution Code

1