Spaces:
Running on Zero
Running on Zero
| """ | |
| LCD Grid System - A movable character on a 20x4 LCD. | |
| The LLM controls the character by outputting actions. | |
| """ | |
| import random | |
| class LCDGrid: | |
| """A 20x4 grid where a character can move around""" | |
| def __init__(self, cols=20, rows=4): | |
| self.cols = cols | |
| self.rows = rows | |
| # Character position (center) | |
| self.char_x = cols // 2 | |
| self.char_y = rows // 2 | |
| # Character appearance | |
| self.char = "@" | |
| self.mood = "neutral" # neutral, happy, sad, excited, angry, sleepy | |
| # Trail of where we've been | |
| self.trail = [] | |
| self.max_trail = 8 | |
| # Objects on the grid | |
| self.objects = [] # list of (x, y, char, name) | |
| # Animation state | |
| self.animation = None | |
| self.anim_frame = 0 | |
| # Mood faces | |
| self.mood_chars = { | |
| "neutral": "@", | |
| "happy": "^_^", | |
| "sad": "T_T", | |
| "excited": "O_O", | |
| "angry": ">_<", | |
| "sleepy": "-_-", | |
| "love": "<3", | |
| "coding": ">_", | |
| } | |
| # Direction vectors | |
| self.directions = { | |
| "up": (0, -1), | |
| "down": (0, 1), | |
| "left": (-1, 0), | |
| "right": (1, 0), | |
| "up-left": (-1, -1), | |
| "up-right": (1, -1), | |
| "down-left": (-1, 1), | |
| "down-right": (1, 1), | |
| } | |
| def move(self, direction): | |
| """Move character in a direction""" | |
| if direction not in self.directions: | |
| return False | |
| dx, dy = self.directions[direction] | |
| new_x = self.char_x + dx | |
| new_y = self.char_y + dy | |
| # Bounce off walls | |
| if new_x < 0 or new_x >= self.cols: | |
| dx = -dx | |
| new_x = self.char_x + dx | |
| if new_y < 0 or new_y >= self.rows: | |
| dy = -dy | |
| new_y = self.char_y + dy | |
| # Save trail | |
| self.trail.append((self.char_x, self.char_y)) | |
| if len(self.trail) > self.max_trail: | |
| self.trail.pop(0) | |
| self.char_x = new_x | |
| self.char_y = new_y | |
| return True | |
| def teleport(self, x, y): | |
| """Move character to specific position""" | |
| if 0 <= x < self.cols and 0 <= y < self.rows: | |
| self.trail.append((self.char_x, self.char_y)) | |
| if len(self.trail) > self.max_trail: | |
| self.trail.pop(0) | |
| self.char_x = x | |
| self.char_y = y | |
| return True | |
| return False | |
| def set_mood(self, mood): | |
| """Change character mood""" | |
| if mood in self.mood_chars: | |
| self.mood = mood | |
| self.char = self.mood_chars[mood] | |
| return True | |
| return False | |
| def add_object(self, x, y, char, name): | |
| """Add an object to the grid""" | |
| self.objects.append((x, y, char, name)) | |
| def clear_objects(self): | |
| """Clear all objects""" | |
| self.objects = [] | |
| def set_animation(self, animation): | |
| """Set an animation to play""" | |
| self.animation = animation | |
| self.anim_frame = 0 | |
| def render(self): | |
| """Render the grid to 4 lines of 20 chars""" | |
| # Create empty grid | |
| grid = [[' ' for _ in range(self.cols)] for _ in range(self.rows)] | |
| # Draw trail (dim) | |
| for i, (tx, ty) in enumerate(self.trail): | |
| if 0 <= tx < self.cols and 0 <= ty < self.rows: | |
| grid[ty][tx] = '.' | |
| # Draw objects | |
| for ox, oy, ochar, _ in self.objects: | |
| if 0 <= ox < self.cols and 0 <= oy < self.rows: | |
| grid[oy][ox] = ochar | |
| # Draw character | |
| char_display = self.char[:3] # Max 3 chars for mood | |
| start_x = self.char_x - len(char_display) // 2 | |
| for i, c in enumerate(char_display): | |
| x = start_x + i | |
| if 0 <= x < self.cols: | |
| grid[self.char_y][x] = c | |
| # Convert to strings | |
| lines = [''.join(row) for row in grid] | |
| return lines | |
| def get_state(self): | |
| """Get grid state for LLM context""" | |
| return { | |
| "char_x": self.char_x, | |
| "char_y": self.char_y, | |
| "mood": self.mood, | |
| "objects": [(x, y, c) for x, y, c, _ in self.objects], | |
| "trail_length": len(self.trail), | |
| } | |
| # Available tools for the LLM | |
| TOOLS = { | |
| "move": { | |
| "description": "Move the character in a direction", | |
| "params": {"dir": "up|down|left|right|up-left|up-right|down-left|down-right"}, | |
| }, | |
| "teleport": { | |
| "description": "Move character to specific position", | |
| "params": {"x": "0-19", "y": "0-3"}, | |
| }, | |
| "mood": { | |
| "description": "Change character mood/expression", | |
| "params": {"mood": "neutral|happy|sad|excited|angry|sleepy|love|coding"}, | |
| }, | |
| "say": { | |
| "description": "Display a message on the grid", | |
| "params": {"text": "message to display"}, | |
| }, | |
| "spawn": { | |
| "description": "Place an object on the grid", | |
| "params": {"x": "0-19", "y": "0-3", "char": "single character", "name": "object name"}, | |
| }, | |
| "clear": { | |
| "description": "Clear all objects from grid", | |
| "params": {}, | |
| }, | |
| "animate": { | |
| "description": "Play an animation", | |
| "params": {"type": "bounce|spin|wave|random_walk"}, | |
| }, | |
| } | |
| def get_tools_for_prompt(): | |
| """Get tool definitions for the LLM prompt""" | |
| lines = [] | |
| for name, tool in TOOLS.items(): | |
| params = ", ".join(f"{k}={v}" for k, v in tool["params"].items()) | |
| lines.append(f"- {name}({params}): {tool['description']}") | |
| return "\n".join(lines) | |