Sure! Here's a test case generator for the "Life Game" problem:

```python
import random

def generate_initial_state(N, M):
    initial_state = []
    for i in range(1, 2 * N):  # The number of rows is 2N - 1
        row_length = N + min(i, 2 * N - i - 1)
        row = [random.randint(0, M - 1) for _ in range(row_length)]
        initial_state.append(row)
    return initial_state

def tcgen():
    N = random.randint(1, 6)
    M = random.randint(2, 10**9)
    L = random.randint(1, 10**9)
    
    initial_state = generate_initial_state(N, M)
    
    return N, M, L, initial_state

def format_test_case(N, M, L, initial_state):
    test_case = f"{N} {M} {L}\n"
    for row in initial_state:
        test_case += " ".join(map(str, row)) + "\n"
    return test_case.strip()

# Generate a single test case and print it
N, M, L, initial_state = tcgen()
print(format_test_case(N, M, L, initial_state))
```

### Explanation:
1. **`generate_initial_state(N, M)`**: This function generates the initial state of the hexagonal grid. The grid has `2N - 1` rows, where the `i-th` row has `N + min(i, 2 * N - i - 1)` columns.
2. **`tcgen()`**: This function generates the parameters `N`, `M`, `L` and the initial state of the hexagonal grid.
3. **`format_test_case(N, M, L, initial_state)`**: This function formats the generated test case into a string that matches the expected input format.

You can use this generator to create multiple test cases and test your solution against them. Each time you run the generator, it will produce a new random test case within the constraints provided.