Repository: openai/gym

Issue:
[Bug Report] Cannot render toy_text envs in Google Colab
**Describe the bug**

The `env.render()` functionality is broken for toy text envs when running in google colab.


**Code example**

Below is a simple example to repro this bug, see also this [notebook](https://colab.research.google.com/drive/1aibrJhzxNN7UwbgdhGQR2YhlUWZjCSYU).

```python
%pip install 'gym==0.25.1' --quiet

import gym
print(gym.__version__)  # 0.25.1
```

```python
env = gym.make('FrozenLake-v1')
env.reset()
env.render()  # error: No available video device
```

The error is triggered when pygame tries to initialize the (nonexistent) display:
```python
pygame.init()          # ok
pygame.display.init()  # fail
```

**System Info**
This is running on google colab ([notebook](https://colab.research.google.com/drive/1aibrJhzxNN7UwbgdhGQR2YhlUWZjCSYU)).

**Additional context**

It looks like the backend for toy text envs was changed to pygame. What was the reason for that change?


Discussion:
FWIW I can't access the notebook, you need to update permissions.

>It looks like the backend for toy text envs was changed to pygame. What was the reason for that change?

It looks better and functions analogously to all other envs (i.e. you can render it as an image, and then record a video or something).

---
In any case, the old mode is available via 
```python
env = gym.make('FrozenLake-v1', render_mode="ansi"))
env.reset()
print(env.render()[0])
```

There is an extra hitch in the fact that the `ansi` mode returns a list of renders, but it should work without any rendering devices.

I suspect that rendering is broken for collab and jupyter notebook. 
My guess is human rendering for collab will never work due to the code not running locally. As for jupyter notebook, it works, it just crashes. 
@andrewtanJS is currently investigating the notebook issue
Thanks, yes I looked into it a bit further this morning and looks like the general rendering API has changed.

As an end user, it's not clear what to expect from `env.render()` in general. It seems that it may ...
- return values without rendering side-effects
- return values with rendering side-effects
- return nothing but has rendering side-effects
- return nothing and no rendering side-effects (maybe because something failed silently)

Also, a small nit: `env.render(mode='somemode')` has no effect if `env.render_mode` is set.
PS I updated the notebook, it's basically just import gym, env.reset(), env.render().
>As an end user, it's not clear what to expect from env.render() in general.

Oh yea, that's an unfortunate artifact of the code we were left with when we restarted the maintenance. It's the reason why the render API is undergoing major changes, one of which is the whole `env.render_mode` thing.

In a future release, you won't be calling `env.render(mode='somemode')`, currently it's only kept for backwards compatibility. Instead, you just set the render mode on initialization, and call `env.render()`.


I'm afraid we don't have a clear plan at the moment to properly make it make sense, because the output of `env.render()` will still depend on the render mode. And we can't easily just rip it out and rewrite in a more sane way, because it's very ingrained in many codebases already.

Resolving patch:
diff --git a/gym/envs/toy_text/cliffwalking.py b/gym/envs/toy_text/cliffwalking.py
--- a/gym/envs/toy_text/cliffwalking.py
+++ b/gym/envs/toy_text/cliffwalking.py
@@ -183,9 +183,10 @@ def _render_gui(self, mode):
 
         if self.window_surface is None:
             pygame.init()
-            pygame.display.init()
-            pygame.display.set_caption("CliffWalking")
+
             if mode == "human":
+                pygame.display.init()
+                pygame.display.set_caption("CliffWalking")
                 self.window_surface = pygame.display.set_mode(self.window_size)
             else:  # rgb_array
                 self.window_surface = pygame.Surface(self.window_size)
diff --git a/gym/envs/toy_text/frozen_lake.py b/gym/envs/toy_text/frozen_lake.py
--- a/gym/envs/toy_text/frozen_lake.py
+++ b/gym/envs/toy_text/frozen_lake.py
@@ -294,9 +294,10 @@ def _render_gui(self, mode):
 
         if self.window_surface is None:
             pygame.init()
-            pygame.display.init()
-            pygame.display.set_caption("Frozen Lake")
+
             if mode == "human":
+                pygame.display.init()
+                pygame.display.set_caption("Frozen Lake")
                 self.window_surface = pygame.display.set_mode(self.window_size)
             elif mode in {"rgb_array", "single_rgb_array"}:
                 self.window_surface = pygame.Surface(self.window_size)


Test patch: