The State object represents everything the game needs to know about any single simulated frame.

You can rewind in time by storing and restoring these state representations.

  • Access the json: to_json
  • Access the image: render_frame

__init__(self, sim, state=None)

Show source code in ctoybox/ffi.py
127
128
129
130
131
132
133
134
135
136
137
    def __init__(self, sim: Simulator, state=None):
        """
        Construct a new State instance wrapper.

        Parameters:
            sim: The simulator responsible for this state.
            state: Optional pointer to a state to use (otherwise it will create one). 
        """
        self.__state = state or lib.state_alloc(sim.get_simulator())
        self.game_name = sim.game_name
        self.deleted = False

Construct a new State instance wrapper.

Parameters

Name Type Description Default
sim Simulator The simulator responsible for this state. required
state _empty Optional pointer to a state to use (otherwise it will create one). None

game_over(self)

Show source code in ctoybox/ffi.py
168
169
170
171
172
173
    def game_over(self):
        """Determine whether the game has ended; i.e., the player has run out of lives.

        >>> assert self.lives() < 0 == self.game_over()
        """
        return self.lives() < 0

Determine whether the game has ended; i.e., the player has run out of lives.

assert self.lives() < 0 == self.game_over()

get_state(self)

Show source code in ctoybox/ffi.py
151
152
153
154
    def get_state(self):
        """Get the raw state pointer."""
        assert(self.__state is not None)
        return self.__state

Get the raw state pointer.

level(self)

Show source code in ctoybox/ffi.py
160
161
162
    def level(self) -> int:
        """How many levels have been completed in the current state?"""
        return lib.state_level(self.__state)

How many levels have been completed in the current state?

lives(self)

Show source code in ctoybox/ffi.py
156
157
158
    def lives(self) -> int:
        """How many lives are remaining in the current state?"""
        return lib.state_lives(self.__state)

How many lives are remaining in the current state?

query_json(self, query, args='null')

Show source code in ctoybox/ffi.py
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
    def query_json(self, query: str, args: Union[Dict[str, Any], str]="null") -> Dict[str, Any]:
        """
        Ask a question of the Rust state; queries are currently implemented manually.

        Parameters:
            query: the message to send to the rust state.
            args: the arguments to send to the rust state, defaults to "null".

        Returns:
            response: A JSON response loaded to python objects.

        Raises:
            ValueError: if anything goes wrong with the query

        ```python
        with Toybox("breakout") as tb:
          tb.query_json("bricks_remaining")
        ```
        """
        txt = rust_str(lib.state_query_json(self.__state, json_str(query).encode('utf-8'), json_str(args).encode('utf-8')))
        try:
            out = json.loads(txt)
        except:
            raise ValueError(txt)
        return out

Ask a question of the Rust state; queries are currently implemented manually.

Parameters

Name Type Description Default
query str the message to send to the rust state. required
args Union[Dict[str, Any], str] the arguments to send to the rust state, defaults to "null". null

Returns

Type Description
Dict[str, Any] response: A JSON response loaded to python objects.

Exceptions

Type Description
ValueError if anything goes wrong with the query
with Toybox("breakout") as tb:
  tb.query_json("bricks_remaining")

render_frame(self, sim, grayscale=True)

Show source code in ctoybox/ffi.py
201
202
203
204
205
206
207
208
209
210
211
    def render_frame(self, sim: Simulator, grayscale: bool =True) -> np.array:
        """Generate an image from the current frame state object.

        Parameters:
            sim: the simulator to use; this tells us the width/height necessary.
            grayscale: True if we want to render in grayscale rather than in color (RGBA).
        """
        if grayscale:
            return self.render_frame_grayscale(sim)
        else:
            return self.render_frame_color(sim)

Generate an image from the current frame state object.

Parameters

Name Type Description Default
sim Simulator the simulator to use; this tells us the width/height necessary. required
grayscale bool True if we want to render in grayscale rather than in color (RGBA). True

render_frame_color(self, sim)

Show source code in ctoybox/ffi.py
213
214
215
216
217
218
219
220
221
222
223
224
225
226
    def render_frame_color(self, sim: Simulator) -> np.array:
        """Generate an RGBA image from the current frame state object.

        Parameters:
            sim: the simulator to use; this tells us the width/height necessary.
        """
        h = sim.get_frame_height()
        w = sim.get_frame_width()
        rgba = 4
        size = h * w  * rgba
        frame = np.zeros(size, dtype='uint8')
        frame_ptr = ffi.cast("uint8_t *", frame.ctypes.data)
        lib.render_current_frame(frame_ptr, size, False, sim.get_simulator(), self.__state)
        return np.reshape(frame, (h,w,rgba))

Generate an RGBA image from the current frame state object.

Parameters

Name Type Description Default
sim Simulator the simulator to use; this tells us the width/height necessary. required

render_frame_grayscale(self, sim)

Show source code in ctoybox/ffi.py
237
238
239
240
241
242
243
244
245
246
247
248
249
    def render_frame_grayscale(self, sim: Simulator) -> np.array:
        """Generate a grayscale image from the current frame state object.

        Parameters:
            sim: the simulator to use; this tells us the width/height necessary.
        """
        h = sim.get_frame_height()
        w = sim.get_frame_width()
        size = h * w 
        frame = np.zeros(size, dtype='uint8')
        frame_ptr = ffi.cast("uint8_t *", frame.ctypes.data)
        lib.render_current_frame(frame_ptr, size, True, sim.get_simulator(), self.__state)
        return np.reshape(frame, (h,w,1))

Generate a grayscale image from the current frame state object.

Parameters

Name Type Description Default
sim Simulator the simulator to use; this tells us the width/height necessary. required

render_frame_rgb(self, sim)

Show source code in ctoybox/ffi.py
228
229
230
231
232
233
234
235
    def render_frame_rgb(self, sim: Simulator) -> np.array:
        """Generate an RGB image from the current frame state object.

        Parameters:
            sim: the simulator to use; this tells us the width/height necessary.
        """
        rgba_frame = self.render_frame_color(sim)
        return rgba_frame[:,:,:3]

Generate an RGB image from the current frame state object.

Parameters

Name Type Description Default
sim Simulator the simulator to use; this tells us the width/height necessary. required

score(self)

Show source code in ctoybox/ffi.py
164
165
166
    def score(self) -> int:
        """How many points have been earned in the current state?"""
        return lib.state_score(self.__state)

How many points have been earned in the current state?

to_json(self)

Show source code in ctoybox/ffi.py
251
252
253
254
    def to_json(self) -> Dict[str, Any]:
        """Get a JSON representation of the state."""
        json_str = rust_str(lib.state_to_json(self.__state))
        return json.loads(str(json_str))

Get a JSON representation of the state.