<system>
You are an experienced Python developer. You will be provided with an incomplete code snippet from a Python program. The task this program is supposed to perform is described in the following user prompt.
Your task is to complete the code snippet by writing the missing code so that the program performs the task as expected without any errors. You will be rewarded based on the number of test cases your code passes.
</system>

<user>
Your task is to create a class which simulates the RTFM (Read to Fight Monsters) environment.

## Rules
The game is set in a grid of size 4x4. The elements of the game are a player (agent), items and monsters. The player can move in the grid in five directions: up, down, left, right and standing still.
When the player is in the same cell with a monster or weapon, the player picks up the item or engages in combat with the monster. The player can possess one item at a time, and drops existing weapons if they pick up a new weapon.
Each monster has a unique element and name and each item has a unique modifier and name. Each monster will also belong to a specific group. Each monster is stationary and will never move.
Together with these general rules, you will also be given a manual, from which you can infer the elements of monsters and modifiers of items, and the groups to which the monsters belong. Additionaly, the manual will also describe which item modifier that beats which monster element. You will have to implement these relationships in the code.

## Manual
The Rebel Enclave consists of demon, spider, and bandit.
Arcane, blessed items are useful for lightning monsters.
Star Alliance contains mage, goblin, and jinn.
Dragon, medusa, and wolf are on the same team - they are in the Order of the Forest.
Gleaming and mysterious weapons beat poison monsters.
Fire monsters are weak against Grandmaster's and Soldier's weapons.
Cold monsters are defeated by fanatical and shimmering weapons.

## Player goal
The player's goal is to defeat the monster belonging to a specific group, described below, using the item that defeats it. This is used to generate the reward function.
Goal: Defeat the Order of the Forest

## Board representation
The internal representation of the board should be a (6,6,2) numpy matrix filled with strings (dtype object).
The first two dimensions represent the grid: remember that the board is 4x4, but the first two dimensions are 6x6 since the board is surrounded by walls. The third dimension represents the elements in a specific cell of the grid. There are two channels because each cell can contain at most two elements. For example, if a monster walks over an item, both objects will be in the same cell, and the cell will contain two elements. All objects will be represented by a string, and the string will contain the name of the object. If a cell is empty, it will contain the string "empty". If a cell contains a wall, it will contain the string "wall".
Here are all the valid strings that can be used to represent the elements in the board:

- 'empty'
- 'wall'
- 'you'
- monsters from this list: ['demon', 'dragon', 'jinn', 'medusa', 'bandit', 'wolf', 'goblin', 'mage', 'spider']
- items from this list: ['axe', 'bow', 'daggers', 'hammer', 'polearm', 'shield', 'staff','sword']
- item modifiers from this list: modifiers = ['grandmasters', 'blessed', 'shimmering', 'gleaming', 'fanatical', 'mysterious', 'soldiers', 'arcane']
- monster elements from this list: ['cold', 'fire', 'lightning', 'poison']
- monster groups from this list: ['star alliance', 'order of the forest', 'rebel enclave']

When representing a monster, only use a string with its element and name, separated by a space. The group will be used in the code to determine the monster's weakness. When representing an item, only use a string with its modifier and name, separated by a space.

## Class Definition
The class should be called "Environment". It should have at least:

- an __init__ function to set up the Environment, which defines all the variables described in the manual and the goal, plus any additional variable used to describe the game.
- a set_state function to set a custom value for the board and change its internal representation should also be provided (you can assume that when "set_state" is used, the game is not done and internal variables should be set as a consequence). The input to set state is a tuple containing (board, inventory), where the board is a matrix of shape (6,6,2) whose entries can only be the strings described above and the inventory is a single string.
- a step function to predict a step in the environment. The input parameters for the step function are:
    - An action represented with an integer representing the direction in which the player will move. The action dictionary is the following: action_dict = {0:"Stay", 1:"Up", 2:"Down", 3:"Left", 4:"Right"}
  
    The outputs required by the step function are:
    - A frame object, representing the prediction of the next state. This is composed of a tuple with two elements:
      - A numpy matrix of shape (6,6,2) that will predict accurately the new board after the action has been simulated.
      - A string representing the player's inventory. If the player has no items, this should be "empty".

    - A numpy array containing the valid actions that the player can take in the next step. The array should contain the integers representing the directions in which the player can move. The action dictionary is the following: action_dict = {0:"Stay", 1:"Up", 2:"Down", 3:"Left", 4:"Right"}
    - A reward function (1 if the player wins, -1 if the player loses, 0 otherwise).
    - A boolean variable indicating if the game is done.

## Important Notes
Only produce the environment class, containing the __init__, set_state and step functions and any additional functions you may need to complete this task. Do not write an example of how to use the class or anything else.
Be careful about edge cases, such as the player moving out of the board or trying to move into a wall. In these cases, the player should stay in the same cell.
Make sure to write all the required functions and that they have the exact names as specified in the task description. Missing or incorrectly named functions will not pass the tests and will result in a score of 0.
It is of VITAL importance that you do not leave undefined any function, but implement each of them completely.
</user>

<assistant>
Sure, here is the complete Python code snippet for the Environment class:
```python
{CODE}
</assistant>