Impl drake
This commit is contained in:
		
							parent
							
								
									f467e9cbcb
								
							
						
					
					
						commit
						e7e7c81d29
					
				
							
								
								
									
										99
									
								
								nucon/drake.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								nucon/drake.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,99 @@
 | 
			
		||||
import os
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
from PIL import Image, ImageDraw, ImageFont
 | 
			
		||||
import textwrap
 | 
			
		||||
 | 
			
		||||
# Get the directory where the script is located
 | 
			
		||||
SCRIPT_DIR = Path(__file__).resolve().parent
 | 
			
		||||
 | 
			
		||||
def get_asset_path(filename):
 | 
			
		||||
    return str(SCRIPT_DIR / 'drake_assets' / filename)
 | 
			
		||||
 | 
			
		||||
def fit_text_to_box(draw, text, font, max_width, max_height, line_spacing=1.2):
 | 
			
		||||
    font_size = 1
 | 
			
		||||
    while True:
 | 
			
		||||
        font = ImageFont.truetype(font.path, font_size)
 | 
			
		||||
        lines = textwrap.wrap(text, width=20)
 | 
			
		||||
        line_height = font.getbbox("Ay")[3] - font.getbbox("Ay")[1]
 | 
			
		||||
        total_height = line_height * len(lines) * line_spacing
 | 
			
		||||
        max_line_width = max(font.getbbox(line)[2] - font.getbbox(line)[0] for line in lines)
 | 
			
		||||
        
 | 
			
		||||
        if max_line_width > max_width or total_height > max_height:
 | 
			
		||||
            font_size -= 1
 | 
			
		||||
            font = ImageFont.truetype(font.path, font_size)
 | 
			
		||||
            break
 | 
			
		||||
        font_size += 1
 | 
			
		||||
    return font, lines
 | 
			
		||||
 | 
			
		||||
def create_drake_meme(items):
 | 
			
		||||
    # Load images
 | 
			
		||||
    no_image = Image.open(get_asset_path('no.jpg'))
 | 
			
		||||
    yes_image = Image.open(get_asset_path('yes.jpg'))
 | 
			
		||||
    
 | 
			
		||||
    # Set up meme dimensions
 | 
			
		||||
    panel_width, panel_height = no_image.size
 | 
			
		||||
    meme_width = panel_width * 2
 | 
			
		||||
    meme_height = panel_height * len(items)
 | 
			
		||||
    
 | 
			
		||||
    # Create meme canvas
 | 
			
		||||
    meme = Image.new("RGB", (meme_width, meme_height), "white")
 | 
			
		||||
    
 | 
			
		||||
    # Set up font (use a proper meme font)
 | 
			
		||||
    font_path = get_asset_path('impact.ttf')
 | 
			
		||||
    try:
 | 
			
		||||
        base_font = ImageFont.truetype(font_path, 1)
 | 
			
		||||
    except OSError:
 | 
			
		||||
        # Fallback to default font if Impact is not available
 | 
			
		||||
        base_font = ImageFont.load_default()
 | 
			
		||||
    
 | 
			
		||||
    for i, (is_yes, text) in enumerate(items):
 | 
			
		||||
        # Paste the appropriate image
 | 
			
		||||
        y_offset = i * panel_height
 | 
			
		||||
        if is_yes:
 | 
			
		||||
            meme.paste(yes_image, (0, y_offset))
 | 
			
		||||
        else:
 | 
			
		||||
            meme.paste(no_image, (0, y_offset))
 | 
			
		||||
        
 | 
			
		||||
        # Create text panel
 | 
			
		||||
        text_panel = Image.new("RGB", (panel_width, panel_height), "white")
 | 
			
		||||
        draw = ImageDraw.Draw(text_panel)
 | 
			
		||||
        
 | 
			
		||||
        # Fit and draw text
 | 
			
		||||
        fitted_font, lines = fit_text_to_box(draw, text, base_font, panel_width - 20, panel_height - 20, line_spacing=1.2)
 | 
			
		||||
        
 | 
			
		||||
        line_height = fitted_font.getbbox("Ay")[3] - fitted_font.getbbox("Ay")[1]
 | 
			
		||||
        total_height = line_height * len(lines) * 1.2
 | 
			
		||||
        y_text = (panel_height - total_height) // 2
 | 
			
		||||
        
 | 
			
		||||
        for line in lines:
 | 
			
		||||
            bbox = fitted_font.getbbox(line)
 | 
			
		||||
            text_width = bbox[2] - bbox[0]
 | 
			
		||||
            x_text = (panel_width - text_width) // 2
 | 
			
		||||
            draw.text((x_text, y_text), line, font=fitted_font, fill="black")
 | 
			
		||||
            y_text += line_height * 1.2
 | 
			
		||||
        
 | 
			
		||||
        # Paste text panel onto meme
 | 
			
		||||
        meme.paste(text_panel, (panel_width, y_offset))
 | 
			
		||||
 | 
			
		||||
    return meme
 | 
			
		||||
 | 
			
		||||
default_items = [
 | 
			
		||||
    (False, "Play Nucleares manually"),
 | 
			
		||||
    (True, "Automate it with a script"),
 | 
			
		||||
    (False, "But the web interface is tedious to use"),
 | 
			
		||||
    (True, "Write an elegant libary to interface with the game and then use that to write the script"),
 | 
			
		||||
    (False, "But I would still need to write the control policy by hand"),
 | 
			
		||||
    (True, "Let's extend the libary such that it trains a policy via Reinforcement Learning"),
 | 
			
		||||
    (False, "But RL is takes a huge number of training samples"),
 | 
			
		||||
    (True, "Extend the libary to also include an efficient simulator"),
 | 
			
		||||
    (False, "But I don't know what the actual internal dynamics are"),
 | 
			
		||||
    (True, "Extend the libary once more to also include a neural network dynamics model"),
 | 
			
		||||
    (True, "And I'm gonna put a drake meme on the README"),
 | 
			
		||||
    (False, "Online meme generators only support a single yes/no pair"),
 | 
			
		||||
    (True, "Let's also add a drake meme generator to the libary"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    meme = create_drake_meme(default_items)
 | 
			
		||||
    meme.save("drake_meme.jpg")
 | 
			
		||||
    print("Meme saved as drake_meme.jpg")
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								nucon/drake_assets/impact.ttf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								nucon/drake_assets/impact.ttf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								nucon/drake_assets/no.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								nucon/drake_assets/no.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 44 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								nucon/drake_assets/yes.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								nucon/drake_assets/yes.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 49 KiB  | 
		Loading…
	
		Reference in New Issue
	
	Block a user