Buckets:
| import{s as LU,a as PU,n as KU,o as la}from"../chunks/scheduler.2b22cead.js";import{S as sa,i as Ta,e,s as t,c as a,h as Ja,a as M,d as T,b as n,f as B,g as i,j as U,k as d,q as S,l as I,m as J,n as y,t as p,o as w,p as j}from"../chunks/index.1a0e8013.js";import{C as ta,H as o,E as na}from"../chunks/MermaidChart.svelte_svelte_type_style_lang.a01de1eb.js";import{C as r}from"../chunks/CodeBlock.81c04d9c.js";function ea(sM){let b,sJ,KT,TJ,f,JJ,V,tJ,u,G,TM,ke,v,Re,BT,JM="<strong>What if RL environments were as easy to use as REST APIs?</strong>",Se,QT,tM="That’s OpenEnv. Type-safe. Isolated. Production-ready. 🎯",fe,kT,nM='<a href="https://colab.research.google.com/github/huggingface/OpenEnv/blob/main/examples/OpenEnv_Tutorial.ipynb" rel="nofollow"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a> <a href="https://github.com/huggingface/OpenEnv" rel="nofollow"><img src="https://img.shields.io/badge/GitHub-huggingface%2FOpenEnv-blue?logo=github" alt="GitHub"/></a> <a href="https://opensource.org/licenses/BSD-3-Clause" rel="nofollow"><img src="https://img.shields.io/badge/License-BSD%203--Clause-green.svg" alt="License"/></a> <a href="https://pytorch.org/" rel="nofollow"><img src="https://img.shields.io/badge/PyTorch-EE4C2C?logo=pytorch&logoColor=white" alt="PyTorch"/></a>',Ve,RT,eM="Author: Sanyam Bhutani",nJ,O,eJ,Z,MM="Let’s take a trip down memory lane:",MJ,F,UM="It’s 2016, RL is popular. You read some papers, it looks promising.",UJ,W,aM="But in real world: Cartpole is the best you can run on a gaming GPU.",aJ,$,iM="What do you do beyond Cartpole?",iJ,Y,yM="Fast-forward to 2025, GRPO is awesome and this time it’s not JUST in theory, it works well in practise and is really here!",yJ,z,pM="The problem still remains, how do you take these RL algorithms and take them beyond Cartpole?",pJ,x,wM="A huge part of RL is giving your algorithms environment access to learn.",wJ,H,jM="We are excited to introduce an Environment Spec for adding Open Environments for RL Training. This will allow you to focus on your experiments and allow everyone to bring their environments.",jJ,_,IM="Focus on experiments, use OpenEnvironments, and build agents that go beyond Cartpole on a single spec.",IJ,oJ,rJ,X,CJ,D,oM='<tr><td width="50%"><p><strong>🎯 Part 1-2: The Fundamentals</strong></p> <ul><li>⚡ RL in 60 seconds</li> <li>🤔 Why existing solutions fall short</li> <li>💡 The OpenEnv solution</li></ul></td> <td width="50%"><p><strong>🏗️ Part 3-5: The Architecture</strong></p> <ul><li>🔧 How OpenEnv works</li> <li>🔍 Exploring real code</li> <li>🎮 OpenSpiel integration example</li></ul></td></tr> <tr><td width="50%"><p><strong>🎮 Part 6-8: Hands-On Demo</strong></p> <ul><li>🔌 Use existing OpenSpiel environment</li> <li>🤖 Test 4 different policies</li> <li>👀 Watch learning happen live</li></ul></td> <td width="50%"><p><strong>🔧 Part 9-10: Going Further</strong></p> <ul><li>🎮 Switch to other OpenSpiel games</li> <li>✨ Build your own integration</li> <li>🌐 Deploy to production</li></ul></td></tr>',cJ,Q,rM="<p>This notebook is designed to run top-to-bottom in Google Colab with zero setup!</p> <p>⏱️ <strong>Time</strong>: ~5 minutes | 📊 <strong>Difficulty</strong>: Beginner-friendly | 🎯 <strong>Outcome</strong>: Production-ready RL knowledge</p>",EJ,uJ,NJ,q,hJ,L,mJ,P,CM='<li><a href="#part-1-rl-in-60-seconds">Part 1: RL in 60 Seconds ⏱️</a></li> <li><a href="#part-2-the-problem-with-traditional-rl">Part 2: The Problem with Traditional RL 😤</a></li> <li><a href="#part-3-setup">Part 3: Setup 🛠️</a></li>',dJ,K,gJ,ll,cM='<li><a href="#part-4-the-openenv-pattern">Part 4: The OpenEnv Pattern 🏗️</a></li> <li><a href="#part-5-example-integration---openspiel">Part 5: Example Integration - OpenSpiel 🎮</a></li>',AJ,sl,bJ,Tl,EM='<li><a href="#part-6-using-real-openspiel">Part 6: Interactive Demo 🎮</a></li> <li><a href="#part-7-four-policies">Part 7: Four Policies 🤖</a></li> <li><a href="#part-8-policy-competition">Part 8: Policy Competition! 🏆</a></li>',BJ,Jl,QJ,tl,uM='<li><a href="#part-9-switching-to-other-games">Part 9: Using Real OpenSpiel 🎮</a></li> <li><a href="#part-10-create-your-own-integration">Part 10: Create Your Own Integration 🛠️</a></li>',kJ,nl,RJ,el,NM='<li><a href="#summary-your-journey">Summary: Your Journey 🎓</a></li> <li><a href="#resources">Resources 📚</a></li>',SJ,fJ,VJ,Ml,GJ,Ul,hM="<strong>Reinforcement Learning is simpler than you think.</strong>",vJ,al,mM="It’s just a loop:",OJ,il,ZJ,yl,dM="That’s it. That’s RL.",FJ,pl,gM="Let’s see it in action:",WJ,wl,$J,jl,AM="<strong>Output:</strong>",YJ,Il,zJ,xJ,HJ,ol,_J,rl,XJ,Cl,bM="Good question! Gym is great for research, but production needs more…",DJ,cl,BM="<thead><tr><th>Challenge</th> <th>Traditional Approach</th> <th>OpenEnv Solution</th></tr></thead> <tbody><tr><td><strong>Type Safety</strong></td> <td>❌ <code>obs[0][3]</code> - what is this?</td> <td>✅ <code>obs.info_state</code> - IDE knows!</td></tr> <tr><td><strong>Isolation</strong></td> <td>❌ Same process (can crash your training)</td> <td>✅ Docker containers (fully isolated)</td></tr> <tr><td><strong>Deployment</strong></td> <td>❌ “Works on my machine” 🤷</td> <td>✅ Same container everywhere 🐳</td></tr> <tr><td><strong>Scaling</strong></td> <td>❌ Hard to distribute</td> <td>✅ Deploy to Kubernetes ☸️</td></tr> <tr><td><strong>Language</strong></td> <td>❌ Python only</td> <td>✅ Any language (HTTP API) 🌐</td></tr> <tr><td><strong>Debugging</strong></td> <td>❌ Cryptic numpy errors</td> <td>✅ Clear type errors 🐛</td></tr></tbody>",qJ,El,LJ,ul,QM="<strong>“RL environments should be like microservices”</strong>",PJ,Nl,kM="Think of it like this: You don’t run your database in the same process as your web server, right? Same principle!",KJ,hl,RM="<li>🔒 <strong>Isolated</strong>: Run in containers (security + stability)</li> <li>🌐 <strong>Standard</strong>: HTTP API, works everywhere</li> <li>📦 <strong>Versioned</strong>: Docker images (reproducibility!)</li> <li>🚀 <strong>Scalable</strong>: Deploy to cloud with one command</li> <li>🛡️ <strong>Type-safe</strong>: Catch bugs before they happen</li> <li>🔄 <strong>Portable</strong>: Works on Mac, Linux, Windows, Cloud</li>",lt,ml,st,dl,Tt,g,ST,SM="You never see HTTP details - just clean Python methods!",Ge,gl,ve,fT,fM="The magic? OpenEnv handles all the plumbing. You focus on RL! ✨",Jt,tt,nt,Al,et,bl,VM="<strong>Running in Colab?</strong> This cell will clone OpenEnv and install dependencies automatically.",Mt,Bl,GM="<strong>Running locally?</strong> Make sure you’re in the OpenEnv directory.",Ut,Ql,at,kl,vM="<strong>Output:</strong>",it,Rl,yt,pt,wt,Sl,jt,fl,It,Vl,ot,Gl,OM="Let’s explore the actual OpenEnv code to see how this works:",rt,vl,Ct,Ol,ZM="<strong>Output:</strong>",ct,Zl,Et,ut,Nt,Fl,ht,Wl,mt,$l,FM="<strong>OpenSpiel</strong> is a library from DeepMind with <strong>70+ game environments</strong> for RL research.",dt,Yl,gt,zl,WM="We’ve wrapped <strong>6 OpenSpiel games</strong> following the OpenEnv pattern:",At,xl,$M="<thead><tr><th><strong>🎯 Single-Player</strong></th> <th><strong>👥 Multi-Player</strong></th></tr></thead> <tbody><tr><td>1. <strong>Catch</strong> - Catch falling ball</td> <td>5. <strong>Tic-Tac-Toe</strong> - Classic 3×3</td></tr> <tr><td>2. <strong>Cliff Walking</strong> - Navigate grid</td> <td>6. <strong>Kuhn Poker</strong> - Imperfect info poker</td></tr> <tr><td>3. <strong>2048</strong> - Tile puzzle</td> <td></td></tr> <tr><td>4. <strong>Blackjack</strong> - Card game</td> <td></td></tr></tbody>",bt,Hl,YM="This shows how OpenEnv can wrap <strong>any</strong> existing RL library!",Bt,_l,Qt,Xl,zM="<strong>Output:</strong>",kt,Dl,Rt,ql,St,Ll,ft,Pl,xM="<strong>Output:</strong>",Vt,Kl,Gt,ls,vt,ss,HM="The client <strong>inherits from HTTPEnvClient</strong> and implements 3 methods:",Ot,Ts,_M="<li><code>_step_payload()</code> - Convert action → JSON</li> <li><code>_parse_result()</code> - Parse JSON → typed observation</li> <li><code>_parse_state()</code> - Parse JSON → state</li>",Zt,Js,XM="That’s it! The base class handles all HTTP communication.",Ft,Wt,$t,ts,Yt,C,ns,Oe,VT,DM="We’ll play <strong>Catch</strong> using OpenEnv’s <strong>OpenSpiel integration</strong> 🎯",Ze,GT,qM="This is a REAL environment running in production at companies!",Fe,vT,LM="<strong>Get ready for:</strong>",We,OT,PM="<li>🔌 Using existing environments (not building)</li> <li>🤖 Testing policies against real games</li> <li>📊 Live gameplay visualization</li> <li>🎯 Production-ready patterns</li>",zt,es,xt,Ms,Ht,Us,KM="<strong>Rules:</strong>",_t,as,lU="<li>10×5 grid</li> <li>Ball falls from random column</li> <li>Move paddle left/right to catch it</li>",Xt,is,sU="<strong>Actions:</strong>",Dt,ys,TU="<li><code>0</code> = Move LEFT ⬅️</li> <li><code>1</code> = STAY 🛑</li> <li><code>2</code> = Move RIGHT ➡️</li>",qt,ps,JU="<strong>Reward:</strong>",Lt,ws,tU="<li><code>+1</code> if caught 🎉</li> <li><code>0</code> if missed 😢</li>",Pt,k,nU=`<ul><li>Simple rules (easy to understand)</li> <li>Fast episodes (~5 steps)</li> <li>Clear success/failure</li> <li>Part of OpenSpiel’s 70+ games!</li></ul> <p><strong>💡 The Big Idea:</strong> | |
| Instead of building this from scratch, we’ll USE OpenEnv’s existing OpenSpiel integration. Same interface, but production-ready!</p>`,Kt,js,ln,Is,eU="<strong>Output:</strong>",sn,os,Tn,Jn,tn,rs,nn,Cs,MU="Let’s test 4 different AI strategies:",en,cs,UU="<thead><tr><th>Policy</th> <th>Strategy</th> <th>Expected Performance</th></tr></thead> <tbody><tr><td><strong>🎲 Random</strong></td> <td>Pick random action every step</td> <td>~20% (pure luck)</td></tr> <tr><td><strong>🛑 Always Stay</strong></td> <td>Never move, hope ball lands in center</td> <td>~20% (terrible!)</td></tr> <tr><td><strong>🧠 Smart</strong></td> <td>Move paddle toward ball</td> <td>100% (optimal!)</td></tr> <tr><td><strong>📈 Learning</strong></td> <td>Start random, learn smart strategy</td> <td>~85% (improves over time)</td></tr></tbody>",Mn,Es,aU="<strong>💡 These policies work with ANY OpenSpiel game!</strong>",Un,us,an,Ns,iU="<strong>Output:</strong>",yn,hs,pn,wn,jn,ms,In,ds,yU="Let’s run <strong>50 episodes</strong> for each policy against <strong>REAL OpenSpiel</strong> and see who wins!",on,gs,pU="This is production code - every action is an HTTP call to the OpenSpiel server!",rn,As,Cn,cn,En,bs,un,Bs,Nn,Qs,wU="In Parts 6-8, we <strong>USED</strong> the existing OpenSpiel Catch environment:",hn,ks,jU="<thead><tr><th>What We Did</th> <th>How It Works</th></tr></thead> <tbody><tr><td><strong>Imported</strong></td> <td>OpenSpielEnv client (pre-built)</td></tr> <tr><td><strong>Started</strong></td> <td>OpenSpiel server via uvicorn</td></tr> <tr><td><strong>Connected</strong></td> <td>HTTP client to server</td></tr> <tr><td><strong>Played</strong></td> <td>Real OpenSpiel Catch game</td></tr></tbody>",mn,Rs,IU="<strong>🎯 This is production code!</strong> Every action was an HTTP call to a real OpenSpiel environment.",dn,Ss,gn,fs,oU="The beauty of OpenEnv? <strong>Same code, different games!</strong>",An,Vs,bn,Gs,rU="<strong>🎮 All 6 Games:</strong>",Bn,vs,CU="<li>✅ <strong><code>catch</code></strong> - What we just used!</li> <li><strong><code>tic_tac_toe</code></strong> - Classic 3×3</li> <li><strong><code>kuhn_poker</code></strong> - Imperfect information poker</li> <li><strong><code>cliff_walking</code></strong> - Grid navigation</li> <li><strong><code>2048</code></strong> - Tile puzzle</li> <li><strong><code>blackjack</code></strong> - Card game</li>",Qn,Os,cU="<strong>All use the exact same OpenSpielEnv client!</strong>",kn,Zs,Rn,Fs,Sn,Ws,EU="<strong>💡 Key Insight</strong>: You don’t rebuild anything - you just USE different games with the same client!",fn,Vn,Gn,$s,vn,Ys,On,zs,uU="Want to wrap your own environment in OpenEnv? Here’s how:",Zn,xs,Fn,Hs,Wn,_s,$n,Xs,Yn,Ds,zn,qs,xn,Ls,Hn,Ps,_n,Ks,Xn,lT,Dn,sT,qn,TT,NU="OpenEnv includes 3 complete examples:",Ln,JT,hU="<li><p><strong><code>src/envs/echo_env/</code></strong></p> <ul><li>Simplest possible environment</li> <li>Great for testing and learning</li></ul></li> <li><p><strong><code>src/envs/openspiel_env/</code></strong></p> <ul><li>Wraps external library (OpenSpiel)</li> <li>Shows integration pattern</li> <li>6 games in one integration</li></ul></li> <li><p><strong><code>src/envs/coding_env/</code></strong></p> <ul><li>Python code execution environment</li> <li>Shows complex use case</li> <li>Security considerations</li></ul></li>",Pn,tT,mU="<strong>💡 Study these to understand the patterns!</strong>",Kn,le,se,nT,dU="(summary-your-journey)=",Te,eT,Je,MT,te,ZT,UT,c,aT,$e,FT,gU="✅ <strong>RL Fundamentals</strong>",Ye,WT,AU="<li>The observe-act-reward loop</li> <li>What makes good policies</li> <li>Exploration vs exploitation</li>",ze,$T,bU="✅ <strong>OpenEnv Architecture</strong>",xe,YT,BU="<li>Client-server separation</li> <li>Type-safe contracts</li> <li>HTTP communication layer</li>",He,zT,QU="✅ <strong>Production Patterns</strong>",_e,xT,kU="<li>Docker isolation</li> <li>API design</li> <li>Reproducible deployments</li>",Xe,E,iT,De,HT,RU="✅ <strong>Using Environments</strong>",qe,_T,SU="<li>Import OpenEnv clients</li> <li>Call reset/step/state</li> <li>Work with typed observations</li>",Le,XT,fU="✅ <strong>Building Environments</strong>",Pe,DT,VU="<li>Define type-safe models</li> <li>Implement Environment class</li> <li>Create HTTPEnvClient</li>",Ke,qT,GU="✅ <strong>Testing & Debugging</strong>",lM,LT,vU="<li>Compare policies</li> <li>Visualize episodes</li> <li>Measure performance</li>",ne,yT,ee,pT,OU="<thead><tr><th>Feature</th> <th>Traditional (Gym)</th> <th>OpenEnv</th> <th>Winner</th></tr></thead> <tbody><tr><td><strong>Type Safety</strong></td> <td>❌ Arrays, dicts</td> <td>✅ Dataclasses</td> <td>🏆 OpenEnv</td></tr> <tr><td><strong>Isolation</strong></td> <td>❌ Same process</td> <td>✅ Docker</td> <td>🏆 OpenEnv</td></tr> <tr><td><strong>Deployment</strong></td> <td>❌ Manual setup</td> <td>✅ K8s-ready</td> <td>🏆 OpenEnv</td></tr> <tr><td><strong>Language</strong></td> <td>❌ Python only</td> <td>✅ Any (HTTP)</td> <td>🏆 OpenEnv</td></tr> <tr><td><strong>Reproducibility</strong></td> <td>❌ “Works on my machine”</td> <td>✅ Same everywhere</td> <td>🏆 OpenEnv</td></tr> <tr><td><strong>Community</strong></td> <td>✅ Large ecosystem</td> <td>🟡 Growing</td> <td>🤝 Both!</td></tr></tbody>",Me,R,ZU="<p>OpenEnv brings <strong>production engineering</strong> to RL:</p> <ul><li>Same environments work locally and in production</li> <li>Type safety catches bugs early</li> <li>Docker isolation prevents conflicts</li> <li>HTTP API works with any language</li></ul> <p><strong>It’s RL for 2024 and beyond.</strong></p>",Ue,ae,ie,wT,ye,jT,pe,IT,FU='<li><strong>🏠 OpenEnv GitHub</strong>: <a href="https://github.com/huggingface/OpenEnv" rel="nofollow">https://github.com/huggingface/OpenEnv</a></li> <li><strong>🎮 OpenSpiel</strong>: <a href="https://github.com/google-deepmind/open_spiel" rel="nofollow">https://github.com/google-deepmind/open_spiel</a></li> <li><strong>⚡ FastAPI Docs</strong>: <a href="https://fastapi.tiangolo.com/" rel="nofollow">https://fastapi.tiangolo.com/</a></li> <li><strong>🐳 Docker Guide</strong>: <a href="https://docs.docker.com/get-started/" rel="nofollow">https://docs.docker.com/get-started/</a></li> <li><strong>🔥 PyTorch</strong>: <a href="https://pytorch.org/" rel="nofollow">https://pytorch.org/</a></li>',we,oT,je,rT,WU='<li><strong>Environment Creation Guide</strong>: <code>src/envs/README.md</code></li> <li><strong>OpenSpiel Integration</strong>: <code>src/envs/openspiel_env/README.md</code></li> <li><strong>Example Scripts</strong>: <code>examples/</code></li> <li><strong>RFC 001</strong>: <a href="https://github.com/huggingface/OpenEnv/pull/26" rel="nofollow">Baseline API Specs</a></li>',Ie,CT,oe,cT,$U="<strong>Openly governed by a technical committee including:</strong>",re,ET,YU="<li>🤗 Hugging Face</li> <li>⚡ Unsloth</li> <li>🌟 Reflection</li> <li>🔥 Meta PyTorch</li> <li>☁️ Modal</li> <li>🧠 Prime Intellect</li>",Ce,uT,zU="<strong>Supported by amazing organizations and contributors.</strong>",ce,NT,xU="<li>🚀 And many more!</li>",Ee,hT,HU="Technical direction, RFCs, and release planning are coordinated in public through the OpenEnv repository.",ue,mT,_U="<strong>License</strong>: BSD 3-Clause (very permissive!)",Ne,dT,XU="<strong>Contributions</strong>: Always welcome! Check out the issues tab.",he,me,de,gT,ge,AT,DU="<li>⭐ <strong>Star the repo</strong> to show support and stay updated</li> <li>🔄 <strong>Try modifying</strong> the Catch game (make it harder? bigger grid?)</li> <li>🎮 <strong>Explore</strong> other OpenSpiel games</li> <li>🛠️ <strong>Build</strong> your own environment integration</li> <li>💬 <strong>Share</strong> what you build with the community!</li>",Ae,bT,be,lJ,Be;return f=new ta({props:{containerStyle:"float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"}}),V=new o({props:{title:"OpenEnv: Production RL Made Simple",local:"openenv-production-rl-made-simple",headingTag:"h1"}}),v=new o({props:{title:"From “Hello World” to RL Training in 5 Minutes ✨",local:"from-hello-world-to-rl-training-in-5-minutes-",headingTag:"h2"}}),O=new o({props:{title:"Why OpenEnv?",local:"why-openenv",headingTag:"h2"}}),X=new o({props:{title:"📋 What You’ll Learn",local:"-what-youll-learn",headingTag:"h2"}}),q=new o({props:{title:"📑 Table of Contents",local:"-table-of-contents",headingTag:"h2"}}),L=new o({props:{title:"Foundation",local:"foundation",headingTag:"h3"}}),K=new o({props:{title:"Architecture",local:"architecture",headingTag:"h3"}}),sl=new o({props:{title:"Hands-On Demo",local:"hands-on-demo",headingTag:"h3"}}),Jl=new o({props:{title:"Advanced",local:"advanced",headingTag:"h3"}}),nl=new o({props:{title:"Wrap Up",local:"wrap-up",headingTag:"h3"}}),Ml=new o({props:{title:"Part 1: RL in 60 Seconds ⏱️",local:"part-1-rl-in-60-seconds-",headingTag:"h2"}}),il=new r({props:{code:"d2hpbGUlMjBub3QlMjBkb25lJTNBJTBBJTIwJTIwJTIwJTIwb2JzZXJ2YXRpb24lMjAlM0QlMjBlbnZpcm9ubWVudC5vYnNlcnZlKCklMEElMjAlMjAlMjAlMjBhY3Rpb24lMjAlM0QlMjBwb2xpY3kuY2hvb3NlKG9ic2VydmF0aW9uKSUwQSUyMCUyMCUyMCUyMHJld2FyZCUyMCUzRCUyMGVudmlyb25tZW50LnN0ZXAoYWN0aW9uKSUwQSUyMCUyMCUyMCUyMHBvbGljeS5sZWFybihyZXdhcmQp",highlighted:`<span class="hljs-keyword">while</span> <span class="hljs-keyword">not</span> done: | |
| observation = environment.observe() | |
| action = policy.choose(observation) | |
| reward = environment.step(action) | |
| policy.learn(reward)`,lang:"python",wrap:!1}}),wl=new r({props:{code:"aW1wb3J0JTIwcmFuZG9tJTBBJTBBcHJpbnQoJTIyJUYwJTlGJThFJUIyJTIwJTIyJTIwJTJCJTIwJTIyJTNEJTIyKjU4JTIwJTJCJTIwJTIyJTIwJUYwJTlGJThFJUIyJTIyKSUwQXByaW50KCUyMiUyMCUyMCUyME51bWJlciUyMEd1ZXNzaW5nJTIwR2FtZSUyMC0lMjBUaGUlMjBTaW1wbGVzdCUyMFJMJTIwRXhhbXBsZSUyMiklMEFwcmludCglMjIlRjAlOUYlOEUlQjIlMjAlMjIlMjAlMkIlMjAlMjIlM0QlMjIqNTglMjAlMkIlMjAlMjIlMjAlRjAlOUYlOEUlQjIlMjIpJTBBJTBBJTIzJTIwRW52aXJvbm1lbnQlMjBzZXR1cCUwQXRhcmdldCUyMCUzRCUyMHJhbmRvbS5yYW5kaW50KDElMkMlMjAxMCklMEFndWVzc2VzX2xlZnQlMjAlM0QlMjAzJTBBJTBBcHJpbnQoZiUyMiU1Q24lRjAlOUYlOEUlQUYlMjBJJ20lMjB0aGlua2luZyUyMG9mJTIwYSUyMG51bWJlciUyMGJldHdlZW4lMjAxJTIwYW5kJTIwMTAuLi4lMjIpJTBBcHJpbnQoZiUyMiVGMCU5RiU5MiVBRCUyMFlvdSUyMGhhdmUlMjAlN0JndWVzc2VzX2xlZnQlN0QlMjBndWVzc2VzLiUyMExldCdzJTIwc2VlJTIwaG93JTIwcmFuZG9tJTIwZ3Vlc3NpbmclMjB3b3JrcyElNUNuJTIyKSUwQSUwQSUyMyUyMFRoZSUyMFJMJTIwTG9vcCUyMC0lMjBQdXJlJTIwcmFuZG9tJTIwcG9saWN5JTIwKG5vJTIwbGVhcm5pbmchKSUwQXdoaWxlJTIwZ3Vlc3Nlc19sZWZ0JTIwJTNFJTIwMCUzQSUwQSUyMCUyMCUyMCUyMCUyMyUyMFBvbGljeSUzQSUyMFJhbmRvbSUyMGd1ZXNzaW5nJTIwKG5vJTIwbGVhcm5pbmclMjB5ZXQhKSUwQSUyMCUyMCUyMCUyMGd1ZXNzJTIwJTNEJTIwcmFuZG9tLnJhbmRpbnQoMSUyQyUyMDEwKSUwQSUyMCUyMCUyMCUyMGd1ZXNzZXNfbGVmdCUyMC0lM0QlMjAxJTBBJTBBJTIwJTIwJTIwJTIwcHJpbnQoZiUyMiVGMCU5RiU5MiVBRCUyMEd1ZXNzJTIwJTIzJTdCMy1ndWVzc2VzX2xlZnQlN0QlM0ElMjAlN0JndWVzcyU3RCUyMiUyQyUyMGVuZCUzRCUyMiUyMCVFMiU4NiU5MiUyMCUyMiklMEElMEElMjAlMjAlMjAlMjAlMjMlMjBSZXdhcmQlMjBzaWduYWwlMjAoYnV0JTIwd2UncmUlMjBub3QlMjB1c2luZyUyMGl0ISklMEElMjAlMjAlMjAlMjBpZiUyMGd1ZXNzJTIwJTNEJTNEJTIwdGFyZ2V0JTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcHJpbnQoJTIyJUYwJTlGJThFJTg5JTIwQ29ycmVjdCElMjAlMkIxMCUyMHBvaW50cyUyMiklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBicmVhayUwQSUyMCUyMCUyMCUyMGVsaWYlMjBhYnMoZ3Vlc3MlMjAtJTIwdGFyZ2V0KSUyMCUzQyUzRCUyMDIlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBwcmludCglMjIlRjAlOUYlOTQlQTUlMjBXYXJtISUyMChjbG9zZSklMjIpJTBBJTIwJTIwJTIwJTIwZWxzZSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHByaW50KCUyMiVFMiU5RCU4NCVFRiVCOCU4RiUyMCUyMENvbGQhJTIwKGZhciklMjIpJTBBZWxzZSUzQSUwQSUyMCUyMCUyMCUyMHByaW50KGYlMjIlNUNuJUYwJTlGJTkyJTk0JTIwT3V0JTIwb2YlMjBndWVzc2VzLiUyMFRoZSUyMG51bWJlciUyMHdhcyUyMCU3QnRhcmdldCU3RC4lMjIpJTBBJTBBcHJpbnQoJTIyJTVDbiUyMiUyMCUyQiUyMCUyMiUzRCUyMio2MiklMEFwcmludCglMjIlRjAlOUYlOTIlQTElMjBUaGlzJTIwaXMlMjBSTCUzQSUyME9ic2VydmUlMjAlRTIlODYlOTIlMjBBY3QlMjAlRTIlODYlOTIlMjBSZXdhcmQlMjAlRTIlODYlOTIlMjBSZXBlYXQlMjIpJTBBcHJpbnQoJTIyJTIwJTIwJTIwQnV0JTIwdGhpcyUyMHBvbGljeSUyMGlzJTIwdGVycmlibGUhJTIwSXQlMjBkb2Vzbid0JTIwbGVhcm4lMjBmcm9tJTIwcmV3YXJkcy4lMjIpJTBBcHJpbnQoJTIyJTNEJTIyKjYyJTIwJTJCJTIwJTIyJTVDbiUyMik=",highlighted:`<span class="hljs-keyword">import</span> random | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"🎲 "</span> + <span class="hljs-string">"="</span>*<span class="hljs-number">58</span> + <span class="hljs-string">" 🎲"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" Number Guessing Game - The Simplest RL Example"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"🎲 "</span> + <span class="hljs-string">"="</span>*<span class="hljs-number">58</span> + <span class="hljs-string">" 🎲"</span>) | |
| <span class="hljs-comment"># Environment setup</span> | |
| target = random.randint(<span class="hljs-number">1</span>, <span class="hljs-number">10</span>) | |
| guesses_left = <span class="hljs-number">3</span> | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f"\\n🎯 I'm thinking of a number between 1 and 10..."</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f"💭 You have <span class="hljs-subst">{guesses_left}</span> guesses. Let's see how random guessing works!\\n"</span>) | |
| <span class="hljs-comment"># The RL Loop - Pure random policy (no learning!)</span> | |
| <span class="hljs-keyword">while</span> guesses_left > <span class="hljs-number">0</span>: | |
| <span class="hljs-comment"># Policy: Random guessing (no learning yet!)</span> | |
| guess = random.randint(<span class="hljs-number">1</span>, <span class="hljs-number">10</span>) | |
| guesses_left -= <span class="hljs-number">1</span> | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f"💭 Guess #<span class="hljs-subst">{<span class="hljs-number">3</span>-guesses_left}</span>: <span class="hljs-subst">{guess}</span>"</span>, end=<span class="hljs-string">" → "</span>) | |
| <span class="hljs-comment"># Reward signal (but we're not using it!)</span> | |
| <span class="hljs-keyword">if</span> guess == target: | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"🎉 Correct! +10 points"</span>) | |
| <span class="hljs-keyword">break</span> | |
| <span class="hljs-keyword">elif</span> <span class="hljs-built_in">abs</span>(guess - target) <= <span class="hljs-number">2</span>: | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"🔥 Warm! (close)"</span>) | |
| <span class="hljs-keyword">else</span>: | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"❄️ Cold! (far)"</span>) | |
| <span class="hljs-keyword">else</span>: | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f"\\n💔 Out of guesses. The number was <span class="hljs-subst">{target}</span>."</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n"</span> + <span class="hljs-string">"="</span>*<span class="hljs-number">62</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"💡 This is RL: Observe → Act → Reward → Repeat"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" But this policy is terrible! It doesn't learn from rewards."</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"="</span>*<span class="hljs-number">62</span> + <span class="hljs-string">"\\n"</span>)`,lang:"python",wrap:!1}}),Il=new r({props:{code:"JUYwJTlGJThFJUIyJTIwJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTIwJUYwJTlGJThFJUIyJTBBJTIwJTIwJTIwTnVtYmVyJTIwR3Vlc3NpbmclMjBHYW1lJTIwLSUyMFRoZSUyMFNpbXBsZXN0JTIwUkwlMjBFeGFtcGxlJTBBJUYwJTlGJThFJUIyJTIwJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTIwJUYwJTlGJThFJUIyJTBBJTBBJUYwJTlGJThFJUFGJTIwSSdtJTIwdGhpbmtpbmclMjBvZiUyMGElMjBudW1iZXIlMjBiZXR3ZWVuJTIwMSUyMGFuZCUyMDEwLi4uJTBBJUYwJTlGJTkyJUFEJTIwWW91JTIwaGF2ZSUyMDMlMjBndWVzc2VzLiUyMExldCdzJTIwc2VlJTIwaG93JTIwcmFuZG9tJTIwZ3Vlc3NpbmclMjB3b3JrcyElMEElMEElRjAlOUYlOTIlQUQlMjBHdWVzcyUyMCUyMzElM0ElMjAyJTIwJUUyJTg2JTkyJTIwJUUyJTlEJTg0JUVGJUI4JThGJTIwJTIwQ29sZCElMjAoZmFyKSUwQSVGMCU5RiU5MiVBRCUyMEd1ZXNzJTIwJTIzMiUzQSUyMDEwJTIwJUUyJTg2JTkyJTIwJUYwJTlGJThFJTg5JTIwQ29ycmVjdCElMjAlMkIxMCUyMHBvaW50cyUwQSUwQSUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUwQSVGMCU5RiU5MiVBMSUyMFRoaXMlMjBpcyUyMFJMJTNBJTIwT2JzZXJ2ZSUyMCVFMiU4NiU5MiUyMEFjdCUyMCVFMiU4NiU5MiUyMFJld2FyZCUyMCVFMiU4NiU5MiUyMFJlcGVhdCUwQSUyMCUyMCUyMEJ1dCUyMHRoaXMlMjBwb2xpY3klMjBpcyUyMHRlcnJpYmxlISUyMEl0JTIwZG9lc24ndCUyMGxlYXJuJTIwZnJvbSUyMHJld2FyZHMuJTBBJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNE",highlighted:`🎲 ========================================================== 🎲 | |
| <span class="hljs-code"> Number Guessing Game - The Simplest RL Example</span> | |
| 🎲 ========================================================== 🎲 | |
| 🎯 I'm thinking of a number between 1 and 10... | |
| 💭 You have 3 guesses. Let's see how random guessing works! | |
| 💭 Guess #1: 2 → ❄️ Cold! (far) | |
| 💭 Guess #2: 10 → 🎉 Correct! +10 points | |
| ============================================================== | |
| 💡 This is RL: Observe → Act → Reward → Repeat | |
| But this policy is terrible! It doesn't learn from rewards. | |
| ==============================================================`,lang:"",wrap:!1}}),ol=new o({props:{title:"Part 2: The Problem with Traditional RL 😤",local:"part-2-the-problem-with-traditional-rl-",headingTag:"h2"}}),rl=new o({props:{title:"🤔 Why Can’t We Just Use OpenAI Gym?",local:"-why-cant-we-just-use-openai-gym",headingTag:"h3"}}),El=new o({props:{title:"💡 The OpenEnv Philosophy",local:"-the-openenv-philosophy",headingTag:"h3"}}),ml=new o({props:{title:"The Architecture",local:"the-architecture",headingTag:"h3"}}),dl=new r({props:{code:"JUUyJTk0JThDJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTkwJTBBJUUyJTk0JTgyJTIwJTIwWU9VUiUyMFRSQUlOSU5HJTIwQ09ERSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCVFMiU5NCU4MiUwQSVFMiU5NCU4MiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCVFMiU5NCU4MiUwQSVFMiU5NCU4MiUyMCUyMGVudiUyMCUzRCUyME9wZW5TcGllbEVudiguLi4pJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJUUyJTg2JTkwJTIwSW1wb3J0JTIwdGhlJTIwY2xpZW50JTIwJTIwJTIwJTIwJTIwJTIwJUUyJTk0JTgyJTBBJUUyJTk0JTgyJTIwJTIwcmVzdWx0JTIwJTNEJTIwZW52LnJlc2V0KCklMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlRTIlODYlOTAlMjBUeXBlLXNhZmUhJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJUUyJTk0JTgyJTBBJUUyJTk0JTgyJTIwJTIwcmVzdWx0JTIwJTNEJTIwZW52LnN0ZXAoYWN0aW9uKSUyMCUyMCUyMCUyMCUyMCUyMCVFMiU4NiU5MCUyMFR5cGUtc2FmZSElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlRTIlOTQlODIlMEElRTIlOTQlODIlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlRTIlOTQlODIlMEElRTIlOTQlOTQlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlQUMlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlOTglMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlRTIlOTQlODIlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlRTIlOTQlODIlMjAlMjBIVFRQJTJGSlNPTiUyMChMYW5ndWFnZS1BZ25vc3RpYyklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlRTIlOTQlODIlMjAlMjBQT1NUJTIwJTJGcmVzZXQlMkMlMjBQT1NUJTIwJTJGc3RlcCUyQyUyMEdFVCUyMCUyRnN0YXRlJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJUUyJTk0JTgyJTBBJUUyJTk0JThDJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk2JUJDJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTkwJTBBJUUyJTk0JTgyJTIwJTIwRE9DS0VSJTIwQ09OVEFJTkVSJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJUUyJTk0JTgyJTBBJUUyJTk0JTgyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJUUyJTk0JTgyJTBBJUUyJTk0JTgyJTIwJTIwJUUyJTk0JThDJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTkwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJUUyJTk0JTgyJTBBJUUyJTk0JTgyJTIwJTIwJUUyJTk0JTgyJTIwJTIwRmFzdEFQSSUyMFNlcnZlciUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCVFMiU5NCU4MiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCVFMiU5NCU4MiUwQSVFMiU5NCU4MiUyMCUyMCVFMiU5NCU4MiUyMCUyMCVFMiU5NCU5NCVFMiU5NCU4MCUyMEVudmlyb25tZW50JTIwKHJlc2V0JTJDJTIwc3RlcCUyQyUyMHN0YXRlKSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCVFMiU5NCU4MiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCVFMiU5NCU4MiUwQSVFMiU5NCU4MiUyMCUyMCVFMiU5NCU4MiUyMCUyMCUyMCUyMCUyMCVFMiU5NCU5NCVFMiU5NCU4MCUyMFlvdXIlMjBHYW1lJTJGU2ltdWxhdGlvbiUyMExvZ2ljJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJUUyJTk0JTgyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJUUyJTk0JTgyJTBBJUUyJTk0JTgyJTIwJTIwJUUyJTk0JTk0JUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTk4JTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJUUyJTk0JTgyJTBBJUUyJTk0JTgyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJUUyJTk0JTgyJTBBJUUyJTk0JTgyJTIwJTIwSXNvbGF0ZWQlMjAlRTIlODAlQTIlMjBSZXByb2R1Y2libGUlMjAlRTIlODAlQTIlMjBTZWN1cmUlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlRTIlOTQlODIlMEElRTIlOTQlOTQlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlOTg=",highlighted:`┌────────────────────────────────────────────────────────────┐ | |
| │ YOUR TRAINING CODE │ | |
| │ │ | |
| │ env = OpenSpielEnv(...) ← Import the client │ | |
| │ result = env.reset() ← Type-safe! │ | |
| │ result = env.step(action) ← Type-safe! │ | |
| │ │ | |
| └─────────────────┬──────────────────────────────────────────┘ | |
| │ | |
| │ HTTP/JSON (Language-Agnostic) | |
| │ POST /reset, POST /step, GET /<span class="hljs-keyword">state</span> | |
| │ | |
| ┌─────────────────▼──────────────────────────────────────────┐ | |
| │ DOCKER CONTAINER │ | |
| │ │ | |
| │ ┌──────────────────────────────────────────────┐ │ | |
| │ │ FastAPI Server │ │ | |
| │ │ └─ Environment (reset, step, <span class="hljs-keyword">state</span>) │ │ | |
| │ │ └─ Your Game/Simulation Logic │ │ | |
| │ └──────────────────────────────────────────────┘ │ | |
| │ │ | |
| │ Isolated • Reproducible • Secure │ | |
| └────────────────────────────────────────────────────────────┘`,lang:"",wrap:!1}}),gl=new r({props:{code:"ZW52LnJlc2V0KCklMjAlMjAlMjAlMjAlMjMlMjBVbmRlciUyMHRoZSUyMGhvb2QlM0ElMjBIVFRQJTIwUE9TVCUyMHRvJTIwJTJGcmVzZXQlMEFlbnYuc3RlcCguLi4pJTIwJTIwJTIzJTIwVW5kZXIlMjB0aGUlMjBob29kJTNBJTIwSFRUUCUyMFBPU1QlMjB0byUyMCUyRnN0ZXAlMEFlbnYuc3RhdGUoKSUyMCUyMCUyMCUyMCUyMyUyMFVuZGVyJTIwdGhlJTIwaG9vZCUzQSUyMEhUVFAlMjBHRVQlMjB0byUyMCUyRnN0YXRl",highlighted:`env.reset() <span class="hljs-comment"># Under the hood: HTTP POST to /reset</span> | |
| env.step(...) <span class="hljs-comment"># Under the hood: HTTP POST to /step</span> | |
| env.state() <span class="hljs-comment"># Under the hood: HTTP GET to /state</span>`,lang:"python",wrap:!1}}),Al=new o({props:{title:"Part 3: Setup 🛠️",local:"part-3-setup-",headingTag:"h2"}}),Ql=new r({props:{code:"JTIzJTIwRGV0ZWN0JTIwZW52aXJvbm1lbnQlMEF0cnklM0ElMEElMjAlMjAlMjAlMjBpbXBvcnQlMjBnb29nbGUuY29sYWIlMEElMjAlMjAlMjAlMjBJTl9DT0xBQiUyMCUzRCUyMFRydWUlMEElMjAlMjAlMjAlMjBwcmludCglMjIlRjAlOUYlOEMlOTAlMjBSdW5uaW5nJTIwaW4lMjBHb29nbGUlMjBDb2xhYiUyMC0lMjBQZXJmZWN0ISUyMiklMEFleGNlcHQlMjBJbXBvcnRFcnJvciUzQSUwQSUyMCUyMCUyMCUyMElOX0NPTEFCJTIwJTNEJTIwRmFsc2UlMEElMjAlMjAlMjAlMjBwcmludCglMjIlRjAlOUYlOTIlQkIlMjBSdW5uaW5nJTIwbG9jYWxseSUyMC0lMjBOaWNlISUyMiklMEElMEFpZiUyMElOX0NPTEFCJTNBJTBBJTIwJTIwJTIwJTIwcHJpbnQoJTIyJTVDbiVGMCU5RiU5MyVBNiUyMENsb25pbmclMjBPcGVuRW52JTIwcmVwb3NpdG9yeS4uLiUyMiklMEElMjAlMjAlMjAlMjAhZ2l0JTIwY2xvbmUlMjBodHRwcyUzQSUyRiUyRmdpdGh1Yi5jb20lMkZodWdnaW5nZmFjZSUyRk9wZW5FbnYuZ2l0JTIwJTNFJTIwJTJGZGV2JTJGbnVsbCUyMDIlM0UlMjYxJTBBJTIwJTIwJTIwJTIwJTI1Y2QlMjBPcGVuRW52JTBBJTBBJTIwJTIwJTIwJTIwcHJpbnQoJTIyJUYwJTlGJTkzJTlBJTIwSW5zdGFsbGluZyUyMGRlcGVuZGVuY2llcyUyMCh0aGlzJTIwdGFrZXMlMjB+MTAlMjBzZWNvbmRzKS4uLiUyMiklMEElMjAlMjAlMjAlMjAhcGlwJTIwaW5zdGFsbCUyMC1xJTIwZmFzdGFwaSUyMHV2aWNvcm4lMjByZXF1ZXN0cyUwQSUwQSUyMCUyMCUyMCUyMGltcG9ydCUyMHN5cyUwQSUyMCUyMCUyMCUyMHN5cy5wYXRoLmluc2VydCgwJTJDJTIwJy4lMkZzcmMnKSUwQSUyMCUyMCUyMCUyMHByaW50KCUyMiU1Q24lRTIlOUMlODUlMjBTZXR1cCUyMGNvbXBsZXRlISUyMEV2ZXJ5dGhpbmclMjBpcyUyMHJlYWR5JTIwdG8lMjBnbyElMjAlRjAlOUYlOEUlODklMjIpJTBBZWxzZSUzQSUwQSUyMCUyMCUyMCUyMGltcG9ydCUyMHN5cyUwQSUyMCUyMCUyMCUyMGZyb20lMjBwYXRobGliJTIwaW1wb3J0JTIwUGF0aCUwQSUyMCUyMCUyMCUyMHN5cy5wYXRoLmluc2VydCgwJTJDJTIwc3RyKFBhdGguY3dkKCkucGFyZW50JTIwJTJGJTIwJ3NyYycpKSUwQSUyMCUyMCUyMCUyMHByaW50KCUyMiVFMiU5QyU4NSUyMFVzaW5nJTIwbG9jYWwlMjBPcGVuRW52JTIwaW5zdGFsbGF0aW9uJTIyKSUwQSUwQXByaW50KCUyMiU1Q24lRjAlOUYlOUElODAlMjBSZWFkeSUyMHRvJTIwZXhwbG9yZSUyME9wZW5FbnYlMjBhbmQlMjBidWlsZCUyMGFtYXppbmclMjB0aGluZ3MhJTIyKSUwQXByaW50KCUyMiVGMCU5RiU5MiVBMSUyMFRpcCUzQSUyMFJ1biUyMGNlbGxzJTIwdG9wLXRvLWJvdHRvbSUyMGZvciUyMHRoZSUyMGJlc3QlMjBleHBlcmllbmNlLiU1Q24lMjIp",highlighted:`<span class="hljs-comment"># Detect environment</span> | |
| <span class="hljs-keyword">try</span>: | |
| <span class="hljs-keyword">import</span> google.colab | |
| IN_COLAB = <span class="hljs-literal">True</span> | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"🌐 Running in Google Colab - Perfect!"</span>) | |
| <span class="hljs-keyword">except</span> ImportError: | |
| IN_COLAB = <span class="hljs-literal">False</span> | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"💻 Running locally - Nice!"</span>) | |
| <span class="hljs-keyword">if</span> IN_COLAB: | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n📦 Cloning OpenEnv repository..."</span>) | |
| !git clone https://github.com/huggingface/OpenEnv.git > /dev/null <span class="hljs-number">2</span>>&<span class="hljs-number">1</span> | |
| %cd OpenEnv | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"📚 Installing dependencies (this takes ~10 seconds)..."</span>) | |
| !pip install -q fastapi uvicorn requests | |
| <span class="hljs-keyword">import</span> sys | |
| sys.path.insert(<span class="hljs-number">0</span>, <span class="hljs-string">'./src'</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n✅ Setup complete! Everything is ready to go! 🎉"</span>) | |
| <span class="hljs-keyword">else</span>: | |
| <span class="hljs-keyword">import</span> sys | |
| <span class="hljs-keyword">from</span> pathlib <span class="hljs-keyword">import</span> Path | |
| sys.path.insert(<span class="hljs-number">0</span>, <span class="hljs-built_in">str</span>(Path.cwd().parent / <span class="hljs-string">'src'</span>)) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"✅ Using local OpenEnv installation"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n🚀 Ready to explore OpenEnv and build amazing things!"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"💡 Tip: Run cells top-to-bottom for the best experience.\\n"</span>)`,lang:"ipython3",wrap:!1}}),Rl=new r({props:{code:"JUYwJTlGJTkyJUJCJTIwUnVubmluZyUyMGxvY2FsbHklMjAtJTIwTmljZSElMEElRTIlOUMlODUlMjBVc2luZyUyMGxvY2FsJTIwT3BlbkVudiUyMGluc3RhbGxhdGlvbiUwQSUwQSVGMCU5RiU5QSU4MCUyMFJlYWR5JTIwdG8lMjBleHBsb3JlJTIwT3BlbkVudiUyMGFuZCUyMGJ1aWxkJTIwYW1hemluZyUyMHRoaW5ncyElMEElRjAlOUYlOTIlQTElMjBUaXAlM0ElMjBSdW4lMjBjZWxscyUyMHRvcC10by1ib3R0b20lMjBmb3IlMjB0aGUlMjBiZXN0JTIwZXhwZXJpZW5jZS4=",highlighted:`💻 Running locally - Nice! | |
| ✅ Using local OpenEnv <span class="hljs-keyword">installation | |
| </span> | |
| 🚀 Ready to explore OpenEnv <span class="hljs-keyword">and </span><span class="hljs-keyword">build </span>amazing things! | |
| 💡 Tip: Run cells top-to-<span class="hljs-keyword">bottom </span>for the <span class="hljs-keyword">best </span>experience.`,lang:"",wrap:!1}}),Sl=new o({props:{title:"Part 4: The OpenEnv Pattern 🏗️",local:"part-4-the-openenv-pattern-",headingTag:"h2"}}),fl=new o({props:{title:"Every OpenEnv Environment Has 3 Components:",local:"every-openenv-environment-has-3-components",headingTag:"h3"}}),Vl=new r({props:{code:"c3JjJTJGZW52cyUyRnlvdXJfZW52JTJGJTBBJUUyJTk0JTlDJUUyJTk0JTgwJUUyJTk0JTgwJTIwJUYwJTlGJTkzJTlEJTIwbW9kZWxzLnB5JTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJUUyJTg2JTkwJTIwVHlwZS1zYWZlJTIwY29udHJhY3RzJTBBJUUyJTk0JTgyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKEFjdGlvbiUyQyUyME9ic2VydmF0aW9uJTJDJTIwU3RhdGUpJTBBJUUyJTk0JTgyJTBBJUUyJTk0JTlDJUUyJTk0JTgwJUUyJTk0JTgwJTIwJUYwJTlGJTkzJUIxJTIwY2xpZW50LnB5JTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJUUyJTg2JTkwJTIwV2hhdCUyMFlPVSUyMGltcG9ydCUwQSVFMiU5NCU4MiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMChIVFRQRW52Q2xpZW50JTIwaW1wbGVtZW50YXRpb24pJTBBJUUyJTk0JTgyJTBBJUUyJTk0JTk0JUUyJTk0JTgwJUUyJTk0JTgwJTIwJUYwJTlGJTk2JUE1JUVGJUI4JThGJTIwJTIwc2VydmVyJTJGJTBBJTIwJTIwJTIwJTIwJUUyJTk0JTlDJUUyJTk0JTgwJUUyJTk0JTgwJTIwZW52aXJvbm1lbnQucHklMjAlMjAlMjAlMjAlRTIlODYlOTAlMjBHYW1lJTJGc2ltdWxhdGlvbiUyMGxvZ2ljJTBBJTIwJTIwJTIwJTIwJUUyJTk0JTlDJUUyJTk0JTgwJUUyJTk0JTgwJTIwYXBwLnB5JTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJUUyJTg2JTkwJTIwRmFzdEFQSSUyMHNlcnZlciUwQSUyMCUyMCUyMCUyMCVFMiU5NCU5NCVFMiU5NCU4MCVFMiU5NCU4MCUyMERvY2tlcmZpbGUlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlRTIlODYlOTAlMjBDb250YWluZXIlMjBkZWZpbml0aW9u",highlighted:`<span class="hljs-attribute">src</span>/envs/your_env/ | |
| ├── 📝 models<span class="hljs-selector-class">.py</span> ← Type-safe contracts | |
| │ (Action, Observation, State) | |
| │ | |
| ├── 📱 client<span class="hljs-selector-class">.py</span> ← What YOU import | |
| │ (HTTPEnvClient implementation) | |
| │ | |
| └── 🖥️ server/ | |
| ├── environment<span class="hljs-selector-class">.py</span> ← Game/simulation logic | |
| ├── app<span class="hljs-selector-class">.py</span> ← FastAPI server | |
| └── Dockerfile ← Container definition`,lang:"",wrap:!1}}),vl=new r({props:{code:"JTIzJTIwSW1wb3J0JTIwT3BlbkVudidzJTIwY29yZSUyMGFic3RyYWN0aW9ucyUwQWZyb20lMjBjb3JlLmVudl9zZXJ2ZXIlMjBpbXBvcnQlMjBFbnZpcm9ubWVudCUyQyUyMEFjdGlvbiUyQyUyME9ic2VydmF0aW9uJTJDJTIwU3RhdGUlMEFmcm9tJTIwY29yZS5odHRwX2Vudl9jbGllbnQlMjBpbXBvcnQlMjBIVFRQRW52Q2xpZW50JTBBJTBBcHJpbnQoJTIyJTNEJTIyKjcwKSUwQXByaW50KCUyMiUyMCUyMCUyMCVGMCU5RiVBNyVBOSUyME9QRU5FTlYlMjBDT1JFJTIwQUJTVFJBQ1RJT05TJTIyKSUwQXByaW50KCUyMiUzRCUyMio3MCklMEElMEFwcmludCglMjIlMjIlMjIlMEElRjAlOUYlOTYlQTUlRUYlQjglOEYlMjAlMjBTRVJWRVIlMjBTSURFJTIwKHJ1bnMlMjBpbiUyMERvY2tlciklM0ElMEElMEElMjAlMjAlMjAlMjBjbGFzcyUyMEVudmlyb25tZW50KEFCQyklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAnJydCYXNlJTIwY2xhc3MlMjBmb3IlMjBhbGwlMjBlbnZpcm9ubWVudCUyMGltcGxlbWVudGF0aW9ucycnJyUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU0MGFic3RyYWN0bWV0aG9kJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZGVmJTIwcmVzZXQoc2VsZiklMjAtJTNFJTIwT2JzZXJ2YXRpb24lM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAnJydTdGFydCUyMG5ldyUyMGVwaXNvZGUnJyclMEElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNDBhYnN0cmFjdG1ldGhvZCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGRlZiUyMHN0ZXAoc2VsZiUyQyUyMGFjdGlvbiUzQSUyMEFjdGlvbiklMjAtJTNFJTIwT2JzZXJ2YXRpb24lM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAnJydFeGVjdXRlJTIwYWN0aW9uJTJDJTIwcmV0dXJuJTIwb2JzZXJ2YXRpb24nJyclMEElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNDBwcm9wZXJ0eSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGRlZiUyMHN0YXRlKHNlbGYpJTIwLSUzRSUyMFN0YXRlJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJycnR2V0JTIwZXBpc29kZSUyMG1ldGFkYXRhJycnJTBBJTBBJUYwJTlGJTkzJUIxJTIwQ0xJRU5UJTIwU0lERSUyMCh5b3VyJTIwdHJhaW5pbmclMjBjb2RlKSUzQSUwQSUwQSUyMCUyMCUyMCUyMGNsYXNzJTIwSFRUUEVudkNsaWVudChBQkMpJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJycnQmFzZSUyMGNsYXNzJTIwZm9yJTIwSFRUUCUyMGNsaWVudHMnJyclMEElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBkZWYlMjByZXNldChzZWxmKSUyMC0lM0UlMjBTdGVwUmVzdWx0JTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIzJTIwSFRUUCUyMFBPU1QlMjAlMkZyZXNldCUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGRlZiUyMHN0ZXAoc2VsZiUyQyUyMGFjdGlvbiklMjAtJTNFJTIwU3RlcFJlc3VsdCUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMyUyMEhUVFAlMjBQT1NUJTIwJTJGc3RlcCUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGRlZiUyMHN0YXRlKHNlbGYpJTIwLSUzRSUyMFN0YXRlJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIzJTIwSFRUUCUyMEdFVCUyMCUyRnN0YXRlJTBBJTIyJTIyJTIyKSUwQSUwQXByaW50KCUyMiUzRCUyMio3MCklMEFwcmludCglMjIlNUNuJUUyJTlDJUE4JTIwU2FtZSUyMGludGVyZmFjZSUyMG9uJTIwYm90aCUyMHNpZGVzJTIwLSUyMGNvbW11bmljYXRpb24lMjB2aWElMjBIVFRQISUyMiklMEFwcmludCglMjIlRjAlOUYlOEUlQUYlMjBZb3UlMjBmb2N1cyUyMG9uJTIwUkwlMkMlMjBPcGVuRW52JTIwaGFuZGxlcyUyMHRoZSUyMGluZnJhc3RydWN0dXJlLiU1Q24lMjIp",highlighted:`<span class="hljs-comment"># Import OpenEnv's core abstractions</span> | |
| <span class="hljs-keyword">from</span> core.env_server <span class="hljs-keyword">import</span> Environment, Action, Observation, State | |
| <span class="hljs-keyword">from</span> core.http_env_client <span class="hljs-keyword">import</span> HTTPEnvClient | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"="</span>*<span class="hljs-number">70</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" 🧩 OPENENV CORE ABSTRACTIONS"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"="</span>*<span class="hljs-number">70</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">""" | |
| 🖥️ SERVER SIDE (runs in Docker): | |
| class Environment(ABC): | |
| '''Base class for all environment implementations''' | |
| @abstractmethod | |
| def reset(self) -> Observation: | |
| '''Start new episode''' | |
| @abstractmethod | |
| def step(self, action: Action) -> Observation: | |
| '''Execute action, return observation''' | |
| @property | |
| def state(self) -> State: | |
| '''Get episode metadata''' | |
| 📱 CLIENT SIDE (your training code): | |
| class HTTPEnvClient(ABC): | |
| '''Base class for HTTP clients''' | |
| def reset(self) -> StepResult: | |
| # HTTP POST /reset | |
| def step(self, action) -> StepResult: | |
| # HTTP POST /step | |
| def state(self) -> State: | |
| # HTTP GET /state | |
| """</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"="</span>*<span class="hljs-number">70</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n✨ Same interface on both sides - communication via HTTP!"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"🎯 You focus on RL, OpenEnv handles the infrastructure.\\n"</span>)`,lang:"python",wrap:!1}}),Zl=new r({props:{code:"JTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTBBJTIwJTIwJTIwJUYwJTlGJUE3JUE5JTIwT1BFTkVOViUyMENPUkUlMjBBQlNUUkFDVElPTlMlMEElM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlMEElMEElRjAlOUYlOTYlQTUlRUYlQjglOEYlMjAlMjBTRVJWRVIlMjBTSURFJTIwKHJ1bnMlMjBpbiUyMERvY2tlciklM0ElMEElMEElMjAlMjAlMjAlMjBjbGFzcyUyMEVudmlyb25tZW50KEFCQyklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAnJydCYXNlJTIwY2xhc3MlMjBmb3IlMjBhbGwlMjBlbnZpcm9ubWVudCUyMGltcGxlbWVudGF0aW9ucycnJyUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU0MGFic3RyYWN0bWV0aG9kJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZGVmJTIwcmVzZXQoc2VsZiklMjAtJTNFJTIwT2JzZXJ2YXRpb24lM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAnJydTdGFydCUyMG5ldyUyMGVwaXNvZGUnJyclMEElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNDBhYnN0cmFjdG1ldGhvZCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGRlZiUyMHN0ZXAoc2VsZiUyQyUyMGFjdGlvbiUzQSUyMEFjdGlvbiklMjAtJTNFJTIwT2JzZXJ2YXRpb24lM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAnJydFeGVjdXRlJTIwYWN0aW9uJTJDJTIwcmV0dXJuJTIwb2JzZXJ2YXRpb24nJyclMEElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNDBwcm9wZXJ0eSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGRlZiUyMHN0YXRlKHNlbGYpJTIwLSUzRSUyMFN0YXRlJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJycnR2V0JTIwZXBpc29kZSUyMG1ldGFkYXRhJycnJTBBJTBBJUYwJTlGJTkzJUIxJTIwQ0xJRU5UJTIwU0lERSUyMCh5b3VyJTIwdHJhaW5pbmclMjBjb2RlKSUzQSUwQSUwQSUyMCUyMCUyMCUyMGNsYXNzJTIwSFRUUEVudkNsaWVudChBQkMpJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJycnQmFzZSUyMGNsYXNzJTIwZm9yJTIwSFRUUCUyMGNsaWVudHMnJyclMEElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBkZWYlMjByZXNldChzZWxmKSUyMC0lM0UlMjBTdGVwUmVzdWx0JTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIzJTIwSFRUUCUyMFBPU1QlMjAlMkZyZXNldCUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGRlZiUyMHN0ZXAoc2VsZiUyQyUyMGFjdGlvbiklMjAtJTNFJTIwU3RlcFJlc3VsdCUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMyUyMEhUVFAlMjBQT1NUJTIwJTJGc3RlcCUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGRlZiUyMHN0YXRlKHNlbGYpJTIwLSUzRSUyMFN0YXRlJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIzJTIwSFRUUCUyMEdFVCUyMCUyRnN0YXRlJTBBJTBBJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTBBJTBBJUUyJTlDJUE4JTIwU2FtZSUyMGludGVyZmFjZSUyMG9uJTIwYm90aCUyMHNpZGVzJTIwLSUyMGNvbW11bmljYXRpb24lMjB2aWElMjBIVFRQISUwQSVGMCU5RiU4RSVBRiUyMFlvdSUyMGZvY3VzJTIwb24lMjBSTCUyQyUyME9wZW5FbnYlMjBoYW5kbGVzJTIwdGhlJTIwaW5mcmFzdHJ1Y3R1cmUu",highlighted:`====================================================================== | |
| 🧩 OPENENV CORE ABSTRACTIONS | |
| ====================================================================== | |
| 🖥️ SERVER SIDE (runs <span class="hljs-keyword">in</span> Docker): | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">Environment</span>(<span class="hljs-title class_ inherited__">ABC</span>): | |
| <span class="hljs-string">'''Base class for all environment implementations'''</span> | |
| <span class="hljs-meta"> @abstractmethod</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">reset</span>(<span class="hljs-params">self</span>) -> Observation: | |
| <span class="hljs-string">'''Start new episode'''</span> | |
| <span class="hljs-meta"> @abstractmethod</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">step</span>(<span class="hljs-params">self, action: Action</span>) -> Observation: | |
| <span class="hljs-string">'''Execute action, return observation'''</span> | |
| <span class="hljs-meta"> @property</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">state</span>(<span class="hljs-params">self</span>) -> State: | |
| <span class="hljs-string">'''Get episode metadata'''</span> | |
| 📱 CLIENT SIDE (your training code): | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">HTTPEnvClient</span>(<span class="hljs-title class_ inherited__">ABC</span>): | |
| <span class="hljs-string">'''Base class for HTTP clients'''</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">reset</span>(<span class="hljs-params">self</span>) -> StepResult: | |
| <span class="hljs-comment"># HTTP POST /reset</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">step</span>(<span class="hljs-params">self, action</span>) -> StepResult: | |
| <span class="hljs-comment"># HTTP POST /step</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">state</span>(<span class="hljs-params">self</span>) -> State: | |
| <span class="hljs-comment"># HTTP GET /state</span> | |
| ====================================================================== | |
| ✨ Same interface on both sides - communication via HTTP! | |
| 🎯 You focus on RL, OpenEnv handles the infrastructure.`,lang:"",wrap:!1}}),Fl=new o({props:{title:"Part 5: Example Integration - OpenSpiel 🎮",local:"part-5-example-integration---openspiel-",headingTag:"h2"}}),Wl=new o({props:{title:"What is OpenSpiel?",local:"what-is-openspiel",headingTag:"h3"}}),Yl=new o({props:{title:"OpenEnv’s Integration",local:"openenvs-integration",headingTag:"h3"}}),_l=new r({props:{code:"ZnJvbSUyMGVudnMub3BlbnNwaWVsX2Vudi5jbGllbnQlMjBpbXBvcnQlMjBPcGVuU3BpZWxFbnYlMEElMEFwcmludCglMjIlM0QlMjIqNzApJTBBcHJpbnQoJTIyJTIwJTIwJTIwJUYwJTlGJTk0JThDJTIwSE9XJTIwT1BFTkVOViUyMFdSQVBTJTIwT1BFTlNQSUVMJTIyKSUwQXByaW50KCUyMiUzRCUyMio3MCklMEElMEFwcmludCglMjIlMjIlMjIlMEFjbGFzcyUyME9wZW5TcGllbEVudihIVFRQRW52Q2xpZW50JTVCT3BlblNwaWVsQWN0aW9uJTJDJTIwT3BlblNwaWVsT2JzZXJ2YXRpb24lNUQpJTNBJTBBJTBBJTIwJTIwJTIwJTIwZGVmJTIwX3N0ZXBfcGF5bG9hZChzZWxmJTJDJTIwYWN0aW9uJTNBJTIwT3BlblNwaWVsQWN0aW9uKSUyMC0lM0UlMjBkaWN0JTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJycnQ29udmVydCUyMHR5cGVkJTIwYWN0aW9uJTIwdG8lMjBKU09OJTIwZm9yJTIwSFRUUCcnJyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMmFjdGlvbl9pZCUyMiUzQSUyMGFjdGlvbi5hY3Rpb25faWQlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJnYW1lX25hbWUlMjIlM0ElMjBhY3Rpb24uZ2FtZV9uYW1lJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdEJTBBJTBBJTIwJTIwJTIwJTIwZGVmJTIwX3BhcnNlX3Jlc3VsdChzZWxmJTJDJTIwcGF5bG9hZCUzQSUyMGRpY3QpJTIwLSUzRSUyMFN0ZXBSZXN1bHQlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAnJydQYXJzZSUyMEhUVFAlMjBKU09OJTIwcmVzcG9uc2UlMjBpbnRvJTIwdHlwZWQlMjBvYnNlcnZhdGlvbicnJyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMFN0ZXBSZXN1bHQoJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwb2JzZXJ2YXRpb24lM0RPcGVuU3BpZWxPYnNlcnZhdGlvbiguLi4pJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV3YXJkJTNEcGF5bG9hZCU1QidyZXdhcmQnJTVEJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZG9uZSUzRHBheWxvYWQlNUInZG9uZSclNUQlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjApJTBBJTBBJTIyJTIyJTIyKSUwQSUwQXByaW50KCUyMiVFMiU5NCU4MCUyMiUyMColMjA3MCklMEFwcmludCglMjIlNUNuJUUyJTlDJUE4JTIwVXNhZ2UlMjAod29ya3MlMjBmb3IlMjBBTEwlMjBPcGVuRW52JTIwZW52aXJvbm1lbnRzKSUzQSUyMiklMEFwcmludCglMjIlMjIlMjIlMEElMjAlMjBlbnYlMjAlM0QlMjBPcGVuU3BpZWxFbnYoYmFzZV91cmwlM0QlMjJodHRwJTNBJTJGJTJGbG9jYWxob3N0JTNBODAwMCUyMiklMEElMEElMjAlMjByZXN1bHQlMjAlM0QlMjBlbnYucmVzZXQoKSUwQSUyMCUyMCUyMyUyMFJldHVybnMlMjBTdGVwUmVzdWx0JTVCT3BlblNwaWVsT2JzZXJ2YXRpb24lNUQlMjAtJTIwVHlwZSUyMHNhZmUhJTBBJTBBJTIwJTIwcmVzdWx0JTIwJTNEJTIwZW52LnN0ZXAoT3BlblNwaWVsQWN0aW9uKGFjdGlvbl9pZCUzRDIlMkMlMjBnYW1lX25hbWUlM0QlMjJjYXRjaCUyMikpJTBBJTIwJTIwJTIzJTIwVHlwZSUyMGNoZWNrZXIlMjBrbm93cyUyMHRoaXMlMjBpcyUyMHZhbGlkISUwQSUwQSUyMCUyMHN0YXRlJTIwJTNEJTIwZW52LnN0YXRlKCklMEElMjAlMjAlMjMlMjBSZXR1cm5zJTIwT3BlblNwaWVsU3RhdGUlMEElMjIlMjIlMjIpJTBBJTBBcHJpbnQoJTIyJUUyJTk0JTgwJTIyJTIwKiUyMDcwKSUwQXByaW50KCUyMiU1Q24lRjAlOUYlOEUlQUYlMjBUaGlzJTIwcGF0dGVybiUyMHdvcmtzJTIwZm9yJTIwQU5ZJTIwZW52aXJvbm1lbnQlMjB5b3UlMjB3YW50JTIwdG8lMjB3cmFwISU1Q24lMjIp",highlighted:`<span class="hljs-keyword">from</span> envs.openspiel_env.client <span class="hljs-keyword">import</span> OpenSpielEnv | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"="</span>*<span class="hljs-number">70</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" 🔌 HOW OPENENV WRAPS OPENSPIEL"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"="</span>*<span class="hljs-number">70</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">""" | |
| class OpenSpielEnv(HTTPEnvClient[OpenSpielAction, OpenSpielObservation]): | |
| def _step_payload(self, action: OpenSpielAction) -> dict: | |
| '''Convert typed action to JSON for HTTP''' | |
| return { | |
| "action_id": action.action_id, | |
| "game_name": action.game_name, | |
| } | |
| def _parse_result(self, payload: dict) -> StepResult: | |
| '''Parse HTTP JSON response into typed observation''' | |
| return StepResult( | |
| observation=OpenSpielObservation(...), | |
| reward=payload['reward'], | |
| done=payload['done'] | |
| ) | |
| """</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"─"</span> * <span class="hljs-number">70</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n✨ Usage (works for ALL OpenEnv environments):"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">""" | |
| env = OpenSpielEnv(base_url="http://localhost:8000") | |
| result = env.reset() | |
| # Returns StepResult[OpenSpielObservation] - Type safe! | |
| result = env.step(OpenSpielAction(action_id=2, game_name="catch")) | |
| # Type checker knows this is valid! | |
| state = env.state() | |
| # Returns OpenSpielState | |
| """</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"─"</span> * <span class="hljs-number">70</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n🎯 This pattern works for ANY environment you want to wrap!\\n"</span>)`,lang:"python",wrap:!1}}),Dl=new r({props:{code:"JTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTBBJTIwJTIwJTIwJUYwJTlGJTk0JThDJTIwSE9XJTIwT1BFTkVOViUyMFdSQVBTJTIwT1BFTlNQSUVMJTBBJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTBBJTBBY2xhc3MlMjBPcGVuU3BpZWxFbnYoSFRUUEVudkNsaWVudCU1Qk9wZW5TcGllbEFjdGlvbiUyQyUyME9wZW5TcGllbE9ic2VydmF0aW9uJTVEKSUzQSUwQSUwQSUyMCUyMCUyMCUyMGRlZiUyMF9zdGVwX3BheWxvYWQoc2VsZiUyQyUyMGFjdGlvbiUzQSUyME9wZW5TcGllbEFjdGlvbiklMjAtJTNFJTIwZGljdCUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCcnJ0NvbnZlcnQlMjB0eXBlZCUyMGFjdGlvbiUyMHRvJTIwSlNPTiUyMGZvciUyMEhUVFAnJyclMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjAlN0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJhY3Rpb25faWQlMjIlM0ElMjBhY3Rpb24uYWN0aW9uX2lkJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIyZ2FtZV9uYW1lJTIyJTNBJTIwYWN0aW9uLmdhbWVfbmFtZSUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCUwQSUwQSUyMCUyMCUyMCUyMGRlZiUyMF9wYXJzZV9yZXN1bHQoc2VsZiUyQyUyMHBheWxvYWQlM0ElMjBkaWN0KSUyMC0lM0UlMjBTdGVwUmVzdWx0JTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJycnUGFyc2UlMjBIVFRQJTIwSlNPTiUyMHJlc3BvbnNlJTIwaW50byUyMHR5cGVkJTIwb2JzZXJ2YXRpb24nJyclMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjBTdGVwUmVzdWx0KCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG9ic2VydmF0aW9uJTNET3BlblNwaWVsT2JzZXJ2YXRpb24oLi4uKSUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJld2FyZCUzRHBheWxvYWQlNUIncmV3YXJkJyU1RCUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGRvbmUlM0RwYXlsb2FkJTVCJ2RvbmUnJTVEJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKSUwQSUwQSUwQSVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCUwQSUwQSVFMiU5QyVBOCUyMFVzYWdlJTIwKHdvcmtzJTIwZm9yJTIwQUxMJTIwT3BlbkVudiUyMGVudmlyb25tZW50cyklM0ElMEElMEElMjAlMjBlbnYlMjAlM0QlMjBPcGVuU3BpZWxFbnYoYmFzZV91cmwlM0QlMjJodHRwJTNBJTJGJTJGbG9jYWxob3N0JTNBODAwMCUyMiklMEElMEElMjAlMjByZXN1bHQlMjAlM0QlMjBlbnYucmVzZXQoKSUwQSUyMCUyMCUyMyUyMFJldHVybnMlMjBTdGVwUmVzdWx0JTVCT3BlblNwaWVsT2JzZXJ2YXRpb24lNUQlMjAtJTIwVHlwZSUyMHNhZmUhJTBBJTBBJTIwJTIwcmVzdWx0JTIwJTNEJTIwZW52LnN0ZXAoT3BlblNwaWVsQWN0aW9uKGFjdGlvbl9pZCUzRDIlMkMlMjBnYW1lX25hbWUlM0QlMjJjYXRjaCUyMikpJTBBJTIwJTIwJTIzJTIwVHlwZSUyMGNoZWNrZXIlMjBrbm93cyUyMHRoaXMlMjBpcyUyMHZhbGlkISUwQSUwQSUyMCUyMHN0YXRlJTIwJTNEJTIwZW52LnN0YXRlKCklMEElMjAlMjAlMjMlMjBSZXR1cm5zJTIwT3BlblNwaWVsU3RhdGUlMEElMEElRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlRTIlOTQlODAlMEElMEElRjAlOUYlOEUlQUYlMjBUaGlzJTIwcGF0dGVybiUyMHdvcmtzJTIwZm9yJTIwQU5ZJTIwZW52aXJvbm1lbnQlMjB5b3UlMjB3YW50JTIwdG8lMjB3cmFwIQ==",highlighted:`====================================================================== | |
| 🔌 HOW OPENENV WRAPS OPENSPIEL | |
| ====================================================================== | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">OpenSpielEnv</span>(HTTPEnvClient[OpenSpielAction, OpenSpielObservation]): | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">_step_payload</span>(<span class="hljs-params">self, action: OpenSpielAction</span>) -> <span class="hljs-built_in">dict</span>: | |
| <span class="hljs-string">'''Convert typed action to JSON for HTTP'''</span> | |
| <span class="hljs-keyword">return</span> { | |
| <span class="hljs-string">"action_id"</span>: action.action_id, | |
| <span class="hljs-string">"game_name"</span>: action.game_name, | |
| } | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">_parse_result</span>(<span class="hljs-params">self, payload: <span class="hljs-built_in">dict</span></span>) -> StepResult: | |
| <span class="hljs-string">'''Parse HTTP JSON response into typed observation'''</span> | |
| <span class="hljs-keyword">return</span> StepResult( | |
| observation=OpenSpielObservation(...), | |
| reward=payload[<span class="hljs-string">'reward'</span>], | |
| done=payload[<span class="hljs-string">'done'</span>] | |
| ) | |
| ────────────────────────────────────────────────────────────────────── | |
| ✨ Usage (works <span class="hljs-keyword">for</span> ALL OpenEnv environments): | |
| env = OpenSpielEnv(base_url=<span class="hljs-string">"http://localhost:8000"</span>) | |
| result = env.reset() | |
| <span class="hljs-comment"># Returns StepResult[OpenSpielObservation] - Type safe!</span> | |
| result = env.step(OpenSpielAction(action_id=<span class="hljs-number">2</span>, game_name=<span class="hljs-string">"catch"</span>)) | |
| <span class="hljs-comment"># Type checker knows this is valid!</span> | |
| state = env.state() | |
| <span class="hljs-comment"># Returns OpenSpielState</span> | |
| ────────────────────────────────────────────────────────────────────── | |
| 🎯 This pattern works <span class="hljs-keyword">for</span> ANY environment you want to wrap!`,lang:"",wrap:!1}}),ql=new o({props:{title:"Type-Safe Models",local:"type-safe-models",headingTag:"h3"}}),Ll=new r({props:{code:"JTIzJTIwSW1wb3J0JTIwT3BlblNwaWVsJTIwaW50ZWdyYXRpb24lMjBtb2RlbHMlMEFmcm9tJTIwZW52cy5vcGVuc3BpZWxfZW52Lm1vZGVscyUyMGltcG9ydCUyMCglMEElMjAlMjAlMjAlMjBPcGVuU3BpZWxBY3Rpb24lMkMlMEElMjAlMjAlMjAlMjBPcGVuU3BpZWxPYnNlcnZhdGlvbiUyQyUwQSUyMCUyMCUyMCUyME9wZW5TcGllbFN0YXRlJTBBKSUwQWZyb20lMjBkYXRhY2xhc3NlcyUyMGltcG9ydCUyMGZpZWxkcyUwQSUwQXByaW50KCUyMiUzRCUyMio3MCklMEFwcmludCglMjIlMjAlMjAlMjAlRjAlOUYlOEUlQUUlMjBPUEVOU1BJRUwlMjBJTlRFR1JBVElPTiUyMC0lMjBUWVBFLVNBRkUlMjBNT0RFTFMlMjIpJTBBcHJpbnQoJTIyJTNEJTIyKjcwKSUwQSUwQXByaW50KCUyMiU1Q24lRjAlOUYlOTMlQTQlMjBPcGVuU3BpZWxBY3Rpb24lMjAod2hhdCUyMHlvdSUyMHNlbmQpJTNBJTIyKSUwQXByaW50KCUyMiUyMCUyMCUyMCUyMiUyMCUyQiUyMCUyMiVFMiU5NCU4MCUyMiUyMColMjA2NCklMEFmb3IlMjBmaWVsZCUyMGluJTIwZmllbGRzKE9wZW5TcGllbEFjdGlvbiklM0ElMEElMjAlMjAlMjAlMjBwcmludChmJTIyJTIwJTIwJTIwJUUyJTgwJUEyJTIwJTdCZmllbGQubmFtZSUzQTIwcyU3RCUyMCUzQSUyMCU3QmZpZWxkLnR5cGUlN0QlMjIpJTBBJTBBcHJpbnQoJTIyJTVDbiVGMCU5RiU5MyVBNSUyME9wZW5TcGllbE9ic2VydmF0aW9uJTIwKHdoYXQlMjB5b3UlMjByZWNlaXZlKSUzQSUyMiklMEFwcmludCglMjIlMjAlMjAlMjAlMjIlMjAlMkIlMjAlMjIlRTIlOTQlODAlMjIlMjAqJTIwNjQpJTBBZm9yJTIwZmllbGQlMjBpbiUyMGZpZWxkcyhPcGVuU3BpZWxPYnNlcnZhdGlvbiklM0ElMEElMjAlMjAlMjAlMjBwcmludChmJTIyJTIwJTIwJTIwJUUyJTgwJUEyJTIwJTdCZmllbGQubmFtZSUzQTIwcyU3RCUyMCUzQSUyMCU3QmZpZWxkLnR5cGUlN0QlMjIpJTBBJTBBcHJpbnQoJTIyJTVDbiVGMCU5RiU5MyU4QSUyME9wZW5TcGllbFN0YXRlJTIwKGVwaXNvZGUlMjBtZXRhZGF0YSklM0ElMjIpJTBBcHJpbnQoJTIyJTIwJTIwJTIwJTIyJTIwJTJCJTIwJTIyJUUyJTk0JTgwJTIyJTIwKiUyMDY0KSUwQWZvciUyMGZpZWxkJTIwaW4lMjBmaWVsZHMoT3BlblNwaWVsU3RhdGUpJTNBJTBBJTIwJTIwJTIwJTIwcHJpbnQoZiUyMiUyMCUyMCUyMCVFMiU4MCVBMiUyMCU3QmZpZWxkLm5hbWUlM0EyMHMlN0QlMjAlM0ElMjAlN0JmaWVsZC50eXBlJTdEJTIyKSUwQSUwQXByaW50KCUyMiU1Q24lMjIlMjAlMkIlMjAlMjIlM0QlMjIqNzApJTBBcHJpbnQoJTIyJTVDbiVGMCU5RiU5MiVBMSUyMFR5cGUlMjBzYWZldHklMjBtZWFucyUzQSUyMiklMEFwcmludCglMjIlMjAlMjAlMjAlRTIlOUMlODUlMjBZb3VyJTIwSURFJTIwYXV0b2NvbXBsZXRlcyUyMHRoZXNlJTIwZmllbGRzJTIyKSUwQXByaW50KCUyMiUyMCUyMCUyMCVFMiU5QyU4NSUyMFR5cG9zJTIwYXJlJTIwY2F1Z2h0JTIwYmVmb3JlJTIwcnVubmluZyUyMiklMEFwcmludCglMjIlMjAlMjAlMjAlRTIlOUMlODUlMjBSZWZhY3RvcmluZyUyMGlzJTIwc2FmZSUyMiklMEFwcmludCglMjIlMjAlMjAlMjAlRTIlOUMlODUlMjBTZWxmLWRvY3VtZW50aW5nJTIwY29kZSU1Q24lMjIp",highlighted:`<span class="hljs-comment"># Import OpenSpiel integration models</span> | |
| <span class="hljs-keyword">from</span> envs.openspiel_env.models <span class="hljs-keyword">import</span> ( | |
| OpenSpielAction, | |
| OpenSpielObservation, | |
| OpenSpielState | |
| ) | |
| <span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> fields | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"="</span>*<span class="hljs-number">70</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" 🎮 OPENSPIEL INTEGRATION - TYPE-SAFE MODELS"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"="</span>*<span class="hljs-number">70</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n📤 OpenSpielAction (what you send):"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" "</span> + <span class="hljs-string">"─"</span> * <span class="hljs-number">64</span>) | |
| <span class="hljs-keyword">for</span> field <span class="hljs-keyword">in</span> fields(OpenSpielAction): | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f" • <span class="hljs-subst">{field.name:20s}</span> : <span class="hljs-subst">{field.<span class="hljs-built_in">type</span>}</span>"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n📥 OpenSpielObservation (what you receive):"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" "</span> + <span class="hljs-string">"─"</span> * <span class="hljs-number">64</span>) | |
| <span class="hljs-keyword">for</span> field <span class="hljs-keyword">in</span> fields(OpenSpielObservation): | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f" • <span class="hljs-subst">{field.name:20s}</span> : <span class="hljs-subst">{field.<span class="hljs-built_in">type</span>}</span>"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n📊 OpenSpielState (episode metadata):"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" "</span> + <span class="hljs-string">"─"</span> * <span class="hljs-number">64</span>) | |
| <span class="hljs-keyword">for</span> field <span class="hljs-keyword">in</span> fields(OpenSpielState): | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f" • <span class="hljs-subst">{field.name:20s}</span> : <span class="hljs-subst">{field.<span class="hljs-built_in">type</span>}</span>"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n"</span> + <span class="hljs-string">"="</span>*<span class="hljs-number">70</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n💡 Type safety means:"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" ✅ Your IDE autocompletes these fields"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" ✅ Typos are caught before running"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" ✅ Refactoring is safe"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" ✅ Self-documenting code\\n"</span>)`,lang:"python",wrap:!1}}),Kl=new r({props:{code:"JTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTBBJTIwJTIwJTIwJUYwJTlGJThFJUFFJTIwT1BFTlNQSUVMJTIwSU5URUdSQVRJT04lMjAtJTIwVFlQRS1TQUZFJTIwTU9ERUxTJTBBJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTBBJTBBJUYwJTlGJTkzJUE0JTIwT3BlblNwaWVsQWN0aW9uJTIwKHdoYXQlMjB5b3UlMjBzZW5kKSUzQSUwQSUyMCUyMCUyMCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCVFMiU5NCU4MCUwQSUyMCUyMCUyMCVFMiU4MCVBMiUyMG1ldGFkYXRhJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNBJTIwdHlwaW5nLkRpY3QlNUJzdHIlMkMlMjB0eXBpbmcuQW55JTVEJTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwYWN0aW9uX2lkJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNBJTIwaW50JTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwZ2FtZV9uYW1lJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNBJTIwc3RyJTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwZ2FtZV9wYXJhbXMlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlM0ElMjBEaWN0JTVCc3RyJTJDJTIwQW55JTVEJTBBJTBBJUYwJTlGJTkzJUE1JTIwT3BlblNwaWVsT2JzZXJ2YXRpb24lMjAod2hhdCUyMHlvdSUyMHJlY2VpdmUpJTNBJTBBJTIwJTIwJTIwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwZG9uZSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUzQSUyMCUzQ2NsYXNzJTIwJ2Jvb2wnJTNFJTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwcmV3YXJkJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNBJTIwdHlwaW5nLlVuaW9uJTVCYm9vbCUyQyUyMGludCUyQyUyMGZsb2F0JTJDJTIwTm9uZVR5cGUlNUQlMEElMjAlMjAlMjAlRTIlODAlQTIlMjBtZXRhZGF0YSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUzQSUyMHR5cGluZy5EaWN0JTVCc3RyJTJDJTIwdHlwaW5nLkFueSU1RCUwQSUyMCUyMCUyMCVFMiU4MCVBMiUyMGluZm9fc3RhdGUlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlM0ElMjBMaXN0JTVCZmxvYXQlNUQlMEElMjAlMjAlMjAlRTIlODAlQTIlMjBsZWdhbF9hY3Rpb25zJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNBJTIwTGlzdCU1QmludCU1RCUwQSUyMCUyMCUyMCVFMiU4MCVBMiUyMGdhbWVfcGhhc2UlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlM0ElMjBzdHIlMEElMjAlMjAlMjAlRTIlODAlQTIlMjBjdXJyZW50X3BsYXllcl9pZCUyMCUyMCUyMCUyMCUzQSUyMGludCUwQSUyMCUyMCUyMCVFMiU4MCVBMiUyMG9wcG9uZW50X2xhc3RfYWN0aW9uJTIwJTNBJTIwT3B0aW9uYWwlNUJpbnQlNUQlMEElMEElRjAlOUYlOTMlOEElMjBPcGVuU3BpZWxTdGF0ZSUyMChlcGlzb2RlJTIwbWV0YWRhdGEpJTNBJTBBJTIwJTIwJTIwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwZXBpc29kZV9pZCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUzQSUyMHR5cGluZy5PcHRpb25hbCU1QnN0ciU1RCUwQSUyMCUyMCUyMCVFMiU4MCVBMiUyMHN0ZXBfY291bnQlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlM0ElMjAlM0NjbGFzcyUyMCdpbnQnJTNFJTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwZ2FtZV9uYW1lJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNBJTIwc3RyJTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwYWdlbnRfcGxheWVyJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNBJTIwaW50JTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwb3Bwb25lbnRfcG9saWN5JTIwJTIwJTIwJTIwJTIwJTIwJTNBJTIwc3RyJTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwZ2FtZV9wYXJhbXMlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlM0ElMjBEaWN0JTVCc3RyJTJDJTIwQW55JTVEJTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwbnVtX3BsYXllcnMlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlM0ElMjBpbnQlMEElMEElM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlMEElMEElRjAlOUYlOTIlQTElMjBUeXBlJTIwc2FmZXR5JTIwbWVhbnMlM0ElMEElMjAlMjAlMjAlRTIlOUMlODUlMjBZb3VyJTIwSURFJTIwYXV0b2NvbXBsZXRlcyUyMHRoZXNlJTIwZmllbGRzJTBBJTIwJTIwJTIwJUUyJTlDJTg1JTIwVHlwb3MlMjBhcmUlMjBjYXVnaHQlMjBiZWZvcmUlMjBydW5uaW5nJTBBJTIwJTIwJTIwJUUyJTlDJTg1JTIwUmVmYWN0b3JpbmclMjBpcyUyMHNhZmUlMEElMjAlMjAlMjAlRTIlOUMlODUlMjBTZWxmLWRvY3VtZW50aW5nJTIwY29kZQ==",highlighted:`====================================================================== | |
| 🎮 OPENSPIEL INTEGRATION - TYPE-SAFE MODELS | |
| ====================================================================== | |
| 📤 OpenSpielAction (what you send): | |
| ──────────────────────────────────────────────────────────────── | |
| • metadata : typing.<span class="hljs-type">Dict</span>[<span class="hljs-built_in">str</span>, typing.<span class="hljs-type">Any</span>] | |
| • action_id : <span class="hljs-built_in">int</span> | |
| • game_name : <span class="hljs-built_in">str</span> | |
| • game_params : <span class="hljs-type">Dict</span>[<span class="hljs-built_in">str</span>, <span class="hljs-type">Any</span>] | |
| 📥 OpenSpielObservation (what you receive): | |
| ──────────────────────────────────────────────────────────────── | |
| • done : <<span class="hljs-keyword">class</span> <span class="hljs-string">'bool'</span>> | |
| • reward : typing.<span class="hljs-type">Union</span>[<span class="hljs-built_in">bool</span>, <span class="hljs-built_in">int</span>, <span class="hljs-built_in">float</span>, NoneType] | |
| • metadata : typing.<span class="hljs-type">Dict</span>[<span class="hljs-built_in">str</span>, typing.<span class="hljs-type">Any</span>] | |
| • info_state : <span class="hljs-type">List</span>[<span class="hljs-built_in">float</span>] | |
| • legal_actions : <span class="hljs-type">List</span>[<span class="hljs-built_in">int</span>] | |
| • game_phase : <span class="hljs-built_in">str</span> | |
| • current_player_id : <span class="hljs-built_in">int</span> | |
| • opponent_last_action : <span class="hljs-type">Optional</span>[<span class="hljs-built_in">int</span>] | |
| 📊 OpenSpielState (episode metadata): | |
| ──────────────────────────────────────────────────────────────── | |
| • episode_id : typing.<span class="hljs-type">Optional</span>[<span class="hljs-built_in">str</span>] | |
| • step_count : <<span class="hljs-keyword">class</span> <span class="hljs-string">'int'</span>> | |
| • game_name : <span class="hljs-built_in">str</span> | |
| • agent_player : <span class="hljs-built_in">int</span> | |
| • opponent_policy : <span class="hljs-built_in">str</span> | |
| • game_params : <span class="hljs-type">Dict</span>[<span class="hljs-built_in">str</span>, <span class="hljs-type">Any</span>] | |
| • num_players : <span class="hljs-built_in">int</span> | |
| ====================================================================== | |
| 💡 <span class="hljs-type">Type</span> safety means: | |
| ✅ Your IDE autocompletes these fields | |
| ✅ Typos are caught before running | |
| ✅ Refactoring <span class="hljs-keyword">is</span> safe | |
| ✅ Self-documenting code`,lang:"",wrap:!1}}),ls=new o({props:{title:"How the Client Works",local:"how-the-client-works",headingTag:"h3"}}),ts=new o({props:{title:"Part 6: Using Real OpenSpiel 🎮",local:"part-6-using-real-openspiel-",headingTag:"h2"}}),ns=new o({props:{title:"Now let’s USE a production environment!",local:"now-lets-use-a-production-environment",headingTag:"h3"}}),es=new o({props:{title:"The Game: Catch 🔴🏓",local:"the-game-catch-",headingTag:"h3"}}),Ms=new r({props:{code:"JUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJUYwJTlGJTk0JUI0JTIwJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTBBJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTBBJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJTIwJTIwQmFsbCUwQSVFMiVBQyU5QyUyMCVFMiVBQyU5QyUyMCVFMiVBQyU5QyUyMCVFMiVBQyU5QyUyMCVFMiVBQyU5QyUwQSVFMiVBQyU5QyUyMCVFMiVBQyU5QyUyMCVFMiVBQyU5QyUyMCVFMiVBQyU5QyUyMCVFMiVBQyU5QyUyMCUyMCUyMGZhbGxzJTBBJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTBBJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJUUyJUFDJTlDJTIwJTIwJTIwZG93biUwQSVFMiVBQyU5QyUyMCVFMiVBQyU5QyUyMCVFMiVBQyU5QyUyMCVFMiVBQyU5QyUyMCVFMiVBQyU5QyUwQSVFMiVBQyU5QyUyMCVFMiVBQyU5QyUyMCVFMiVBQyU5QyUyMCVFMiVBQyU5QyUyMCVFMiVBQyU5QyUwQSVFMiVBQyU5QyUyMCVFMiVBQyU5QyUyMCVGMCU5RiU4RiU5MyUyMCVFMiVBQyU5QyUyMCVFMiVBQyU5QyUwQSUyMCUyMCUyMCUyMCUyMFBhZGRsZQ==",highlighted:`⬜ ⬜ 🔴 ⬜ ⬜ | |
| ⬜ ⬜ ⬜ ⬜ ⬜ | |
| ⬜ ⬜ ⬜ ⬜ ⬜ <span class="hljs-built_in">Ball</span> | |
| ⬜ ⬜ ⬜ ⬜ ⬜ | |
| ⬜ ⬜ ⬜ ⬜ ⬜ <span class="hljs-variable">falls</span> | |
| ⬜ ⬜ ⬜ ⬜ ⬜ | |
| ⬜ ⬜ ⬜ ⬜ ⬜ <span class="hljs-variable">down</span> | |
| ⬜ ⬜ ⬜ ⬜ ⬜ | |
| ⬜ ⬜ ⬜ ⬜ ⬜ | |
| ⬜ ⬜ 🏓 ⬜ ⬜ | |
| <span class="hljs-variable">Paddle</span>`,lang:"",wrap:!1}}),js=new r({props:{code:"ZnJvbSUyMGVudnMub3BlbnNwaWVsX2VudiUyMGltcG9ydCUyME9wZW5TcGllbEVudiUwQWZyb20lMjBlbnZzLm9wZW5zcGllbF9lbnYubW9kZWxzJTIwaW1wb3J0JTIwKCUwQSUyMCUyMCUyMCUyME9wZW5TcGllbEFjdGlvbiUyQyUwQSUyMCUyMCUyMCUyME9wZW5TcGllbE9ic2VydmF0aW9uJTJDJTBBJTIwJTIwJTIwJTIwT3BlblNwaWVsU3RhdGUlMEEpJTBBZnJvbSUyMGRhdGFjbGFzc2VzJTIwaW1wb3J0JTIwZmllbGRzJTBBJTBBcHJpbnQoJTIyJUYwJTlGJThFJUFFJTIwJTIyJTIwJTJCJTIwJTIyJTNEJTIyKjY0JTIwJTJCJTIwJTIyJTIwJUYwJTlGJThFJUFFJTIyKSUwQXByaW50KCUyMiUyMCUyMCUyMCVFMiU5QyU4NSUyMEltcG9ydGluZyUyMFJlYWwlMjBPcGVuU3BpZWwlMjBFbnZpcm9ubWVudCElMjIpJTBBcHJpbnQoJTIyJUYwJTlGJThFJUFFJTIwJTIyJTIwJTJCJTIwJTIyJTNEJTIyKjY0JTIwJTJCJTIwJTIyJTIwJUYwJTlGJThFJUFFJTVDbiUyMiklMEElMEFwcmludCglMjIlRjAlOUYlOTMlQTYlMjBXaGF0JTIwd2UlMjBqdXN0JTIwaW1wb3J0ZWQlM0ElMjIpJTBBcHJpbnQoJTIyJTIwJTIwJTIwJUUyJTgwJUEyJTIwT3BlblNwaWVsRW52JTIwLSUyMEhUVFAlMjBjbGllbnQlMjBmb3IlMjBPcGVuU3BpZWwlMjBnYW1lcyUyMiklMEFwcmludCglMjIlMjAlMjAlMjAlRTIlODAlQTIlMjBPcGVuU3BpZWxBY3Rpb24lMjAtJTIwVHlwZS1zYWZlJTIwYWN0aW9ucyUyMiklMEFwcmludCglMjIlMjAlMjAlMjAlRTIlODAlQTIlMjBPcGVuU3BpZWxPYnNlcnZhdGlvbiUyMC0lMjBUeXBlLXNhZmUlMjBvYnNlcnZhdGlvbnMlMjIpJTBBcHJpbnQoJTIyJTIwJTIwJTIwJUUyJTgwJUEyJTIwT3BlblNwaWVsU3RhdGUlMjAtJTIwRXBpc29kZSUyMG1ldGFkYXRhJTVDbiUyMiklMEElMEFwcmludCglMjIlRjAlOUYlOTMlOEIlMjBPcGVuU3BpZWxPYnNlcnZhdGlvbiUyMGZpZWxkcyUzQSUyMiklMEFwcmludCglMjIlMjAlMjAlMjAlMjIlMjAlMkIlMjAlMjIlRTIlOTQlODAlMjIlMjAqJTIwNjApJTBBZm9yJTIwZmllbGQlMjBpbiUyMGZpZWxkcyhPcGVuU3BpZWxPYnNlcnZhdGlvbiklM0ElMEElMjAlMjAlMjAlMjBwcmludChmJTIyJTIwJTIwJTIwJUUyJTgwJUEyJTIwJTdCZmllbGQubmFtZSUzQTI1cyU3RCUyMCUzQSUyMCU3QmZpZWxkLnR5cGUlN0QlMjIpJTBBJTBBcHJpbnQoJTIyJTVDbiUyMiUyMCUyQiUyMCUyMiUzRCUyMio3MCklMEFwcmludCglMjIlNUNuJUYwJTlGJTkyJUExJTIwVGhpcyUyMGlzJTIwUkVBTCUyME9wZW5FbnYlMjBjb2RlJTIwLSUyMHVzZWQlMjBpbiUyMHByb2R1Y3Rpb24hJTIyKSUwQXByaW50KCUyMiUyMCUyMCUyMCVFMiU4MCVBMiUyMFdyYXBzJTIwNiUyME9wZW5TcGllbCUyMGdhbWVzJTIwKENhdGNoJTJDJTIwVGljLVRhYy1Ub2UlMkMlMjBQb2tlciUyQyUyMGV0Yy4pJTIyKSUwQXByaW50KCUyMiUyMCUyMCUyMCVFMiU4MCVBMiUyMFR5cGUtc2FmZSUyMGFjdGlvbnMlMjBhbmQlMjBvYnNlcnZhdGlvbnMlMjIpJTBBcHJpbnQoJTIyJTIwJTIwJTIwJUUyJTgwJUEyJTIwV29ya3MlMjB2aWElMjBIVFRQJTIwKHdlJ2xsJTIwc2VlJTIwdGhhdCUyMG5leHQhKSU1Q24lMjIp",highlighted:`<span class="hljs-keyword">from</span> envs.openspiel_env <span class="hljs-keyword">import</span> OpenSpielEnv | |
| <span class="hljs-keyword">from</span> envs.openspiel_env.models <span class="hljs-keyword">import</span> ( | |
| OpenSpielAction, | |
| OpenSpielObservation, | |
| OpenSpielState | |
| ) | |
| <span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> fields | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"🎮 "</span> + <span class="hljs-string">"="</span>*<span class="hljs-number">64</span> + <span class="hljs-string">" 🎮"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" ✅ Importing Real OpenSpiel Environment!"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"🎮 "</span> + <span class="hljs-string">"="</span>*<span class="hljs-number">64</span> + <span class="hljs-string">" 🎮\\n"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"📦 What we just imported:"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" • OpenSpielEnv - HTTP client for OpenSpiel games"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" • OpenSpielAction - Type-safe actions"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" • OpenSpielObservation - Type-safe observations"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" • OpenSpielState - Episode metadata\\n"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"📋 OpenSpielObservation fields:"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" "</span> + <span class="hljs-string">"─"</span> * <span class="hljs-number">60</span>) | |
| <span class="hljs-keyword">for</span> field <span class="hljs-keyword">in</span> fields(OpenSpielObservation): | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f" • <span class="hljs-subst">{field.name:25s}</span> : <span class="hljs-subst">{field.<span class="hljs-built_in">type</span>}</span>"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n"</span> + <span class="hljs-string">"="</span>*<span class="hljs-number">70</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n💡 This is REAL OpenEnv code - used in production!"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" • Wraps 6 OpenSpiel games (Catch, Tic-Tac-Toe, Poker, etc.)"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" • Type-safe actions and observations"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" • Works via HTTP (we'll see that next!)\\n"</span>)`,lang:"python",wrap:!1}}),os=new r({props:{code:"JUYwJTlGJThFJUFFJTIwJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTIwJUYwJTlGJThFJUFFJTBBJTIwJTIwJTIwJUUyJTlDJTg1JTIwSW1wb3J0aW5nJTIwUmVhbCUyME9wZW5TcGllbCUyMEVudmlyb25tZW50ISUwQSVGMCU5RiU4RSVBRSUyMCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUzRCUyMCVGMCU5RiU4RSVBRSUwQSUwQSVGMCU5RiU5MyVBNiUyMFdoYXQlMjB3ZSUyMGp1c3QlMjBpbXBvcnRlZCUzQSUwQSUyMCUyMCUyMCVFMiU4MCVBMiUyME9wZW5TcGllbEVudiUyMC0lMjBIVFRQJTIwY2xpZW50JTIwZm9yJTIwT3BlblNwaWVsJTIwZ2FtZXMlMEElMjAlMjAlMjAlRTIlODAlQTIlMjBPcGVuU3BpZWxBY3Rpb24lMjAtJTIwVHlwZS1zYWZlJTIwYWN0aW9ucyUwQSUyMCUyMCUyMCVFMiU4MCVBMiUyME9wZW5TcGllbE9ic2VydmF0aW9uJTIwLSUyMFR5cGUtc2FmZSUyMG9ic2VydmF0aW9ucyUwQSUyMCUyMCUyMCVFMiU4MCVBMiUyME9wZW5TcGllbFN0YXRlJTIwLSUyMEVwaXNvZGUlMjBtZXRhZGF0YSUwQSUwQSVGMCU5RiU5MyU4QiUyME9wZW5TcGllbE9ic2VydmF0aW9uJTIwZmllbGRzJTNBJTBBJTIwJTIwJTIwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJUUyJTk0JTgwJTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwZG9uZSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUzQSUyMCUzQ2NsYXNzJTIwJ2Jvb2wnJTNFJTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwcmV3YXJkJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNBJTIwdHlwaW5nLlVuaW9uJTVCYm9vbCUyQyUyMGludCUyQyUyMGZsb2F0JTJDJTIwTm9uZVR5cGUlNUQlMEElMjAlMjAlMjAlRTIlODAlQTIlMjBtZXRhZGF0YSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUzQSUyMHR5cGluZy5EaWN0JTVCc3RyJTJDJTIwdHlwaW5nLkFueSU1RCUwQSUyMCUyMCUyMCVFMiU4MCVBMiUyMGluZm9fc3RhdGUlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlM0ElMjBMaXN0JTVCZmxvYXQlNUQlMEElMjAlMjAlMjAlRTIlODAlQTIlMjBsZWdhbF9hY3Rpb25zJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTNBJTIwTGlzdCU1QmludCU1RCUwQSUyMCUyMCUyMCVFMiU4MCVBMiUyMGdhbWVfcGhhc2UlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlM0ElMjBzdHIlMEElMjAlMjAlMjAlRTIlODAlQTIlMjBjdXJyZW50X3BsYXllcl9pZCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUzQSUyMGludCUwQSUyMCUyMCUyMCVFMiU4MCVBMiUyMG9wcG9uZW50X2xhc3RfYWN0aW9uJTIwJTIwJTIwJTIwJTIwJTIwJTNBJTIwT3B0aW9uYWwlNUJpbnQlNUQlMEElMEElM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlMEElMEElRjAlOUYlOTIlQTElMjBUaGlzJTIwaXMlMjBSRUFMJTIwT3BlbkVudiUyMGNvZGUlMjAtJTIwdXNlZCUyMGluJTIwcHJvZHVjdGlvbiElMEElMjAlMjAlMjAlRTIlODAlQTIlMjBXcmFwcyUyMDYlMjBPcGVuU3BpZWwlMjBnYW1lcyUyMChDYXRjaCUyQyUyMFRpYy1UYWMtVG9lJTJDJTIwUG9rZXIlMkMlMjBldGMuKSUwQSUyMCUyMCUyMCVFMiU4MCVBMiUyMFR5cGUtc2FmZSUyMGFjdGlvbnMlMjBhbmQlMjBvYnNlcnZhdGlvbnMlMEElMjAlMjAlMjAlRTIlODAlQTIlMjBXb3JrcyUyMHZpYSUyMEhUVFAlMjAod2UnbGwlMjBzZWUlMjB0aGF0JTIwbmV4dCEp",highlighted:`🎮 ================================================================ 🎮 | |
| ✅ Importing Real OpenSpiel Environment! | |
| 🎮 ================================================================ 🎮 | |
| 📦 What we just imported: | |
| • OpenSpielEnv - HTTP client <span class="hljs-keyword">for</span> OpenSpiel games | |
| • OpenSpielAction - <span class="hljs-type">Type</span>-safe actions | |
| • OpenSpielObservation - <span class="hljs-type">Type</span>-safe observations | |
| • OpenSpielState - Episode metadata | |
| 📋 OpenSpielObservation fields: | |
| ──────────────────────────────────────────────────────────── | |
| • done : <<span class="hljs-keyword">class</span> <span class="hljs-string">'bool'</span>> | |
| • reward : typing.<span class="hljs-type">Union</span>[<span class="hljs-built_in">bool</span>, <span class="hljs-built_in">int</span>, <span class="hljs-built_in">float</span>, NoneType] | |
| • metadata : typing.<span class="hljs-type">Dict</span>[<span class="hljs-built_in">str</span>, typing.<span class="hljs-type">Any</span>] | |
| • info_state : <span class="hljs-type">List</span>[<span class="hljs-built_in">float</span>] | |
| • legal_actions : <span class="hljs-type">List</span>[<span class="hljs-built_in">int</span>] | |
| • game_phase : <span class="hljs-built_in">str</span> | |
| • current_player_id : <span class="hljs-built_in">int</span> | |
| • opponent_last_action : <span class="hljs-type">Optional</span>[<span class="hljs-built_in">int</span>] | |
| ====================================================================== | |
| 💡 This <span class="hljs-keyword">is</span> REAL OpenEnv code - used <span class="hljs-keyword">in</span> production! | |
| • Wraps <span class="hljs-number">6</span> OpenSpiel games (Catch, Tic-Tac-Toe, Poker, etc.) | |
| • <span class="hljs-type">Type</span>-safe actions <span class="hljs-keyword">and</span> observations | |
| • Works via HTTP (we<span class="hljs-string">'ll see that next!)</span>`,lang:"",wrap:!1}}),rs=new o({props:{title:"Part 7: Four Policies 🤖",local:"part-7-four-policies-",headingTag:"h2"}}),us=new r({props:{code:"aW1wb3J0JTIwcmFuZG9tJTBBJTBBJTIzJTIwJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTBBJTIzJTIwUE9MSUNJRVMlMjAtJTIwRGlmZmVyZW50JTIwQUklMjBzdHJhdGVnaWVzJTIwKGFkYXB0ZWQlMjBmb3IlMjBPcGVuU3BpZWwpJTBBJTIzJTIwJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTBBJTBBY2xhc3MlMjBSYW5kb21Qb2xpY3klM0ElMEElMjAlMjAlMjAlMjAlMjIlMjIlMjJCYXNlbGluZSUzQSUyMFB1cmUlMjByYW5kb20lMjBndWVzc2luZy4lMjIlMjIlMjIlMEElMjAlMjAlMjAlMjBuYW1lJTIwJTNEJTIwJTIyJUYwJTlGJThFJUIyJTIwUmFuZG9tJTIwR3Vlc3NlciUyMiUwQSUwQSUyMCUyMCUyMCUyMGRlZiUyMHNlbGVjdF9hY3Rpb24oc2VsZiUyQyUyMG9icyUzQSUyME9wZW5TcGllbE9ic2VydmF0aW9uKSUyMC0lM0UlMjBpbnQlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjByYW5kb20uY2hvaWNlKG9icy5sZWdhbF9hY3Rpb25zKSUwQSUwQSUwQWNsYXNzJTIwQWx3YXlzU3RheVBvbGljeSUzQSUwQSUyMCUyMCUyMCUyMCUyMiUyMiUyMkJhZCUyMHN0cmF0ZWd5JTNBJTIwTmV2ZXIlMjBtb3Zlcy4lMjIlMjIlMjIlMEElMjAlMjAlMjAlMjBuYW1lJTIwJTNEJTIwJTIyJUYwJTlGJTlCJTkxJTIwQWx3YXlzJTIwU3RheSUyMiUwQSUwQSUyMCUyMCUyMCUyMGRlZiUyMHNlbGVjdF9hY3Rpb24oc2VsZiUyQyUyMG9icyUzQSUyME9wZW5TcGllbE9ic2VydmF0aW9uKSUyMC0lM0UlMjBpbnQlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjAxJTIwJTIwJTIzJTIwU1RBWSUwQSUwQSUwQWNsYXNzJTIwU21hcnRQb2xpY3klM0ElMEElMjAlMjAlMjAlMjAlMjIlMjIlMjJPcHRpbWFsJTNBJTIwTW92ZSUyMHBhZGRsZSUyMHRvd2FyZCUyMGJhbGwuJTIyJTIyJTIyJTBBJTIwJTIwJTIwJTIwbmFtZSUyMCUzRCUyMCUyMiVGMCU5RiVBNyVBMCUyMFNtYXJ0JTIwSGV1cmlzdGljJTIyJTBBJTBBJTIwJTIwJTIwJTIwZGVmJTIwc2VsZWN0X2FjdGlvbihzZWxmJTJDJTIwb2JzJTNBJTIwT3BlblNwaWVsT2JzZXJ2YXRpb24pJTIwLSUzRSUyMGludCUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMyUyMFBhcnNlJTIwT3BlblNwaWVsJTIwb2JzZXJ2YXRpb24lMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjMlMjBGb3IlMjBDYXRjaCUzQSUyMGluZm9fc3RhdGUlMjBpcyUyMGElMjBmbGF0dGVuZWQlMjAxMHg1JTIwZ3JpZCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMyUyMEJhbGwlMjBwb3NpdGlvbiUyMGFuZCUyMHBhZGRsZSUyMHBvc2l0aW9uJTIwZW5jb2RlZCUyMGluJTIwdGhlJTIwdmVjdG9yJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwaW5mb19zdGF0ZSUyMCUzRCUyMG9icy5pbmZvX3N0YXRlJTBBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIzJTIwRmluZCUyMGJhbGwlMjBhbmQlMjBwYWRkbGUlMjBwb3NpdGlvbnMlMjBmcm9tJTIwaW5mb19zdGF0ZSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMyUyMENhdGNoJTIwdXNlcyUyMGElMjAxMHg1JTIwZ3JpZCUyQyUyMHNvJTIwNTAlMjB2YWx1ZXMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBncmlkX3NpemUlMjAlM0QlMjA1JTBBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIzJTIwRmluZCUyMHBvc2l0aW9ucyUyMChiYWxsJTIwJTNEJTIwMS4wJTIwaW4lMjB0aGUlMjBmbGF0dGVuZWQlMjBncmlkJTJDJTIwcGFkZGxlJTIwJTNEJTIwMS4wJTIwaW4lMjB0aGUlMjBsYXN0JTIwcm93JTIwb2YlMjB0aGUlMjBmbGF0dGVuZWQlMjBncmlkKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGJhbGxfY29sJTIwJTNEJTIwTm9uZSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHBhZGRsZV9jb2wlMjAlM0QlMjBOb25lJTBBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZm9yJTIwaWR4JTJDJTIwdmFsJTIwaW4lMjBlbnVtZXJhdGUoaW5mb19zdGF0ZSklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBpZiUyMGFicyh2YWwlMjAtJTIwMS4wKSUyMCUzQyUyMDAuMDElM0ElMjAlMjAlMjMlMjBCYWxsJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwYmFsbF9jb2wlMjAlM0QlMjBpZHglMjAlMjUlMjBncmlkX3NpemUlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBicmVhayUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGxhc3Rfcm93JTIwJTNEJTIwaW5mb19zdGF0ZSU1Qi1ncmlkX3NpemUlM0ElNUQlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBwYWRkbGVfY29sJTIwJTNEJTIwbGFzdF9yb3cuaW5kZXgoMS4wKSUyMCUyMyUyMFBhZGRsZSUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGlmJTIwYmFsbF9jb2wlMjBpcyUyMG5vdCUyME5vbmUlMjBhbmQlMjBwYWRkbGVfY29sJTIwaXMlMjBub3QlMjBOb25lJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwaWYlMjBwYWRkbGVfY29sJTIwJTNDJTIwYmFsbF9jb2wlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjAyJTIwJTIwJTIzJTIwTW92ZSUyMFJJR0hUJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZWxpZiUyMHBhZGRsZV9jb2wlMjAlM0UlMjBiYWxsX2NvbCUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMDAlMjAlMjAlMjMlMjBNb3ZlJTIwTEVGVCUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMDElMjAlMjAlMjMlMjBTVEFZJTIwKGZhbGxiYWNrKSUwQSUwQSUwQWNsYXNzJTIwTGVhcm5pbmdQb2xpY3klM0ElMEElMjAlMjAlMjAlMjAlMjIlMjIlMjJTaW11bGF0ZWQlMjBSTCUzQSUyMEVwc2lsb24tZ3JlZWR5JTIwZXhwbG9yYXRpb24uJTIyJTIyJTIyJTBBJTIwJTIwJTIwJTIwbmFtZSUyMCUzRCUyMCUyMiVGMCU5RiU5MyU4OCUyMExlYXJuaW5nJTIwQWdlbnQlMjIlMEElMEElMjAlMjAlMjAlMjBkZWYlMjBfX2luaXRfXyhzZWxmKSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHNlbGYuc3RlcHMlMjAlM0QlMjAwJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwc2VsZi5zbWFydF9wb2xpY3klMjAlM0QlMjBTbWFydFBvbGljeSgpJTBBJTBBJTIwJTIwJTIwJTIwZGVmJTIwc2VsZWN0X2FjdGlvbihzZWxmJTJDJTIwb2JzJTNBJTIwT3BlblNwaWVsT2JzZXJ2YXRpb24pJTIwLSUzRSUyMGludCUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHNlbGYuc3RlcHMlMjAlMkIlM0QlMjAxJTBBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIzJTIwRGVjYXklMjBleHBsb3JhdGlvbiUyMHJhdGUlMjBvdmVyJTIwdGltZSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGVwc2lsb24lMjAlM0QlMjBtYXgoMC4xJTJDJTIwMS4wJTIwLSUyMChzZWxmLnN0ZXBzJTIwJTJGJTIwMTAwKSklMEElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBpZiUyMHJhbmRvbS5yYW5kb20oKSUyMCUzQyUyMGVwc2lsb24lM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjMlMjBFeHBsb3JlJTNBJTIwcmFuZG9tJTIwYWN0aW9uJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwcmFuZG9tLmNob2ljZShvYnMubGVnYWxfYWN0aW9ucyklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBlbHNlJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIzJTIwRXhwbG9pdCUzQSUyMHVzZSUyMHNtYXJ0JTIwc3RyYXRlZ3klMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjBzZWxmLnNtYXJ0X3BvbGljeS5zZWxlY3RfYWN0aW9uKG9icyklMEElMEElMEFwcmludCglMjIlRjAlOUYlQTQlOTYlMjAlMjIlMjAlMkIlMjAlMjIlM0QlMjIqNjQlMjAlMkIlMjAlMjIlMjAlRjAlOUYlQTQlOTYlMjIpJTBBcHJpbnQoJTIyJTIwJTIwJTIwJUUyJTlDJTg1JTIwNCUyMFBvbGljaWVzJTIwQ3JlYXRlZCUyMChBZGFwdGVkJTIwZm9yJTIwT3BlblNwaWVsKSElMjIpJTBBcHJpbnQoJTIyJUYwJTlGJUE0JTk2JTIwJTIyJTIwJTJCJTIwJTIyJTNEJTIyKjY0JTIwJTJCJTIwJTIyJTIwJUYwJTlGJUE0JTk2JTVDbiUyMiklMEElMEFwb2xpY2llcyUyMCUzRCUyMCU1QlJhbmRvbVBvbGljeSgpJTJDJTIwQWx3YXlzU3RheVBvbGljeSgpJTJDJTIwU21hcnRQb2xpY3koKSUyQyUyMExlYXJuaW5nUG9saWN5KCklNUQlMEFmb3IlMjBpJTJDJTIwcG9saWN5JTIwaW4lMjBlbnVtZXJhdGUocG9saWNpZXMlMkMlMjAxKSUzQSUwQSUyMCUyMCUyMCUyMHByaW50KGYlMjIlMjAlMjAlMjAlN0JpJTdELiUyMCU3QnBvbGljeS5uYW1lJTdEJTIyKSUwQSUwQXByaW50KCUyMiU1Q24lRjAlOUYlOTIlQTElMjBUaGVzZSUyMHBvbGljaWVzJTIwd29yayUyMHdpdGglMjBPcGVuU3BpZWxPYnNlcnZhdGlvbiElMjIpJTBBcHJpbnQoJTIyJTIwJTIwJTIwJUUyJTgwJUEyJTIwUmVhZCUyMGluZm9fc3RhdGUlMjAoZmxhdHRlbmVkJTIwZ3JpZCklMjIpJTBBcHJpbnQoJTIyJTIwJTIwJTIwJUUyJTgwJUEyJTIwVXNlJTIwbGVnYWxfYWN0aW9ucyUyMiklMEFwcmludCglMjIlMjAlMjAlMjAlRTIlODAlQTIlMjBXb3JrJTIwd2l0aCUyMEFOWSUyME9wZW5TcGllbCUyMGdhbWUlMjB0aGF0JTIwZXhwb3NlcyUyMHRoZXNlISU1Q24lMjIp",highlighted:`<span class="hljs-keyword">import</span> random | |
| <span class="hljs-comment"># ============================================================================</span> | |
| <span class="hljs-comment"># POLICIES - Different AI strategies (adapted for OpenSpiel)</span> | |
| <span class="hljs-comment"># ============================================================================</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">RandomPolicy</span>: | |
| <span class="hljs-string">"""Baseline: Pure random guessing."""</span> | |
| name = <span class="hljs-string">"🎲 Random Guesser"</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">select_action</span>(<span class="hljs-params">self, obs: OpenSpielObservation</span>) -> <span class="hljs-built_in">int</span>: | |
| <span class="hljs-keyword">return</span> random.choice(obs.legal_actions) | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">AlwaysStayPolicy</span>: | |
| <span class="hljs-string">"""Bad strategy: Never moves."""</span> | |
| name = <span class="hljs-string">"🛑 Always Stay"</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">select_action</span>(<span class="hljs-params">self, obs: OpenSpielObservation</span>) -> <span class="hljs-built_in">int</span>: | |
| <span class="hljs-keyword">return</span> <span class="hljs-number">1</span> <span class="hljs-comment"># STAY</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">SmartPolicy</span>: | |
| <span class="hljs-string">"""Optimal: Move paddle toward ball."""</span> | |
| name = <span class="hljs-string">"🧠 Smart Heuristic"</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">select_action</span>(<span class="hljs-params">self, obs: OpenSpielObservation</span>) -> <span class="hljs-built_in">int</span>: | |
| <span class="hljs-comment"># Parse OpenSpiel observation</span> | |
| <span class="hljs-comment"># For Catch: info_state is a flattened 10x5 grid</span> | |
| <span class="hljs-comment"># Ball position and paddle position encoded in the vector</span> | |
| info_state = obs.info_state | |
| <span class="hljs-comment"># Find ball and paddle positions from info_state</span> | |
| <span class="hljs-comment"># Catch uses a 10x5 grid, so 50 values</span> | |
| grid_size = <span class="hljs-number">5</span> | |
| <span class="hljs-comment"># Find positions (ball = 1.0 in the flattened grid, paddle = 1.0 in the last row of the flattened grid)</span> | |
| ball_col = <span class="hljs-literal">None</span> | |
| paddle_col = <span class="hljs-literal">None</span> | |
| <span class="hljs-keyword">for</span> idx, val <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(info_state): | |
| <span class="hljs-keyword">if</span> <span class="hljs-built_in">abs</span>(val - <span class="hljs-number">1.0</span>) < <span class="hljs-number">0.01</span>: <span class="hljs-comment"># Ball</span> | |
| ball_col = idx % grid_size | |
| <span class="hljs-keyword">break</span> | |
| last_row = info_state[-grid_size:] | |
| paddle_col = last_row.index(<span class="hljs-number">1.0</span>) <span class="hljs-comment"># Paddle</span> | |
| <span class="hljs-keyword">if</span> ball_col <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-literal">None</span> <span class="hljs-keyword">and</span> paddle_col <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-literal">None</span>: | |
| <span class="hljs-keyword">if</span> paddle_col < ball_col: | |
| <span class="hljs-keyword">return</span> <span class="hljs-number">2</span> <span class="hljs-comment"># Move RIGHT</span> | |
| <span class="hljs-keyword">elif</span> paddle_col > ball_col: | |
| <span class="hljs-keyword">return</span> <span class="hljs-number">0</span> <span class="hljs-comment"># Move LEFT</span> | |
| <span class="hljs-keyword">return</span> <span class="hljs-number">1</span> <span class="hljs-comment"># STAY (fallback)</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">LearningPolicy</span>: | |
| <span class="hljs-string">"""Simulated RL: Epsilon-greedy exploration."""</span> | |
| name = <span class="hljs-string">"📈 Learning Agent"</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self</span>): | |
| self.steps = <span class="hljs-number">0</span> | |
| self.smart_policy = SmartPolicy() | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">select_action</span>(<span class="hljs-params">self, obs: OpenSpielObservation</span>) -> <span class="hljs-built_in">int</span>: | |
| self.steps += <span class="hljs-number">1</span> | |
| <span class="hljs-comment"># Decay exploration rate over time</span> | |
| epsilon = <span class="hljs-built_in">max</span>(<span class="hljs-number">0.1</span>, <span class="hljs-number">1.0</span> - (self.steps / <span class="hljs-number">100</span>)) | |
| <span class="hljs-keyword">if</span> random.random() < epsilon: | |
| <span class="hljs-comment"># Explore: random action</span> | |
| <span class="hljs-keyword">return</span> random.choice(obs.legal_actions) | |
| <span class="hljs-keyword">else</span>: | |
| <span class="hljs-comment"># Exploit: use smart strategy</span> | |
| <span class="hljs-keyword">return</span> self.smart_policy.select_action(obs) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"🤖 "</span> + <span class="hljs-string">"="</span>*<span class="hljs-number">64</span> + <span class="hljs-string">" 🤖"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" ✅ 4 Policies Created (Adapted for OpenSpiel)!"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"🤖 "</span> + <span class="hljs-string">"="</span>*<span class="hljs-number">64</span> + <span class="hljs-string">" 🤖\\n"</span>) | |
| policies = [RandomPolicy(), AlwaysStayPolicy(), SmartPolicy(), LearningPolicy()] | |
| <span class="hljs-keyword">for</span> i, policy <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(policies, <span class="hljs-number">1</span>): | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f" <span class="hljs-subst">{i}</span>. <span class="hljs-subst">{policy.name}</span>"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n💡 These policies work with OpenSpielObservation!"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" • Read info_state (flattened grid)"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" • Use legal_actions"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" • Work with ANY OpenSpiel game that exposes these!\\n"</span>)`,lang:"python",wrap:!1}}),hs=new r({props:{code:"JUYwJTlGJUE0JTk2JTIwJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTNEJTIwJUYwJTlGJUE0JTk2JTBBJTIwJTIwJTIwJUUyJTlDJTg1JTIwNCUyMFBvbGljaWVzJTIwQ3JlYXRlZCUyMChBZGFwdGVkJTIwZm9yJTIwT3BlblNwaWVsKSElMEElRjAlOUYlQTQlOTYlMjAlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlM0QlMjAlRjAlOUYlQTQlOTYlMEElMEElMjAlMjAlMjAxLiUyMCVGMCU5RiU4RSVCMiUyMFJhbmRvbSUyMEd1ZXNzZXIlMEElMjAlMjAlMjAyLiUyMCVGMCU5RiU5QiU5MSUyMEFsd2F5cyUyMFN0YXklMEElMjAlMjAlMjAzLiUyMCVGMCU5RiVBNyVBMCUyMFNtYXJ0JTIwSGV1cmlzdGljJTBBJTIwJTIwJTIwNC4lMjAlRjAlOUYlOTMlODglMjBMZWFybmluZyUyMEFnZW50JTBBJTBBJUYwJTlGJTkyJUExJTIwVGhlc2UlMjBwb2xpY2llcyUyMHdvcmslMjB3aXRoJTIwT3BlblNwaWVsT2JzZXJ2YXRpb24hJTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwUmVhZCUyMGluZm9fc3RhdGUlMjAoZmxhdHRlbmVkJTIwZ3JpZCklMEElMjAlMjAlMjAlRTIlODAlQTIlMjBVc2UlMjBsZWdhbF9hY3Rpb25zJTBBJTIwJTIwJTIwJUUyJTgwJUEyJTIwV29yayUyMHdpdGglMjBBTlklMjBPcGVuU3BpZWwlMjBnYW1lJTIwdGhhdCUyMGV4cG9zZXMlMjB0aGVzZSE=",highlighted:`🤖 ================================================================ 🤖 | |
| ✅ <span class="hljs-number">4</span> Policies Created (Adapted <span class="hljs-keyword">for</span> OpenSpiel)! | |
| 🤖 ================================================================ 🤖 | |
| <span class="hljs-number">1.</span> 🎲 Random Guesser | |
| <span class="hljs-number">2.</span> 🛑 <span class="hljs-keyword">Always</span> Stay | |
| <span class="hljs-number">3.</span> 🧠 Smart Heuristic | |
| <span class="hljs-number">4.</span> 📈 Learning Agent | |
| 💡 These policies <span class="hljs-keyword">work</span> <span class="hljs-keyword">with</span> OpenSpielObservation! | |
| • <span class="hljs-keyword">Read</span> info_state (flattened grid) | |
| • Use legal_actions | |
| • <span class="hljs-keyword">Work</span> <span class="hljs-keyword">with</span> <span class="hljs-keyword">ANY</span> OpenSpiel game that exposes these!`,lang:"",wrap:!1}}),ms=new o({props:{title:"Part 8: Policy Competition! 🏆",local:"part-8-policy-competition-",headingTag:"h2"}}),As=new r({props:{code:"ZGVmJTIwZXZhbHVhdGVfcG9saWNpZXMoZW52JTJDJTIwbnVtX2VwaXNvZGVzJTNENTApJTNBJTBBJTIwJTIwJTIwJTIwJTIyJTIyJTIyQ29tcGFyZSUyMGFsbCUyMHBvbGljaWVzJTIwb3ZlciUyMG1hbnklMjBlcGlzb2RlcyUyMHVzaW5nJTIwcmVhbCUyME9wZW5TcGllbC4lMjIlMjIlMjIlMEElMjAlMjAlMjAlMjBwb2xpY2llcyUyMCUzRCUyMCU1QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMFJhbmRvbVBvbGljeSgpJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwQWx3YXlzU3RheVBvbGljeSgpJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwU21hcnRQb2xpY3koKSUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMExlYXJuaW5nUG9saWN5KCklMkMlMEElMjAlMjAlMjAlMjAlNUQlMEElMEElMjAlMjAlMjAlMjBwcmludCglMjIlNUNuJUYwJTlGJThGJTg2JTIwJTIyJTIwJTJCJTIwJTIyJTNEJTIyKjY2JTIwJTJCJTIwJTIyJTIwJUYwJTlGJThGJTg2JTIyKSUwQSUyMCUyMCUyMCUyMHByaW50KGYlMjIlMjAlMjAlMjBQT0xJQ1klMjBTSE9XRE9XTiUyMC0lMjAlN0JudW1fZXBpc29kZXMlN0QlMjBFcGlzb2RlcyUyMEVhY2glMjIpJTBBJTIwJTIwJTIwJTIwcHJpbnQoZiUyMiUyMCUyMCUyMFBsYXlpbmclMjBhZ2FpbnN0JTIwUkVBTCUyME9wZW5TcGllbCUyMENhdGNoISUyMiklMEElMjAlMjAlMjAlMjBwcmludCglMjIlRjAlOUYlOEYlODYlMjAlMjIlMjAlMkIlMjAlMjIlM0QlMjIqNjYlMjAlMkIlMjAlMjIlMjAlRjAlOUYlOEYlODYlNUNuJTIyKSUwQSUwQSUyMCUyMCUyMCUyMHJlc3VsdHMlMjAlM0QlMjAlNUIlNUQlMEElMjAlMjAlMjAlMjBmb3IlMjBwb2xpY3klMjBpbiUyMHBvbGljaWVzJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcHJpbnQoZiUyMiVFMiU5QSVBMSUyMFRlc3RpbmclMjAlN0Jwb2xpY3kubmFtZSU3RC4uLiUyMiUyQyUyMGVuZCUzRCUyMiUyMCUyMiklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBzdWNjZXNzZXMlMjAlM0QlMjBzdW0ocnVuX2VwaXNvZGUoZW52JTJDJTIwcG9saWN5JTJDJTIwdmlzdWFsaXplJTNERmFsc2UpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZm9yJTIwXyUyMGluJTIwcmFuZ2UobnVtX2VwaXNvZGVzKSklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBzdWNjZXNzX3JhdGUlMjAlM0QlMjAoc3VjY2Vzc2VzJTIwJTJGJTIwbnVtX2VwaXNvZGVzKSUyMColMjAxMDAlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXN1bHRzLmFwcGVuZCgocG9saWN5Lm5hbWUlMkMlMjBzdWNjZXNzX3JhdGUlMkMlMjBzdWNjZXNzZXMpKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHByaW50KGYlMjIlRTIlOUMlOTMlMjBEb25lISUyMiklMEElMEElMjAlMjAlMjAlMjBwcmludCglMjIlNUNuJTIyJTIwJTJCJTIwJTIyJTNEJTIyKjcwKSUwQSUyMCUyMCUyMCUyMHByaW50KCUyMiUyMCUyMCUyMCVGMCU5RiU5MyU4QSUyMEZJTkFMJTIwUkVTVUxUUyUyMiklMEElMjAlMjAlMjAlMjBwcmludCglMjIlM0QlMjIqNzAlMjAlMkIlMjAlMjIlNUNuJTIyKSUwQSUwQSUyMCUyMCUyMCUyMCUyMyUyMFNvcnQlMjBieSUyMHN1Y2Nlc3MlMjByYXRlJTIwKGRlc2NlbmRpbmcpJTBBJTIwJTIwJTIwJTIwcmVzdWx0cy5zb3J0KGtleSUzRGxhbWJkYSUyMHglM0ElMjB4JTVCMSU1RCUyQyUyMHJldmVyc2UlM0RUcnVlKSUwQSUwQSUyMCUyMCUyMCUyMCUyMyUyMEF3YXJkJTIwbWVkYWxzJTIwdG8lMjB0b3AlMjAzJTBBJTIwJTIwJTIwJTIwbWVkYWxzJTIwJTNEJTIwJTVCJTIyJUYwJTlGJUE1JTg3JTIyJTJDJTIwJTIyJUYwJTlGJUE1JTg4JTIyJTJDJTIwJTIyJUYwJTlGJUE1JTg5JTIyJTJDJTIwJTIyJTIwJTIwJTIyJTVEJTBBJTBBJTIwJTIwJTIwJTIwZm9yJTIwaSUyQyUyMChuYW1lJTJDJTIwcmF0ZSUyQyUyMHN1Y2Nlc3NlcyklMjBpbiUyMGVudW1lcmF0ZShyZXN1bHRzKSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG1lZGFsJTIwJTNEJTIwbWVkYWxzJTVCaSU1RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGJhciUyMCUzRCUyMCUyMiVFMiU5NiU4OCUyMiUyMColMjBpbnQocmF0ZSUyMCUyRiUyMDIpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcHJpbnQoZiUyMiU3Qm1lZGFsJTdEJTIwJTdCbmFtZSUzQTI1cyU3RCUyMCU1QiU3QmJhciUzQSUzQzUwJTdEJTVEJTIwJTdCcmF0ZSUzQTUuMWYlN0QlMjUlMjAoJTdCc3VjY2Vzc2VzJTdEJTJGJTdCbnVtX2VwaXNvZGVzJTdEKSUyMiklMEElMEElMjAlMjAlMjAlMjBwcmludCglMjIlNUNuJTIyJTIwJTJCJTIwJTIyJTNEJTIyKjcwKSUwQSUyMCUyMCUyMCUyMHByaW50KCUyMiU1Q24lRTIlOUMlQTglMjBLZXklMjBJbnNpZ2h0cyUzQSUyMiklMEElMjAlMjAlMjAlMjBwcmludCglMjIlMjAlMjAlMjAlRTIlODAlQTIlMjBSYW5kb20lMjAofjIwJTI1KSUzQSUyMCUyMCUyMCUyMCUyMCUyMEJhc2VsaW5lJTIwLSUyMHB1cmUlMjBsdWNrJTIwJUYwJTlGJThFJUIyJTIyKSUwQSUyMCUyMCUyMCUyMHByaW50KCUyMiUyMCUyMCUyMCVFMiU4MCVBMiUyMEFsd2F5cyUyMFN0YXklMjAofjIwJTI1KSUzQSUyMEJhZCUyMHN0cmF0ZWd5JTIwLSUyMHN0YXlzJTIwY2VudGVyJTIwJUYwJTlGJTlCJTkxJTIyKSUwQSUyMCUyMCUyMCUyMHByaW50KCUyMiUyMCUyMCUyMCVFMiU4MCVBMiUyMFNtYXJ0JTIwKDEwMCUyNSklM0ElMjAlMjAlMjAlMjAlMjAlMjAlMjBPcHRpbWFsJTIwLSUyMHBlcmZlY3QlMjBwbGF5ISUyMCVGMCU5RiVBNyVBMCUyMiklMEElMjAlMjAlMjAlMjBwcmludCglMjIlMjAlMjAlMjAlRTIlODAlQTIlMjBMZWFybmluZyUyMCh+ODUlMjUpJTNBJTIwJTIwJTIwJTIwSW1wcm92ZXMlMjBvdmVyJTIwdGltZSUyMCVGMCU5RiU5MyU4OCUyMiklMEElMjAlMjAlMjAlMjBwcmludCglMjIlNUNuJUYwJTlGJThFJTkzJTIwVGhpcyUyMGlzJTIwUmVpbmZvcmNlbWVudCUyMExlYXJuaW5nJTIwJTJCJTIwT3BlbkVudiUyMGluJTIwYWN0aW9uJTNBJTIyKSUwQSUyMCUyMCUyMCUyMHByaW50KCUyMiUyMCUyMCUyMDEuJTIwV2UlMjBVU0VEJTIwZXhpc3RpbmclMjBPcGVuU3BpZWwlMjBlbnZpcm9ubWVudCUyMChkaWRuJ3QlMjBidWlsZCUyMGl0KSUyMiklMEElMjAlMjAlMjAlMjBwcmludCglMjIlMjAlMjAlMjAyLiUyMFR5cGUtc2FmZSUyMGNvbW11bmljYXRpb24lMjBvdmVyJTIwSFRUUCUyMiklMEElMjAlMjAlMjAlMjBwcmludCglMjIlMjAlMjAlMjAzLiUyMFNhbWUlMjBjb2RlJTIwd29ya3MlMjBmb3IlMjBBTlklMjBPcGVuU3BpZWwlMjBnYW1lJTIyKSUwQSUyMCUyMCUyMCUyMHByaW50KCUyMiUyMCUyMCUyMDQuJTIwUHJvZHVjdGlvbi1yZWFkeSUyMGFyY2hpdGVjdHVyZSU1Q24lMjIpJTBBJTBBJTIzJTIwUnVuJTIwdGhlJTIwZXBpYyUyMGNvbXBldGl0aW9uISUwQXByaW50KCUyMiVGMCU5RiU4RSVBRSUyMFN0YXJ0aW5nJTIwdGhlJTIwc2hvd2Rvd24lMjBhZ2FpbnN0JTIwUkVBTCUyME9wZW5TcGllbC4uLiU1Q24lMjIpJTBBZXZhbHVhdGVfcG9saWNpZXMoY2xpZW50JTJDJTIwbnVtX2VwaXNvZGVzJTNENTAp",highlighted:`<span class="hljs-keyword">def</span> <span class="hljs-title function_">evaluate_policies</span>(<span class="hljs-params">env, num_episodes=<span class="hljs-number">50</span></span>): | |
| <span class="hljs-string">"""Compare all policies over many episodes using real OpenSpiel."""</span> | |
| policies = [ | |
| RandomPolicy(), | |
| AlwaysStayPolicy(), | |
| SmartPolicy(), | |
| LearningPolicy(), | |
| ] | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n🏆 "</span> + <span class="hljs-string">"="</span>*<span class="hljs-number">66</span> + <span class="hljs-string">" 🏆"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f" POLICY SHOWDOWN - <span class="hljs-subst">{num_episodes}</span> Episodes Each"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f" Playing against REAL OpenSpiel Catch!"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"🏆 "</span> + <span class="hljs-string">"="</span>*<span class="hljs-number">66</span> + <span class="hljs-string">" 🏆\\n"</span>) | |
| results = [] | |
| <span class="hljs-keyword">for</span> policy <span class="hljs-keyword">in</span> policies: | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f"⚡ Testing <span class="hljs-subst">{policy.name}</span>..."</span>, end=<span class="hljs-string">" "</span>) | |
| successes = <span class="hljs-built_in">sum</span>(run_episode(env, policy, visualize=<span class="hljs-literal">False</span>) | |
| <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num_episodes)) | |
| success_rate = (successes / num_episodes) * <span class="hljs-number">100</span> | |
| results.append((policy.name, success_rate, successes)) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f"✓ Done!"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n"</span> + <span class="hljs-string">"="</span>*<span class="hljs-number">70</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" 📊 FINAL RESULTS"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"="</span>*<span class="hljs-number">70</span> + <span class="hljs-string">"\\n"</span>) | |
| <span class="hljs-comment"># Sort by success rate (descending)</span> | |
| results.sort(key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-number">1</span>], reverse=<span class="hljs-literal">True</span>) | |
| <span class="hljs-comment"># Award medals to top 3</span> | |
| medals = [<span class="hljs-string">"🥇"</span>, <span class="hljs-string">"🥈"</span>, <span class="hljs-string">"🥉"</span>, <span class="hljs-string">" "</span>] | |
| <span class="hljs-keyword">for</span> i, (name, rate, successes) <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(results): | |
| medal = medals[i] | |
| bar = <span class="hljs-string">"█"</span> * <span class="hljs-built_in">int</span>(rate / <span class="hljs-number">2</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f"<span class="hljs-subst">{medal}</span> <span class="hljs-subst">{name:25s}</span> [<span class="hljs-subst">{bar:<<span class="hljs-number">50</span>}</span>] <span class="hljs-subst">{rate:<span class="hljs-number">5.1</span>f}</span>% (<span class="hljs-subst">{successes}</span>/<span class="hljs-subst">{num_episodes}</span>)"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n"</span> + <span class="hljs-string">"="</span>*<span class="hljs-number">70</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n✨ Key Insights:"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" • Random (~20%): Baseline - pure luck 🎲"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" • Always Stay (~20%): Bad strategy - stays center 🛑"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" • Smart (100%): Optimal - perfect play! 🧠"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" • Learning (~85%): Improves over time 📈"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"\\n🎓 This is Reinforcement Learning + OpenEnv in action:"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" 1. We USED existing OpenSpiel environment (didn't build it)"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" 2. Type-safe communication over HTTP"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" 3. Same code works for ANY OpenSpiel game"</span>) | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">" 4. Production-ready architecture\\n"</span>) | |
| <span class="hljs-comment"># Run the epic competition!</span> | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">"🎮 Starting the showdown against REAL OpenSpiel...\\n"</span>) | |
| evaluate_policies(client, num_episodes=<span class="hljs-number">50</span>)`,lang:"python",wrap:!1}}),bs=new o({props:{title:"Part 9: Switching to Other Games 🎮",local:"part-9-switching-to-other-games-",headingTag:"h2"}}),Bs=new o({props:{title:"What We Just Used: Real OpenSpiel! 🎉",local:"what-we-just-used-real-openspiel-",headingTag:"h3"}}),Ss=new o({props:{title:"🎮 6 Games Available - Same Interface!",local:"-6-games-available---same-interface",headingTag:"h3"}}),Vs=new r({props:{code:"JTIzJTIwV2UlMjBqdXN0JTIwdXNlZCUyMENhdGNoJTBBZW52JTIwJTNEJTIwT3BlblNwaWVsRW52KGJhc2VfdXJsJTNEJTIyaHR0cCUzQSUyRiUyRmxvY2FsaG9zdCUzQTgwMDAlMjIpJTBBJTIzJTIwZ2FtZV9uYW1lJTNEJTIyY2F0Y2glMjIlMjB3YXMlMjBzZXQlMjB2aWElMjBlbnZpcm9ubWVudCUyMHZhcmlhYmxlJTBBJTBBJTIzJTIwV2FudCUyMFRpYy1UYWMtVG9lJTIwaW5zdGVhZCUzRiUyMEp1c3QlMjBjaGFuZ2UlMjB0aGUlMjBnYW1lISUwQSUyMyUyMFN0YXJ0JTIwc2VydmVyJTIwd2l0aCUzQSUyME9QRU5TUElFTF9HQU1FJTNEdGljX3RhY190b2UlMjB1dmljb3JuJTIwLi4uJTBBJTIzJTIwU2FtZSUyMGNsaWVudCUyMGNvZGUlMjB3b3JrcyE=",highlighted:`<span class="hljs-comment"># We just used Catch</span> | |
| env = OpenSpielEnv(base_url=<span class="hljs-string">"http://localhost:8000"</span>) | |
| <span class="hljs-comment"># game_name="catch" was set via environment variable</span> | |
| <span class="hljs-comment"># Want Tic-Tac-Toe instead? Just change the game!</span> | |
| <span class="hljs-comment"># Start server with: OPENSPIEL_GAME=tic_tac_toe uvicorn ...</span> | |
| <span class="hljs-comment"># Same client code works!</span>`,lang:"python",wrap:!1}}),Zs=new o({props:{title:"Try Another Game (Optional):",local:"try-another-game-optional",headingTag:"h3"}}),Fs=new r({props:{code:"JTIzJTIwU3RvcCUyMHRoZSUyMGN1cnJlbnQlMjBzZXJ2ZXIlMjAoa2lsbCUyMHRoZSUyMHNlcnZlcl9wcm9jZXNzKSUwQSUyMyUyMFRoZW4lMjBzdGFydCUyMGElMjBuZXclMjBnYW1lJTNBJTBBJTBBc2VydmVyX3Byb2Nlc3MlMjAlM0QlMjBzdWJwcm9jZXNzLlBvcGVuKCUwQSUyMCUyMCUyMCUyMCU1QnN5cy5leGVjdXRhYmxlJTJDJTIwJTIyLW0lMjIlMkMlMjAlMjJ1dmljb3JuJTIyJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIyZW52cy5vcGVuc3BpZWxfZW52LnNlcnZlci5hcHAlM0FhcHAlMjIlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjItLWhvc3QlMjIlMkMlMjAlMjIwLjAuMC4wJTIyJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIyLS1wb3J0JTIyJTJDJTIwJTIyODAwMCUyMiU1RCUyQyUwQSUyMCUyMCUyMCUyMGVudiUzRCU3Qioqb3MuZW52aXJvbiUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMlBZVEhPTlBBVEglMjIlM0ElMjBmJTIyJTdCd29ya19kaXIlN0QlMkZzcmMlMjIlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJPUEVOU1BJRUxfR0FNRSUyMiUzQSUyMCUyMnRpY190YWNfdG9lJTIyJTJDJTIwJTIwJTIzJTIwQ2hhbmdlZCElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJPUEVOU1BJRUxfQUdFTlRfUExBWUVSJTIyJTNBJTIwJTIyMCUyMiUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMk9QRU5TUElFTF9PUFBPTkVOVF9QT0xJQ1klMjIlM0ElMjAlMjJyYW5kb20lMjIlN0QlMkMlMEElMjAlMjAlMjAlMjAlMjMlMjAuLi4lMjByZXN0JTIwb2YlMjBjb25maWclMEEpJTBBJTBBJTIzJTIwU2FtZSUyMGNsaWVudCUyMHdvcmtzISUwQWNsaWVudCUyMCUzRCUyME9wZW5TcGllbEVudihiYXNlX3VybCUzRCUyMmh0dHAlM0ElMkYlMkZsb2NhbGhvc3QlM0E4MDAwJTIyKSUwQXJlc3VsdCUyMCUzRCUyMGNsaWVudC5yZXNldCgpJTIwJTIwJTIzJTIwTm93JTIwcGxheWluZyUyMFRpYy1UYWMtVG9lIQ==",highlighted:`<span class="hljs-comment"># Stop the current server (kill the server_process)</span> | |
| <span class="hljs-comment"># Then start a new game:</span> | |
| server_process = subprocess.Popen( | |
| [sys.executable, <span class="hljs-string">"-m"</span>, <span class="hljs-string">"uvicorn"</span>, | |
| <span class="hljs-string">"envs.openspiel_env.server.app:app"</span>, | |
| <span class="hljs-string">"--host"</span>, <span class="hljs-string">"0.0.0.0"</span>, | |
| <span class="hljs-string">"--port"</span>, <span class="hljs-string">"8000"</span>], | |
| env={**os.environ, | |
| <span class="hljs-string">"PYTHONPATH"</span>: <span class="hljs-string">f"<span class="hljs-subst">{work_dir}</span>/src"</span>, | |
| <span class="hljs-string">"OPENSPIEL_GAME"</span>: <span class="hljs-string">"tic_tac_toe"</span>, <span class="hljs-comment"># Changed!</span> | |
| <span class="hljs-string">"OPENSPIEL_AGENT_PLAYER"</span>: <span class="hljs-string">"0"</span>, | |
| <span class="hljs-string">"OPENSPIEL_OPPONENT_POLICY"</span>: <span class="hljs-string">"random"</span>}, | |
| <span class="hljs-comment"># ... rest of config</span> | |
| ) | |
| <span class="hljs-comment"># Same client works!</span> | |
| client = OpenSpielEnv(base_url=<span class="hljs-string">"http://localhost:8000"</span>) | |
| result = client.reset() <span class="hljs-comment"># Now playing Tic-Tac-Toe!</span>`,lang:"python",wrap:!1}}),$s=new o({props:{title:"Part 10: Create Your Own Integration 🛠️",local:"part-10-create-your-own-integration-",headingTag:"h2"}}),Ys=new o({props:{title:"The 5-Step Pattern",local:"the-5-step-pattern",headingTag:"h3"}}),xs=new o({props:{title:"Step 1: Define Types ( models.py )",local:"step-1-define-types--modelspy-",headingTag:"h3"}}),Hs=new r({props:{code:"ZnJvbSUyMGRhdGFjbGFzc2VzJTIwaW1wb3J0JTIwZGF0YWNsYXNzJTBBZnJvbSUyMGNvcmUuZW52X3NlcnZlciUyMGltcG9ydCUyMEFjdGlvbiUyQyUyME9ic2VydmF0aW9uJTJDJTIwU3RhdGUlMEElMEElNDBkYXRhY2xhc3MlMEFjbGFzcyUyMFlvdXJBY3Rpb24oQWN0aW9uKSUzQSUwQSUyMCUyMCUyMCUyMGFjdGlvbl92YWx1ZSUzQSUyMGludCUwQSUyMCUyMCUyMCUyMCUyMyUyMEFkZCUyMHlvdXIlMjBhY3Rpb24lMjBmaWVsZHMlMEElMEElNDBkYXRhY2xhc3MlMEFjbGFzcyUyMFlvdXJPYnNlcnZhdGlvbihPYnNlcnZhdGlvbiklM0ElMEElMjAlMjAlMjAlMjBzdGF0ZV9kYXRhJTNBJTIwTGlzdCU1QmZsb2F0JTVEJTBBJTIwJTIwJTIwJTIwZG9uZSUzQSUyMGJvb2wlMEElMjAlMjAlMjAlMjByZXdhcmQlM0ElMjBmbG9hdCUwQSUyMCUyMCUyMCUyMCUyMyUyMEFkZCUyMHlvdXIlMjBvYnNlcnZhdGlvbiUyMGZpZWxkcyUwQSUwQSU0MGRhdGFjbGFzcyUwQWNsYXNzJTIwWW91clN0YXRlKFN0YXRlKSUzQSUwQSUyMCUyMCUyMCUyMGVwaXNvZGVfaWQlM0ElMjBzdHIlMEElMjAlMjAlMjAlMjBzdGVwX2NvdW50JTNBJTIwaW50JTBBJTIwJTIwJTIwJTIwJTIzJTIwQWRkJTIweW91ciUyMHN0YXRlJTIwZmllbGRz",highlighted:`<span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> dataclass | |
| <span class="hljs-keyword">from</span> core.env_server <span class="hljs-keyword">import</span> Action, Observation, State | |
| <span class="hljs-meta">@dataclass</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">YourAction</span>(<span class="hljs-title class_ inherited__">Action</span>): | |
| action_value: <span class="hljs-built_in">int</span> | |
| <span class="hljs-comment"># Add your action fields</span> | |
| <span class="hljs-meta">@dataclass</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">YourObservation</span>(<span class="hljs-title class_ inherited__">Observation</span>): | |
| state_data: <span class="hljs-type">List</span>[<span class="hljs-built_in">float</span>] | |
| done: <span class="hljs-built_in">bool</span> | |
| reward: <span class="hljs-built_in">float</span> | |
| <span class="hljs-comment"># Add your observation fields</span> | |
| <span class="hljs-meta">@dataclass</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">YourState</span>(<span class="hljs-title class_ inherited__">State</span>): | |
| episode_id: <span class="hljs-built_in">str</span> | |
| step_count: <span class="hljs-built_in">int</span> | |
| <span class="hljs-comment"># Add your state fields</span>`,lang:"python",wrap:!1}}),_s=new o({props:{title:"Step 2: Implement Environment ( server/environment.py )",local:"step-2-implement-environment--serverenvironmentpy-",headingTag:"h3"}}),Xs=new r({props:{code:"ZnJvbSUyMGNvcmUuZW52X3NlcnZlciUyMGltcG9ydCUyMEVudmlyb25tZW50JTBBJTBBY2xhc3MlMjBZb3VyRW52aXJvbm1lbnQoRW52aXJvbm1lbnQpJTNBJTBBJTIwJTIwJTIwJTIwZGVmJTIwcmVzZXQoc2VsZiklMjAtJTNFJTIwT2JzZXJ2YXRpb24lM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjMlMjBJbml0aWFsaXplJTIweW91ciUyMGdhbWUlMkZzaW11bGF0aW9uJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwWW91ck9ic2VydmF0aW9uKC4uLiklMEElMEElMjAlMjAlMjAlMjBkZWYlMjBzdGVwKHNlbGYlMkMlMjBhY3Rpb24lM0ElMjBBY3Rpb24pJTIwLSUzRSUyME9ic2VydmF0aW9uJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIzJTIwRXhlY3V0ZSUyMGFjdGlvbiUyQyUyMHVwZGF0ZSUyMHN0YXRlJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwWW91ck9ic2VydmF0aW9uKC4uLiklMEElMEElMjAlMjAlMjAlMjAlNDBwcm9wZXJ0eSUwQSUyMCUyMCUyMCUyMGRlZiUyMHN0YXRlKHNlbGYpJTIwLSUzRSUyMFN0YXRlJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwc2VsZi5fc3RhdGU=",highlighted:`<span class="hljs-keyword">from</span> core.env_server <span class="hljs-keyword">import</span> Environment | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">YourEnvironment</span>(<span class="hljs-title class_ inherited__">Environment</span>): | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">reset</span>(<span class="hljs-params">self</span>) -> Observation: | |
| <span class="hljs-comment"># Initialize your game/simulation</span> | |
| <span class="hljs-keyword">return</span> YourObservation(...) | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">step</span>(<span class="hljs-params">self, action: Action</span>) -> Observation: | |
| <span class="hljs-comment"># Execute action, update state</span> | |
| <span class="hljs-keyword">return</span> YourObservation(...) | |
| <span class="hljs-meta"> @property</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">state</span>(<span class="hljs-params">self</span>) -> State: | |
| <span class="hljs-keyword">return</span> self._state`,lang:"python",wrap:!1}}),Ds=new o({props:{title:"Step 3: Create Client ( client.py )",local:"step-3-create-client--clientpy-",headingTag:"h3"}}),qs=new r({props:{code:"ZnJvbSUyMGNvcmUuaHR0cF9lbnZfY2xpZW50JTIwaW1wb3J0JTIwSFRUUEVudkNsaWVudCUwQWZyb20lMjBjb3JlLnR5cGVzJTIwaW1wb3J0JTIwU3RlcFJlc3VsdCUwQSUwQWNsYXNzJTIwWW91ckVudihIVFRQRW52Q2xpZW50JTVCWW91ckFjdGlvbiUyQyUyMFlvdXJPYnNlcnZhdGlvbiU1RCklM0ElMEElMjAlMjAlMjAlMjBkZWYlMjBfc3RlcF9wYXlsb2FkKHNlbGYlMkMlMjBhY3Rpb24lM0ElMjBZb3VyQWN0aW9uKSUyMC0lM0UlMjBkaWN0JTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIyJTIyJTIyQ29udmVydCUyMGFjdGlvbiUyMHRvJTIwSlNPTiUyMiUyMiUyMiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMCU3QiUyMmFjdGlvbl92YWx1ZSUyMiUzQSUyMGFjdGlvbi5hY3Rpb25fdmFsdWUlN0QlMEElMEElMjAlMjAlMjAlMjBkZWYlMjBfcGFyc2VfcmVzdWx0KHNlbGYlMkMlMjBwYXlsb2FkJTNBJTIwZGljdCklMjAtJTNFJTIwU3RlcFJlc3VsdCUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMiUyMiUyMlBhcnNlJTIwSlNPTiUyMHRvJTIwb2JzZXJ2YXRpb24lMjIlMjIlMjIlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjBTdGVwUmVzdWx0KCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG9ic2VydmF0aW9uJTNEWW91ck9ic2VydmF0aW9uKC4uLiklMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXdhcmQlM0RwYXlsb2FkJTVCJ3Jld2FyZCclNUQlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBkb25lJTNEcGF5bG9hZCU1Qidkb25lJyU1RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCklMEElMEElMjAlMjAlMjAlMjBkZWYlMjBfcGFyc2Vfc3RhdGUoc2VsZiUyQyUyMHBheWxvYWQlM0ElMjBkaWN0KSUyMC0lM0UlMjBZb3VyU3RhdGUlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjBZb3VyU3RhdGUoLi4uKQ==",highlighted:`<span class="hljs-keyword">from</span> core.http_env_client <span class="hljs-keyword">import</span> HTTPEnvClient | |
| <span class="hljs-keyword">from</span> core.types <span class="hljs-keyword">import</span> StepResult | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">YourEnv</span>(HTTPEnvClient[YourAction, YourObservation]): | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">_step_payload</span>(<span class="hljs-params">self, action: YourAction</span>) -> <span class="hljs-built_in">dict</span>: | |
| <span class="hljs-string">"""Convert action to JSON"""</span> | |
| <span class="hljs-keyword">return</span> {<span class="hljs-string">"action_value"</span>: action.action_value} | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">_parse_result</span>(<span class="hljs-params">self, payload: <span class="hljs-built_in">dict</span></span>) -> StepResult: | |
| <span class="hljs-string">"""Parse JSON to observation"""</span> | |
| <span class="hljs-keyword">return</span> StepResult( | |
| observation=YourObservation(...), | |
| reward=payload[<span class="hljs-string">'reward'</span>], | |
| done=payload[<span class="hljs-string">'done'</span>] | |
| ) | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">_parse_state</span>(<span class="hljs-params">self, payload: <span class="hljs-built_in">dict</span></span>) -> YourState: | |
| <span class="hljs-keyword">return</span> YourState(...)`,lang:"python",wrap:!1}}),Ls=new o({props:{title:"Step 4: Create Server ( server/app.py )",local:"step-4-create-server--serverapppy-",headingTag:"h3"}}),Ps=new r({props:{code:"ZnJvbSUyMGNvcmUuZW52X3NlcnZlciUyMGltcG9ydCUyMGNyZWF0ZV9mYXN0YXBpX2FwcCUwQWZyb20lMjAueW91cl9lbnZpcm9ubWVudCUyMGltcG9ydCUyMFlvdXJFbnZpcm9ubWVudCUwQSUwQWVudiUyMCUzRCUyMFlvdXJFbnZpcm9ubWVudCgpJTBBYXBwJTIwJTNEJTIwY3JlYXRlX2Zhc3RhcGlfYXBwKGVudiklMEElMEElMjMlMjBUaGF0J3MlMjBpdCElMjBPcGVuRW52JTIwY3JlYXRlcyUyMGFsbCUyMGVuZHBvaW50cyUyMGZvciUyMHlvdS4=",highlighted:`<span class="hljs-keyword">from</span> core.env_server <span class="hljs-keyword">import</span> create_fastapi_app | |
| <span class="hljs-keyword">from</span> .your_environment <span class="hljs-keyword">import</span> YourEnvironment | |
| env = YourEnvironment() | |
| app = create_fastapi_app(env) | |
| <span class="hljs-comment"># That's it! OpenEnv creates all endpoints for you.</span>`,lang:"python",wrap:!1}}),Ks=new o({props:{title:"Step 5: Dockerize ( server/Dockerfile )",local:"step-5-dockerize--serverdockerfile-",headingTag:"h3"}}),lT=new r({props:{code:"RlJPTSUyMHB5dGhvbiUzQTMuMTEtc2xpbSUwQSUwQVdPUktESVIlMjAlMkZhcHAlMEFDT1BZJTIwcmVxdWlyZW1lbnRzLnR4dCUyMC4lMEFSVU4lMjBwaXAlMjBpbnN0YWxsJTIwLS1uby1jYWNoZS1kaXIlMjAtciUyMHJlcXVpcmVtZW50cy50eHQlMEElMEFDT1BZJTIwLiUyMC4lMEFDTUQlMjAlNUIlMjJ1dmljb3JuJTIyJTJDJTIwJTIyYXBwJTNBYXBwJTIyJTJDJTIwJTIyLS1ob3N0JTIyJTJDJTIwJTIyMC4wLjAuMCUyMiUyQyUyMCUyMi0tcG9ydCUyMiUyQyUyMCUyMjgwMDAlMjIlNUQ=",highlighted:`<span class="hljs-keyword">FROM</span> python:<span class="hljs-number">3.11</span>-slim | |
| <span class="hljs-keyword">WORKDIR</span><span class="language-bash"> /app</span> | |
| <span class="hljs-keyword">COPY</span><span class="language-bash"> requirements.txt .</span> | |
| <span class="hljs-keyword">RUN</span><span class="language-bash"> pip install --no-cache-dir -r requirements.txt</span> | |
| <span class="hljs-keyword">COPY</span><span class="language-bash"> . .</span> | |
| <span class="hljs-keyword">CMD</span><span class="language-bash"> [<span class="hljs-string">"uvicorn"</span>, <span class="hljs-string">"app:app"</span>, <span class="hljs-string">"--host"</span>, <span class="hljs-string">"0.0.0.0"</span>, <span class="hljs-string">"--port"</span>, <span class="hljs-string">"8000"</span>]</span>`,lang:"dockerfile",wrap:!1}}),sT=new o({props:{title:"🎓 Examples to Study",local:"-examples-to-study",headingTag:"h3"}}),eT=new o({props:{title:"🎓 Summary: Your Journey",local:"-summary-your-journey",headingTag:"h2"}}),MT=new o({props:{title:"What You Learned",local:"what-you-learned",headingTag:"h3"}}),aT=new o({props:{title:"📚 Concepts",local:"-concepts",headingTag:"h3"}}),iT=new o({props:{title:"🛠️ Skills",local:"-skills",headingTag:"h3"}}),yT=new o({props:{title:"OpenEnv vs Traditional RL",local:"openenv-vs-traditional-rl",headingTag:"h3"}}),wT=new o({props:{title:"📚 Resources",local:"-resources",headingTag:"h2"}}),jT=new o({props:{title:"🔗 Essential Links",local:"-essential-links",headingTag:"h3"}}),oT=new o({props:{title:"📖 Documentation Deep Dives",local:"-documentation-deep-dives",headingTag:"h3"}}),CT=new o({props:{title:"🎓 Community & Support",local:"-community--support",headingTag:"h3"}}),gT=new o({props:{title:"🌈 What’s Next?",local:"-whats-next",headingTag:"h3"}}),bT=new na({props:{source:"https://github.com/huggingface/openenv/blob/main/docs/source/tutorials/openenv-tutorial.md"}}),{c(){b=e("meta"),sJ=t(),KT=e("p"),TJ=t(),a(f.$$.fragment),JJ=t(),a(V.$$.fragment),tJ=t(),u=e("div"),G=e("img"),ke=t(),a(v.$$.fragment),Re=t(),BT=e("p"),BT.innerHTML=JM,Se=t(),QT=e("p"),QT.textContent=tM,fe=t(),kT=e("p"),kT.innerHTML=nM,Ve=t(),RT=e("p"),RT.textContent=eM,nJ=t(),a(O.$$.fragment),eJ=t(),Z=e("p"),Z.textContent=MM,MJ=t(),F=e("p"),F.textContent=UM,UJ=t(),W=e("p"),W.textContent=aM,aJ=t(),$=e("p"),$.textContent=iM,iJ=t(),Y=e("p"),Y.textContent=yM,yJ=t(),z=e("p"),z.textContent=pM,pJ=t(),x=e("p"),x.textContent=wM,wJ=t(),H=e("p"),H.textContent=jM,jJ=t(),_=e("p"),_.textContent=IM,IJ=t(),oJ=e("hr"),rJ=t(),a(X.$$.fragment),CJ=t(),D=e("table"),D.innerHTML=oM,cJ=t(),Q=e("blockquote"),Q.innerHTML=rM,EJ=t(),uJ=e("hr"),NJ=t(),a(q.$$.fragment),hJ=t(),a(L.$$.fragment),mJ=t(),P=e("ul"),P.innerHTML=CM,dJ=t(),a(K.$$.fragment),gJ=t(),ll=e("ul"),ll.innerHTML=cM,AJ=t(),a(sl.$$.fragment),bJ=t(),Tl=e("ul"),Tl.innerHTML=EM,BJ=t(),a(Jl.$$.fragment),QJ=t(),tl=e("ul"),tl.innerHTML=uM,kJ=t(),a(nl.$$.fragment),RJ=t(),el=e("ul"),el.innerHTML=NM,SJ=t(),fJ=e("hr"),VJ=t(),a(Ml.$$.fragment),GJ=t(),Ul=e("p"),Ul.innerHTML=hM,vJ=t(),al=e("p"),al.textContent=mM,OJ=t(),a(il.$$.fragment),ZJ=t(),yl=e("p"),yl.textContent=dM,FJ=t(),pl=e("p"),pl.textContent=gM,WJ=t(),a(wl.$$.fragment),$J=t(),jl=e("p"),jl.innerHTML=AM,YJ=t(),a(Il.$$.fragment),zJ=t(),xJ=e("hr"),HJ=t(),a(ol.$$.fragment),_J=t(),a(rl.$$.fragment),XJ=t(),Cl=e("p"),Cl.textContent=bM,DJ=t(),cl=e("table"),cl.innerHTML=BM,qJ=t(),a(El.$$.fragment),LJ=t(),ul=e("p"),ul.innerHTML=QM,PJ=t(),Nl=e("p"),Nl.textContent=kM,KJ=t(),hl=e("ul"),hl.innerHTML=RM,lt=t(),a(ml.$$.fragment),st=t(),a(dl.$$.fragment),Tt=t(),g=e("blockquote"),ST=e("p"),ST.textContent=SM,Ge=t(),a(gl.$$.fragment),ve=t(),fT=e("p"),fT.textContent=fM,Jt=t(),tt=e("hr"),nt=t(),a(Al.$$.fragment),et=t(),bl=e("p"),bl.innerHTML=VM,Mt=t(),Bl=e("p"),Bl.innerHTML=GM,Ut=t(),a(Ql.$$.fragment),at=t(),kl=e("p"),kl.innerHTML=vM,it=t(),a(Rl.$$.fragment),yt=t(),pt=e("hr"),wt=t(),a(Sl.$$.fragment),jt=t(),a(fl.$$.fragment),It=t(),a(Vl.$$.fragment),ot=t(),Gl=e("p"),Gl.textContent=OM,rt=t(),a(vl.$$.fragment),Ct=t(),Ol=e("p"),Ol.innerHTML=ZM,ct=t(),a(Zl.$$.fragment),Et=t(),ut=e("hr"),Nt=t(),a(Fl.$$.fragment),ht=t(),a(Wl.$$.fragment),mt=t(),$l=e("p"),$l.innerHTML=FM,dt=t(),a(Yl.$$.fragment),gt=t(),zl=e("p"),zl.innerHTML=WM,At=t(),xl=e("table"),xl.innerHTML=$M,bt=t(),Hl=e("p"),Hl.innerHTML=YM,Bt=t(),a(_l.$$.fragment),Qt=t(),Xl=e("p"),Xl.innerHTML=zM,kt=t(),a(Dl.$$.fragment),Rt=t(),a(ql.$$.fragment),St=t(),a(Ll.$$.fragment),ft=t(),Pl=e("p"),Pl.innerHTML=xM,Vt=t(),a(Kl.$$.fragment),Gt=t(),a(ls.$$.fragment),vt=t(),ss=e("p"),ss.innerHTML=HM,Ot=t(),Ts=e("ol"),Ts.innerHTML=_M,Zt=t(),Js=e("p"),Js.textContent=XM,Ft=t(),Wt=e("hr"),$t=t(),a(ts.$$.fragment),Yt=t(),C=e("div"),a(ns.$$.fragment),Oe=t(),VT=e("p"),VT.innerHTML=DM,Ze=t(),GT=e("p"),GT.textContent=qM,Fe=t(),vT=e("p"),vT.innerHTML=LM,We=t(),OT=e("ul"),OT.innerHTML=PM,zt=t(),a(es.$$.fragment),xt=t(),a(Ms.$$.fragment),Ht=t(),Us=e("p"),Us.innerHTML=KM,_t=t(),as=e("ul"),as.innerHTML=lU,Xt=t(),is=e("p"),is.innerHTML=sU,Dt=t(),ys=e("ul"),ys.innerHTML=TU,qt=t(),ps=e("p"),ps.innerHTML=JU,Lt=t(),ws=e("ul"),ws.innerHTML=tU,Pt=t(),k=e("blockquote"),k.innerHTML=nU,Kt=t(),a(js.$$.fragment),ln=t(),Is=e("p"),Is.innerHTML=eU,sn=t(),a(os.$$.fragment),Tn=t(),Jn=e("hr"),tn=t(),a(rs.$$.fragment),nn=t(),Cs=e("p"),Cs.textContent=MU,en=t(),cs=e("table"),cs.innerHTML=UU,Mn=t(),Es=e("p"),Es.innerHTML=aU,Un=t(),a(us.$$.fragment),an=t(),Ns=e("p"),Ns.innerHTML=iU,yn=t(),a(hs.$$.fragment),pn=t(),wn=e("hr"),jn=t(),a(ms.$$.fragment),In=t(),ds=e("p"),ds.innerHTML=yU,on=t(),gs=e("p"),gs.textContent=pU,rn=t(),a(As.$$.fragment),Cn=t(),cn=e("hr"),En=t(),a(bs.$$.fragment),un=t(),a(Bs.$$.fragment),Nn=t(),Qs=e("p"),Qs.innerHTML=wU,hn=t(),ks=e("table"),ks.innerHTML=jU,mn=t(),Rs=e("p"),Rs.innerHTML=IU,dn=t(),a(Ss.$$.fragment),gn=t(),fs=e("p"),fs.innerHTML=oU,An=t(),a(Vs.$$.fragment),bn=t(),Gs=e("p"),Gs.innerHTML=rU,Bn=t(),vs=e("ol"),vs.innerHTML=CU,Qn=t(),Os=e("p"),Os.innerHTML=cU,kn=t(),a(Zs.$$.fragment),Rn=t(),a(Fs.$$.fragment),Sn=t(),Ws=e("p"),Ws.innerHTML=EU,fn=t(),Vn=e("hr"),Gn=t(),a($s.$$.fragment),vn=t(),a(Ys.$$.fragment),On=t(),zs=e("p"),zs.textContent=uU,Zn=t(),a(xs.$$.fragment),Fn=t(),a(Hs.$$.fragment),Wn=t(),a(_s.$$.fragment),$n=t(),a(Xs.$$.fragment),Yn=t(),a(Ds.$$.fragment),zn=t(),a(qs.$$.fragment),xn=t(),a(Ls.$$.fragment),Hn=t(),a(Ps.$$.fragment),_n=t(),a(Ks.$$.fragment),Xn=t(),a(lT.$$.fragment),Dn=t(),a(sT.$$.fragment),qn=t(),TT=e("p"),TT.textContent=NU,Ln=t(),JT=e("ol"),JT.innerHTML=hU,Pn=t(),tT=e("p"),tT.innerHTML=mU,Kn=t(),le=e("hr"),se=t(),nT=e("p"),nT.textContent=dU,Te=t(),a(eT.$$.fragment),Je=t(),a(MT.$$.fragment),te=t(),ZT=e("table"),UT=e("tr"),c=e("td"),a(aT.$$.fragment),$e=t(),FT=e("p"),FT.innerHTML=gU,Ye=t(),WT=e("ul"),WT.innerHTML=AU,ze=t(),$T=e("p"),$T.innerHTML=bU,xe=t(),YT=e("ul"),YT.innerHTML=BU,He=t(),zT=e("p"),zT.innerHTML=QU,_e=t(),xT=e("ul"),xT.innerHTML=kU,Xe=t(),E=e("td"),a(iT.$$.fragment),De=t(),HT=e("p"),HT.innerHTML=RU,qe=t(),_T=e("ul"),_T.innerHTML=SU,Le=t(),XT=e("p"),XT.innerHTML=fU,Pe=t(),DT=e("ul"),DT.innerHTML=VU,Ke=t(),qT=e("p"),qT.innerHTML=GU,lM=t(),LT=e("ul"),LT.innerHTML=vU,ne=t(),a(yT.$$.fragment),ee=t(),pT=e("table"),pT.innerHTML=OU,Me=t(),R=e("blockquote"),R.innerHTML=ZU,Ue=t(),ae=e("hr"),ie=t(),a(wT.$$.fragment),ye=t(),a(jT.$$.fragment),pe=t(),IT=e("ul"),IT.innerHTML=FU,we=t(),a(oT.$$.fragment),je=t(),rT=e("ul"),rT.innerHTML=WU,Ie=t(),a(CT.$$.fragment),oe=t(),cT=e("p"),cT.innerHTML=$U,re=t(),ET=e("ul"),ET.innerHTML=YU,Ce=t(),uT=e("p"),uT.innerHTML=zU,ce=t(),NT=e("ul"),NT.innerHTML=xU,Ee=t(),hT=e("p"),hT.textContent=HU,ue=t(),mT=e("p"),mT.innerHTML=_U,Ne=t(),dT=e("p"),dT.innerHTML=XU,he=t(),me=e("hr"),de=t(),a(gT.$$.fragment),ge=t(),AT=e("ol"),AT.innerHTML=DU,Ae=t(),a(bT.$$.fragment),be=t(),lJ=e("p"),this.h()},l(l){const s=Ja("svelte-u9bgzb",document.head);b=M(s,"META",{name:!0,content:!0}),s.forEach(T),sJ=n(l),KT=M(l,"P",{}),B(KT).forEach(T),TJ=n(l),i(f.$$.fragment,l),JJ=n(l),i(V.$$.fragment,l),tJ=n(l),u=M(l,"DIV",{align:!0});var m=B(u);G=M(m,"IMG",{src:!0,width:!0,alt:!0}),ke=n(m),i(v.$$.fragment,m),Re=n(m),BT=M(m,"P",{"data-svelte-h":!0}),U(BT)!=="svelte-dqwr3"&&(BT.innerHTML=JM),Se=n(m),QT=M(m,"P",{"data-svelte-h":!0}),U(QT)!=="svelte-1dgvh9j"&&(QT.textContent=tM),fe=n(m),kT=M(m,"P",{"data-svelte-h":!0}),U(kT)!=="svelte-10npbdt"&&(kT.innerHTML=nM),Ve=n(m),RT=M(m,"P",{"data-svelte-h":!0}),U(RT)!=="svelte-wo7gof"&&(RT.textContent=eM),m.forEach(T),nJ=n(l),i(O.$$.fragment,l),eJ=n(l),Z=M(l,"P",{"data-svelte-h":!0}),U(Z)!=="svelte-147i8a1"&&(Z.textContent=MM),MJ=n(l),F=M(l,"P",{"data-svelte-h":!0}),U(F)!=="svelte-1mep8fs"&&(F.textContent=UM),UJ=n(l),W=M(l,"P",{"data-svelte-h":!0}),U(W)!=="svelte-3h5zwk"&&(W.textContent=aM),aJ=n(l),$=M(l,"P",{"data-svelte-h":!0}),U($)!=="svelte-1pwvial"&&($.textContent=iM),iJ=n(l),Y=M(l,"P",{"data-svelte-h":!0}),U(Y)!=="svelte-u3ba3d"&&(Y.textContent=yM),yJ=n(l),z=M(l,"P",{"data-svelte-h":!0}),U(z)!=="svelte-13dejvb"&&(z.textContent=pM),pJ=n(l),x=M(l,"P",{"data-svelte-h":!0}),U(x)!=="svelte-a6sebp"&&(x.textContent=wM),wJ=n(l),H=M(l,"P",{"data-svelte-h":!0}),U(H)!=="svelte-1t9nmmv"&&(H.textContent=jM),jJ=n(l),_=M(l,"P",{"data-svelte-h":!0}),U(_)!=="svelte-1wh8n1a"&&(_.textContent=IM),IJ=n(l),oJ=M(l,"HR",{}),rJ=n(l),i(X.$$.fragment,l),CJ=n(l),D=M(l,"TABLE",{"data-svelte-h":!0}),U(D)!=="svelte-1ujwz7q"&&(D.innerHTML=oM),cJ=n(l),Q=M(l,"BLOCKQUOTE",{class:!0,"data-svelte-h":!0}),U(Q)!=="svelte-sponpw"&&(Q.innerHTML=rM),EJ=n(l),uJ=M(l,"HR",{}),NJ=n(l),i(q.$$.fragment,l),hJ=n(l),i(L.$$.fragment,l),mJ=n(l),P=M(l,"UL",{"data-svelte-h":!0}),U(P)!=="svelte-16zxjx5"&&(P.innerHTML=CM),dJ=n(l),i(K.$$.fragment,l),gJ=n(l),ll=M(l,"UL",{"data-svelte-h":!0}),U(ll)!=="svelte-1phxpcb"&&(ll.innerHTML=cM),AJ=n(l),i(sl.$$.fragment,l),bJ=n(l),Tl=M(l,"UL",{"data-svelte-h":!0}),U(Tl)!=="svelte-412jsu"&&(Tl.innerHTML=EM),BJ=n(l),i(Jl.$$.fragment,l),QJ=n(l),tl=M(l,"UL",{"data-svelte-h":!0}),U(tl)!=="svelte-whbwpr"&&(tl.innerHTML=uM),kJ=n(l),i(nl.$$.fragment,l),RJ=n(l),el=M(l,"UL",{"data-svelte-h":!0}),U(el)!=="svelte-1rdx1k6"&&(el.innerHTML=NM),SJ=n(l),fJ=M(l,"HR",{}),VJ=n(l),i(Ml.$$.fragment,l),GJ=n(l),Ul=M(l,"P",{"data-svelte-h":!0}),U(Ul)!=="svelte-1sra4qo"&&(Ul.innerHTML=hM),vJ=n(l),al=M(l,"P",{"data-svelte-h":!0}),U(al)!=="svelte-1hq0szu"&&(al.textContent=mM),OJ=n(l),i(il.$$.fragment,l),ZJ=n(l),yl=M(l,"P",{"data-svelte-h":!0}),U(yl)!=="svelte-12623bd"&&(yl.textContent=dM),FJ=n(l),pl=M(l,"P",{"data-svelte-h":!0}),U(pl)!=="svelte-se3du"&&(pl.textContent=gM),WJ=n(l),i(wl.$$.fragment,l),$J=n(l),jl=M(l,"P",{"data-svelte-h":!0}),U(jl)!=="svelte-1mvdyro"&&(jl.innerHTML=AM),YJ=n(l),i(Il.$$.fragment,l),zJ=n(l),xJ=M(l,"HR",{}),HJ=n(l),i(ol.$$.fragment,l),_J=n(l),i(rl.$$.fragment,l),XJ=n(l),Cl=M(l,"P",{"data-svelte-h":!0}),U(Cl)!=="svelte-i67p0s"&&(Cl.textContent=bM),DJ=n(l),cl=M(l,"TABLE",{"data-svelte-h":!0}),U(cl)!=="svelte-18a95on"&&(cl.innerHTML=BM),qJ=n(l),i(El.$$.fragment,l),LJ=n(l),ul=M(l,"P",{"data-svelte-h":!0}),U(ul)!=="svelte-5fc4nf"&&(ul.innerHTML=QM),PJ=n(l),Nl=M(l,"P",{"data-svelte-h":!0}),U(Nl)!=="svelte-q35fwk"&&(Nl.textContent=kM),KJ=n(l),hl=M(l,"UL",{"data-svelte-h":!0}),U(hl)!=="svelte-r5r65e"&&(hl.innerHTML=RM),lt=n(l),i(ml.$$.fragment,l),st=n(l),i(dl.$$.fragment,l),Tt=n(l),g=M(l,"BLOCKQUOTE",{class:!0});var PT=B(g);ST=M(PT,"P",{"data-svelte-h":!0}),U(ST)!=="svelte-1bevvul"&&(ST.textContent=SM),Ge=n(PT),i(gl.$$.fragment,PT),ve=n(PT),fT=M(PT,"P",{"data-svelte-h":!0}),U(fT)!=="svelte-n5mieo"&&(fT.textContent=fM),PT.forEach(T),Jt=n(l),tt=M(l,"HR",{}),nt=n(l),i(Al.$$.fragment,l),et=n(l),bl=M(l,"P",{"data-svelte-h":!0}),U(bl)!=="svelte-sah4rf"&&(bl.innerHTML=VM),Mt=n(l),Bl=M(l,"P",{"data-svelte-h":!0}),U(Bl)!=="svelte-1ubnijd"&&(Bl.innerHTML=GM),Ut=n(l),i(Ql.$$.fragment,l),at=n(l),kl=M(l,"P",{"data-svelte-h":!0}),U(kl)!=="svelte-1mvdyro"&&(kl.innerHTML=vM),it=n(l),i(Rl.$$.fragment,l),yt=n(l),pt=M(l,"HR",{}),wt=n(l),i(Sl.$$.fragment,l),jt=n(l),i(fl.$$.fragment,l),It=n(l),i(Vl.$$.fragment,l),ot=n(l),Gl=M(l,"P",{"data-svelte-h":!0}),U(Gl)!=="svelte-13qkwtj"&&(Gl.textContent=OM),rt=n(l),i(vl.$$.fragment,l),Ct=n(l),Ol=M(l,"P",{"data-svelte-h":!0}),U(Ol)!=="svelte-1mvdyro"&&(Ol.innerHTML=ZM),ct=n(l),i(Zl.$$.fragment,l),Et=n(l),ut=M(l,"HR",{}),Nt=n(l),i(Fl.$$.fragment,l),ht=n(l),i(Wl.$$.fragment,l),mt=n(l),$l=M(l,"P",{"data-svelte-h":!0}),U($l)!=="svelte-1ulvbfl"&&($l.innerHTML=FM),dt=n(l),i(Yl.$$.fragment,l),gt=n(l),zl=M(l,"P",{"data-svelte-h":!0}),U(zl)!=="svelte-11ajvx"&&(zl.innerHTML=WM),At=n(l),xl=M(l,"TABLE",{"data-svelte-h":!0}),U(xl)!=="svelte-10odg88"&&(xl.innerHTML=$M),bt=n(l),Hl=M(l,"P",{"data-svelte-h":!0}),U(Hl)!=="svelte-1qjt3rd"&&(Hl.innerHTML=YM),Bt=n(l),i(_l.$$.fragment,l),Qt=n(l),Xl=M(l,"P",{"data-svelte-h":!0}),U(Xl)!=="svelte-1mvdyro"&&(Xl.innerHTML=zM),kt=n(l),i(Dl.$$.fragment,l),Rt=n(l),i(ql.$$.fragment,l),St=n(l),i(Ll.$$.fragment,l),ft=n(l),Pl=M(l,"P",{"data-svelte-h":!0}),U(Pl)!=="svelte-1mvdyro"&&(Pl.innerHTML=xM),Vt=n(l),i(Kl.$$.fragment,l),Gt=n(l),i(ls.$$.fragment,l),vt=n(l),ss=M(l,"P",{"data-svelte-h":!0}),U(ss)!=="svelte-13byqjp"&&(ss.innerHTML=HM),Ot=n(l),Ts=M(l,"OL",{"data-svelte-h":!0}),U(Ts)!=="svelte-1e9pr2e"&&(Ts.innerHTML=_M),Zt=n(l),Js=M(l,"P",{"data-svelte-h":!0}),U(Js)!=="svelte-t9q2et"&&(Js.textContent=XM),Ft=n(l),Wt=M(l,"HR",{}),$t=n(l),i(ts.$$.fragment,l),Yt=n(l),C=M(l,"DIV",{style:!0});var A=B(C);i(ns.$$.fragment,A),Oe=n(A),VT=M(A,"P",{"data-svelte-h":!0}),U(VT)!=="svelte-cx2mlx"&&(VT.innerHTML=DM),Ze=n(A),GT=M(A,"P",{"data-svelte-h":!0}),U(GT)!=="svelte-mrbvl4"&&(GT.textContent=qM),Fe=n(A),vT=M(A,"P",{"data-svelte-h":!0}),U(vT)!=="svelte-9gqed3"&&(vT.innerHTML=LM),We=n(A),OT=M(A,"UL",{"data-svelte-h":!0}),U(OT)!=="svelte-1syb72m"&&(OT.innerHTML=PM),A.forEach(T),zt=n(l),i(es.$$.fragment,l),xt=n(l),i(Ms.$$.fragment,l),Ht=n(l),Us=M(l,"P",{"data-svelte-h":!0}),U(Us)!=="svelte-1sb7zhg"&&(Us.innerHTML=KM),_t=n(l),as=M(l,"UL",{"data-svelte-h":!0}),U(as)!=="svelte-168m2ui"&&(as.innerHTML=lU),Xt=n(l),is=M(l,"P",{"data-svelte-h":!0}),U(is)!=="svelte-1nta3bs"&&(is.innerHTML=sU),Dt=n(l),ys=M(l,"UL",{"data-svelte-h":!0}),U(ys)!=="svelte-104dyvo"&&(ys.innerHTML=TU),qt=n(l),ps=M(l,"P",{"data-svelte-h":!0}),U(ps)!=="svelte-94aj12"&&(ps.innerHTML=JU),Lt=n(l),ws=M(l,"UL",{"data-svelte-h":!0}),U(ws)!=="svelte-1pwfkd5"&&(ws.innerHTML=tU),Pt=n(l),k=M(l,"BLOCKQUOTE",{class:!0,"data-svelte-h":!0}),U(k)!=="svelte-1au92wc"&&(k.innerHTML=nU),Kt=n(l),i(js.$$.fragment,l),ln=n(l),Is=M(l,"P",{"data-svelte-h":!0}),U(Is)!=="svelte-1mvdyro"&&(Is.innerHTML=eU),sn=n(l),i(os.$$.fragment,l),Tn=n(l),Jn=M(l,"HR",{}),tn=n(l),i(rs.$$.fragment,l),nn=n(l),Cs=M(l,"P",{"data-svelte-h":!0}),U(Cs)!=="svelte-13ty1hx"&&(Cs.textContent=MU),en=n(l),cs=M(l,"TABLE",{"data-svelte-h":!0}),U(cs)!=="svelte-thn5hf"&&(cs.innerHTML=UU),Mn=n(l),Es=M(l,"P",{"data-svelte-h":!0}),U(Es)!=="svelte-3ez0lz"&&(Es.innerHTML=aU),Un=n(l),i(us.$$.fragment,l),an=n(l),Ns=M(l,"P",{"data-svelte-h":!0}),U(Ns)!=="svelte-1mvdyro"&&(Ns.innerHTML=iU),yn=n(l),i(hs.$$.fragment,l),pn=n(l),wn=M(l,"HR",{}),jn=n(l),i(ms.$$.fragment,l),In=n(l),ds=M(l,"P",{"data-svelte-h":!0}),U(ds)!=="svelte-kempwn"&&(ds.innerHTML=yU),on=n(l),gs=M(l,"P",{"data-svelte-h":!0}),U(gs)!=="svelte-m5903s"&&(gs.textContent=pU),rn=n(l),i(As.$$.fragment,l),Cn=n(l),cn=M(l,"HR",{}),En=n(l),i(bs.$$.fragment,l),un=n(l),i(Bs.$$.fragment,l),Nn=n(l),Qs=M(l,"P",{"data-svelte-h":!0}),U(Qs)!=="svelte-1ov8p0r"&&(Qs.innerHTML=wU),hn=n(l),ks=M(l,"TABLE",{"data-svelte-h":!0}),U(ks)!=="svelte-rbd6y9"&&(ks.innerHTML=jU),mn=n(l),Rs=M(l,"P",{"data-svelte-h":!0}),U(Rs)!=="svelte-1gas7wo"&&(Rs.innerHTML=IU),dn=n(l),i(Ss.$$.fragment,l),gn=n(l),fs=M(l,"P",{"data-svelte-h":!0}),U(fs)!=="svelte-gvky0b"&&(fs.innerHTML=oU),An=n(l),i(Vs.$$.fragment,l),bn=n(l),Gs=M(l,"P",{"data-svelte-h":!0}),U(Gs)!=="svelte-1bf95mj"&&(Gs.innerHTML=rU),Bn=n(l),vs=M(l,"OL",{"data-svelte-h":!0}),U(vs)!=="svelte-pz67ff"&&(vs.innerHTML=CU),Qn=n(l),Os=M(l,"P",{"data-svelte-h":!0}),U(Os)!=="svelte-g15ej3"&&(Os.innerHTML=cU),kn=n(l),i(Zs.$$.fragment,l),Rn=n(l),i(Fs.$$.fragment,l),Sn=n(l),Ws=M(l,"P",{"data-svelte-h":!0}),U(Ws)!=="svelte-1hfxpdg"&&(Ws.innerHTML=EU),fn=n(l),Vn=M(l,"HR",{}),Gn=n(l),i($s.$$.fragment,l),vn=n(l),i(Ys.$$.fragment,l),On=n(l),zs=M(l,"P",{"data-svelte-h":!0}),U(zs)!=="svelte-qjq0u2"&&(zs.textContent=uU),Zn=n(l),i(xs.$$.fragment,l),Fn=n(l),i(Hs.$$.fragment,l),Wn=n(l),i(_s.$$.fragment,l),$n=n(l),i(Xs.$$.fragment,l),Yn=n(l),i(Ds.$$.fragment,l),zn=n(l),i(qs.$$.fragment,l),xn=n(l),i(Ls.$$.fragment,l),Hn=n(l),i(Ps.$$.fragment,l),_n=n(l),i(Ks.$$.fragment,l),Xn=n(l),i(lT.$$.fragment,l),Dn=n(l),i(sT.$$.fragment,l),qn=n(l),TT=M(l,"P",{"data-svelte-h":!0}),U(TT)!=="svelte-1o1vvxr"&&(TT.textContent=NU),Ln=n(l),JT=M(l,"OL",{"data-svelte-h":!0}),U(JT)!=="svelte-vr8qzd"&&(JT.innerHTML=hU),Pn=n(l),tT=M(l,"P",{"data-svelte-h":!0}),U(tT)!=="svelte-xpj7m9"&&(tT.innerHTML=mU),Kn=n(l),le=M(l,"HR",{}),se=n(l),nT=M(l,"P",{"data-svelte-h":!0}),U(nT)!=="svelte-1o8m9nz"&&(nT.textContent=dU),Te=n(l),i(eT.$$.fragment,l),Je=n(l),i(MT.$$.fragment,l),te=n(l),ZT=M(l,"TABLE",{});var qU=B(ZT);UT=M(qU,"TR",{});var Qe=B(UT);c=M(Qe,"TD",{width:!0,style:!0});var N=B(c);i(aT.$$.fragment,N),$e=n(N),FT=M(N,"P",{"data-svelte-h":!0}),U(FT)!=="svelte-1vr33uo"&&(FT.innerHTML=gU),Ye=n(N),WT=M(N,"UL",{"data-svelte-h":!0}),U(WT)!=="svelte-m84lyj"&&(WT.innerHTML=AU),ze=n(N),$T=M(N,"P",{"data-svelte-h":!0}),U($T)!=="svelte-1x4v1d4"&&($T.innerHTML=bU),xe=n(N),YT=M(N,"UL",{"data-svelte-h":!0}),U(YT)!=="svelte-v91uca"&&(YT.innerHTML=BU),He=n(N),zT=M(N,"P",{"data-svelte-h":!0}),U(zT)!=="svelte-91807s"&&(zT.innerHTML=QU),_e=n(N),xT=M(N,"UL",{"data-svelte-h":!0}),U(xT)!=="svelte-yf1s25"&&(xT.innerHTML=kU),N.forEach(T),Xe=n(Qe),E=M(Qe,"TD",{width:!0,style:!0});var h=B(E);i(iT.$$.fragment,h),De=n(h),HT=M(h,"P",{"data-svelte-h":!0}),U(HT)!=="svelte-l2hxiw"&&(HT.innerHTML=RU),qe=n(h),_T=M(h,"UL",{"data-svelte-h":!0}),U(_T)!=="svelte-1sedtxv"&&(_T.innerHTML=SU),Le=n(h),XT=M(h,"P",{"data-svelte-h":!0}),U(XT)!=="svelte-ktnw4c"&&(XT.innerHTML=fU),Pe=n(h),DT=M(h,"UL",{"data-svelte-h":!0}),U(DT)!=="svelte-b67dck"&&(DT.innerHTML=VU),Ke=n(h),qT=M(h,"P",{"data-svelte-h":!0}),U(qT)!=="svelte-s2ejng"&&(qT.innerHTML=GU),lM=n(h),LT=M(h,"UL",{"data-svelte-h":!0}),U(LT)!=="svelte-1198i2y"&&(LT.innerHTML=vU),h.forEach(T),Qe.forEach(T),qU.forEach(T),ne=n(l),i(yT.$$.fragment,l),ee=n(l),pT=M(l,"TABLE",{"data-svelte-h":!0}),U(pT)!=="svelte-1qfha29"&&(pT.innerHTML=OU),Me=n(l),R=M(l,"BLOCKQUOTE",{class:!0,"data-svelte-h":!0}),U(R)!=="svelte-1dhztij"&&(R.innerHTML=ZU),Ue=n(l),ae=M(l,"HR",{}),ie=n(l),i(wT.$$.fragment,l),ye=n(l),i(jT.$$.fragment,l),pe=n(l),IT=M(l,"UL",{"data-svelte-h":!0}),U(IT)!=="svelte-152slk3"&&(IT.innerHTML=FU),we=n(l),i(oT.$$.fragment,l),je=n(l),rT=M(l,"UL",{"data-svelte-h":!0}),U(rT)!=="svelte-120rcor"&&(rT.innerHTML=WU),Ie=n(l),i(CT.$$.fragment,l),oe=n(l),cT=M(l,"P",{"data-svelte-h":!0}),U(cT)!=="svelte-s800wd"&&(cT.innerHTML=$U),re=n(l),ET=M(l,"UL",{"data-svelte-h":!0}),U(ET)!=="svelte-gaykih"&&(ET.innerHTML=YU),Ce=n(l),uT=M(l,"P",{"data-svelte-h":!0}),U(uT)!=="svelte-18dmhca"&&(uT.innerHTML=zU),ce=n(l),NT=M(l,"UL",{"data-svelte-h":!0}),U(NT)!=="svelte-xg09wq"&&(NT.innerHTML=xU),Ee=n(l),hT=M(l,"P",{"data-svelte-h":!0}),U(hT)!=="svelte-15hfh7e"&&(hT.textContent=HU),ue=n(l),mT=M(l,"P",{"data-svelte-h":!0}),U(mT)!=="svelte-hxsby3"&&(mT.innerHTML=_U),Ne=n(l),dT=M(l,"P",{"data-svelte-h":!0}),U(dT)!=="svelte-1d4miao"&&(dT.innerHTML=XU),he=n(l),me=M(l,"HR",{}),de=n(l),i(gT.$$.fragment,l),ge=n(l),AT=M(l,"OL",{"data-svelte-h":!0}),U(AT)!=="svelte-2e177m"&&(AT.innerHTML=DU),Ae=n(l),i(bT.$$.fragment,l),be=n(l),lJ=M(l,"P",{}),B(lJ).forEach(T),this.h()},h(){d(b,"name","hf:doc:metadata"),d(b,"content",Ma),PU(G.src,TM="https://upload.wikimedia.org/wikipedia/commons/1/10/PyTorch_logo_icon.svg")||d(G,"src",TM),d(G,"width","200"),d(G,"alt","PyTorch"),d(u,"align","center"),d(Q,"class","tip"),d(g,"class","note"),S(C,"text-align","center"),S(C,"background","linear-gradient(135deg, #667eea 0%, #764ba2 100%)"),S(C,"color","white"),S(C,"padding","30px"),S(C,"border-radius","15px"),S(C,"margin","30px 0"),d(k,"class","note"),d(c,"width","50%"),S(c,"vertical-align","top"),d(E,"width","50%"),S(E,"vertical-align","top"),d(R,"class","tip")},m(l,s){I(document.head,b),J(l,sJ,s),J(l,KT,s),J(l,TJ,s),y(f,l,s),J(l,JJ,s),y(V,l,s),J(l,tJ,s),J(l,u,s),I(u,G),I(u,ke),y(v,u,null),I(u,Re),I(u,BT),I(u,Se),I(u,QT),I(u,fe),I(u,kT),I(u,Ve),I(u,RT),J(l,nJ,s),y(O,l,s),J(l,eJ,s),J(l,Z,s),J(l,MJ,s),J(l,F,s),J(l,UJ,s),J(l,W,s),J(l,aJ,s),J(l,$,s),J(l,iJ,s),J(l,Y,s),J(l,yJ,s),J(l,z,s),J(l,pJ,s),J(l,x,s),J(l,wJ,s),J(l,H,s),J(l,jJ,s),J(l,_,s),J(l,IJ,s),J(l,oJ,s),J(l,rJ,s),y(X,l,s),J(l,CJ,s),J(l,D,s),J(l,cJ,s),J(l,Q,s),J(l,EJ,s),J(l,uJ,s),J(l,NJ,s),y(q,l,s),J(l,hJ,s),y(L,l,s),J(l,mJ,s),J(l,P,s),J(l,dJ,s),y(K,l,s),J(l,gJ,s),J(l,ll,s),J(l,AJ,s),y(sl,l,s),J(l,bJ,s),J(l,Tl,s),J(l,BJ,s),y(Jl,l,s),J(l,QJ,s),J(l,tl,s),J(l,kJ,s),y(nl,l,s),J(l,RJ,s),J(l,el,s),J(l,SJ,s),J(l,fJ,s),J(l,VJ,s),y(Ml,l,s),J(l,GJ,s),J(l,Ul,s),J(l,vJ,s),J(l,al,s),J(l,OJ,s),y(il,l,s),J(l,ZJ,s),J(l,yl,s),J(l,FJ,s),J(l,pl,s),J(l,WJ,s),y(wl,l,s),J(l,$J,s),J(l,jl,s),J(l,YJ,s),y(Il,l,s),J(l,zJ,s),J(l,xJ,s),J(l,HJ,s),y(ol,l,s),J(l,_J,s),y(rl,l,s),J(l,XJ,s),J(l,Cl,s),J(l,DJ,s),J(l,cl,s),J(l,qJ,s),y(El,l,s),J(l,LJ,s),J(l,ul,s),J(l,PJ,s),J(l,Nl,s),J(l,KJ,s),J(l,hl,s),J(l,lt,s),y(ml,l,s),J(l,st,s),y(dl,l,s),J(l,Tt,s),J(l,g,s),I(g,ST),I(g,Ge),y(gl,g,null),I(g,ve),I(g,fT),J(l,Jt,s),J(l,tt,s),J(l,nt,s),y(Al,l,s),J(l,et,s),J(l,bl,s),J(l,Mt,s),J(l,Bl,s),J(l,Ut,s),y(Ql,l,s),J(l,at,s),J(l,kl,s),J(l,it,s),y(Rl,l,s),J(l,yt,s),J(l,pt,s),J(l,wt,s),y(Sl,l,s),J(l,jt,s),y(fl,l,s),J(l,It,s),y(Vl,l,s),J(l,ot,s),J(l,Gl,s),J(l,rt,s),y(vl,l,s),J(l,Ct,s),J(l,Ol,s),J(l,ct,s),y(Zl,l,s),J(l,Et,s),J(l,ut,s),J(l,Nt,s),y(Fl,l,s),J(l,ht,s),y(Wl,l,s),J(l,mt,s),J(l,$l,s),J(l,dt,s),y(Yl,l,s),J(l,gt,s),J(l,zl,s),J(l,At,s),J(l,xl,s),J(l,bt,s),J(l,Hl,s),J(l,Bt,s),y(_l,l,s),J(l,Qt,s),J(l,Xl,s),J(l,kt,s),y(Dl,l,s),J(l,Rt,s),y(ql,l,s),J(l,St,s),y(Ll,l,s),J(l,ft,s),J(l,Pl,s),J(l,Vt,s),y(Kl,l,s),J(l,Gt,s),y(ls,l,s),J(l,vt,s),J(l,ss,s),J(l,Ot,s),J(l,Ts,s),J(l,Zt,s),J(l,Js,s),J(l,Ft,s),J(l,Wt,s),J(l,$t,s),y(ts,l,s),J(l,Yt,s),J(l,C,s),y(ns,C,null),I(C,Oe),I(C,VT),I(C,Ze),I(C,GT),I(C,Fe),I(C,vT),I(C,We),I(C,OT),J(l,zt,s),y(es,l,s),J(l,xt,s),y(Ms,l,s),J(l,Ht,s),J(l,Us,s),J(l,_t,s),J(l,as,s),J(l,Xt,s),J(l,is,s),J(l,Dt,s),J(l,ys,s),J(l,qt,s),J(l,ps,s),J(l,Lt,s),J(l,ws,s),J(l,Pt,s),J(l,k,s),J(l,Kt,s),y(js,l,s),J(l,ln,s),J(l,Is,s),J(l,sn,s),y(os,l,s),J(l,Tn,s),J(l,Jn,s),J(l,tn,s),y(rs,l,s),J(l,nn,s),J(l,Cs,s),J(l,en,s),J(l,cs,s),J(l,Mn,s),J(l,Es,s),J(l,Un,s),y(us,l,s),J(l,an,s),J(l,Ns,s),J(l,yn,s),y(hs,l,s),J(l,pn,s),J(l,wn,s),J(l,jn,s),y(ms,l,s),J(l,In,s),J(l,ds,s),J(l,on,s),J(l,gs,s),J(l,rn,s),y(As,l,s),J(l,Cn,s),J(l,cn,s),J(l,En,s),y(bs,l,s),J(l,un,s),y(Bs,l,s),J(l,Nn,s),J(l,Qs,s),J(l,hn,s),J(l,ks,s),J(l,mn,s),J(l,Rs,s),J(l,dn,s),y(Ss,l,s),J(l,gn,s),J(l,fs,s),J(l,An,s),y(Vs,l,s),J(l,bn,s),J(l,Gs,s),J(l,Bn,s),J(l,vs,s),J(l,Qn,s),J(l,Os,s),J(l,kn,s),y(Zs,l,s),J(l,Rn,s),y(Fs,l,s),J(l,Sn,s),J(l,Ws,s),J(l,fn,s),J(l,Vn,s),J(l,Gn,s),y($s,l,s),J(l,vn,s),y(Ys,l,s),J(l,On,s),J(l,zs,s),J(l,Zn,s),y(xs,l,s),J(l,Fn,s),y(Hs,l,s),J(l,Wn,s),y(_s,l,s),J(l,$n,s),y(Xs,l,s),J(l,Yn,s),y(Ds,l,s),J(l,zn,s),y(qs,l,s),J(l,xn,s),y(Ls,l,s),J(l,Hn,s),y(Ps,l,s),J(l,_n,s),y(Ks,l,s),J(l,Xn,s),y(lT,l,s),J(l,Dn,s),y(sT,l,s),J(l,qn,s),J(l,TT,s),J(l,Ln,s),J(l,JT,s),J(l,Pn,s),J(l,tT,s),J(l,Kn,s),J(l,le,s),J(l,se,s),J(l,nT,s),J(l,Te,s),y(eT,l,s),J(l,Je,s),y(MT,l,s),J(l,te,s),J(l,ZT,s),I(ZT,UT),I(UT,c),y(aT,c,null),I(c,$e),I(c,FT),I(c,Ye),I(c,WT),I(c,ze),I(c,$T),I(c,xe),I(c,YT),I(c,He),I(c,zT),I(c,_e),I(c,xT),I(UT,Xe),I(UT,E),y(iT,E,null),I(E,De),I(E,HT),I(E,qe),I(E,_T),I(E,Le),I(E,XT),I(E,Pe),I(E,DT),I(E,Ke),I(E,qT),I(E,lM),I(E,LT),J(l,ne,s),y(yT,l,s),J(l,ee,s),J(l,pT,s),J(l,Me,s),J(l,R,s),J(l,Ue,s),J(l,ae,s),J(l,ie,s),y(wT,l,s),J(l,ye,s),y(jT,l,s),J(l,pe,s),J(l,IT,s),J(l,we,s),y(oT,l,s),J(l,je,s),J(l,rT,s),J(l,Ie,s),y(CT,l,s),J(l,oe,s),J(l,cT,s),J(l,re,s),J(l,ET,s),J(l,Ce,s),J(l,uT,s),J(l,ce,s),J(l,NT,s),J(l,Ee,s),J(l,hT,s),J(l,ue,s),J(l,mT,s),J(l,Ne,s),J(l,dT,s),J(l,he,s),J(l,me,s),J(l,de,s),y(gT,l,s),J(l,ge,s),J(l,AT,s),J(l,Ae,s),y(bT,l,s),J(l,be,s),J(l,lJ,s),Be=!0},p:KU,i(l){Be||(p(f.$$.fragment,l),p(V.$$.fragment,l),p(v.$$.fragment,l),p(O.$$.fragment,l),p(X.$$.fragment,l),p(q.$$.fragment,l),p(L.$$.fragment,l),p(K.$$.fragment,l),p(sl.$$.fragment,l),p(Jl.$$.fragment,l),p(nl.$$.fragment,l),p(Ml.$$.fragment,l),p(il.$$.fragment,l),p(wl.$$.fragment,l),p(Il.$$.fragment,l),p(ol.$$.fragment,l),p(rl.$$.fragment,l),p(El.$$.fragment,l),p(ml.$$.fragment,l),p(dl.$$.fragment,l),p(gl.$$.fragment,l),p(Al.$$.fragment,l),p(Ql.$$.fragment,l),p(Rl.$$.fragment,l),p(Sl.$$.fragment,l),p(fl.$$.fragment,l),p(Vl.$$.fragment,l),p(vl.$$.fragment,l),p(Zl.$$.fragment,l),p(Fl.$$.fragment,l),p(Wl.$$.fragment,l),p(Yl.$$.fragment,l),p(_l.$$.fragment,l),p(Dl.$$.fragment,l),p(ql.$$.fragment,l),p(Ll.$$.fragment,l),p(Kl.$$.fragment,l),p(ls.$$.fragment,l),p(ts.$$.fragment,l),p(ns.$$.fragment,l),p(es.$$.fragment,l),p(Ms.$$.fragment,l),p(js.$$.fragment,l),p(os.$$.fragment,l),p(rs.$$.fragment,l),p(us.$$.fragment,l),p(hs.$$.fragment,l),p(ms.$$.fragment,l),p(As.$$.fragment,l),p(bs.$$.fragment,l),p(Bs.$$.fragment,l),p(Ss.$$.fragment,l),p(Vs.$$.fragment,l),p(Zs.$$.fragment,l),p(Fs.$$.fragment,l),p($s.$$.fragment,l),p(Ys.$$.fragment,l),p(xs.$$.fragment,l),p(Hs.$$.fragment,l),p(_s.$$.fragment,l),p(Xs.$$.fragment,l),p(Ds.$$.fragment,l),p(qs.$$.fragment,l),p(Ls.$$.fragment,l),p(Ps.$$.fragment,l),p(Ks.$$.fragment,l),p(lT.$$.fragment,l),p(sT.$$.fragment,l),p(eT.$$.fragment,l),p(MT.$$.fragment,l),p(aT.$$.fragment,l),p(iT.$$.fragment,l),p(yT.$$.fragment,l),p(wT.$$.fragment,l),p(jT.$$.fragment,l),p(oT.$$.fragment,l),p(CT.$$.fragment,l),p(gT.$$.fragment,l),p(bT.$$.fragment,l),Be=!0)},o(l){w(f.$$.fragment,l),w(V.$$.fragment,l),w(v.$$.fragment,l),w(O.$$.fragment,l),w(X.$$.fragment,l),w(q.$$.fragment,l),w(L.$$.fragment,l),w(K.$$.fragment,l),w(sl.$$.fragment,l),w(Jl.$$.fragment,l),w(nl.$$.fragment,l),w(Ml.$$.fragment,l),w(il.$$.fragment,l),w(wl.$$.fragment,l),w(Il.$$.fragment,l),w(ol.$$.fragment,l),w(rl.$$.fragment,l),w(El.$$.fragment,l),w(ml.$$.fragment,l),w(dl.$$.fragment,l),w(gl.$$.fragment,l),w(Al.$$.fragment,l),w(Ql.$$.fragment,l),w(Rl.$$.fragment,l),w(Sl.$$.fragment,l),w(fl.$$.fragment,l),w(Vl.$$.fragment,l),w(vl.$$.fragment,l),w(Zl.$$.fragment,l),w(Fl.$$.fragment,l),w(Wl.$$.fragment,l),w(Yl.$$.fragment,l),w(_l.$$.fragment,l),w(Dl.$$.fragment,l),w(ql.$$.fragment,l),w(Ll.$$.fragment,l),w(Kl.$$.fragment,l),w(ls.$$.fragment,l),w(ts.$$.fragment,l),w(ns.$$.fragment,l),w(es.$$.fragment,l),w(Ms.$$.fragment,l),w(js.$$.fragment,l),w(os.$$.fragment,l),w(rs.$$.fragment,l),w(us.$$.fragment,l),w(hs.$$.fragment,l),w(ms.$$.fragment,l),w(As.$$.fragment,l),w(bs.$$.fragment,l),w(Bs.$$.fragment,l),w(Ss.$$.fragment,l),w(Vs.$$.fragment,l),w(Zs.$$.fragment,l),w(Fs.$$.fragment,l),w($s.$$.fragment,l),w(Ys.$$.fragment,l),w(xs.$$.fragment,l),w(Hs.$$.fragment,l),w(_s.$$.fragment,l),w(Xs.$$.fragment,l),w(Ds.$$.fragment,l),w(qs.$$.fragment,l),w(Ls.$$.fragment,l),w(Ps.$$.fragment,l),w(Ks.$$.fragment,l),w(lT.$$.fragment,l),w(sT.$$.fragment,l),w(eT.$$.fragment,l),w(MT.$$.fragment,l),w(aT.$$.fragment,l),w(iT.$$.fragment,l),w(yT.$$.fragment,l),w(wT.$$.fragment,l),w(jT.$$.fragment,l),w(oT.$$.fragment,l),w(CT.$$.fragment,l),w(gT.$$.fragment,l),w(bT.$$.fragment,l),Be=!1},d(l){l&&(T(sJ),T(KT),T(TJ),T(JJ),T(tJ),T(u),T(nJ),T(eJ),T(Z),T(MJ),T(F),T(UJ),T(W),T(aJ),T($),T(iJ),T(Y),T(yJ),T(z),T(pJ),T(x),T(wJ),T(H),T(jJ),T(_),T(IJ),T(oJ),T(rJ),T(CJ),T(D),T(cJ),T(Q),T(EJ),T(uJ),T(NJ),T(hJ),T(mJ),T(P),T(dJ),T(gJ),T(ll),T(AJ),T(bJ),T(Tl),T(BJ),T(QJ),T(tl),T(kJ),T(RJ),T(el),T(SJ),T(fJ),T(VJ),T(GJ),T(Ul),T(vJ),T(al),T(OJ),T(ZJ),T(yl),T(FJ),T(pl),T(WJ),T($J),T(jl),T(YJ),T(zJ),T(xJ),T(HJ),T(_J),T(XJ),T(Cl),T(DJ),T(cl),T(qJ),T(LJ),T(ul),T(PJ),T(Nl),T(KJ),T(hl),T(lt),T(st),T(Tt),T(g),T(Jt),T(tt),T(nt),T(et),T(bl),T(Mt),T(Bl),T(Ut),T(at),T(kl),T(it),T(yt),T(pt),T(wt),T(jt),T(It),T(ot),T(Gl),T(rt),T(Ct),T(Ol),T(ct),T(Et),T(ut),T(Nt),T(ht),T(mt),T($l),T(dt),T(gt),T(zl),T(At),T(xl),T(bt),T(Hl),T(Bt),T(Qt),T(Xl),T(kt),T(Rt),T(St),T(ft),T(Pl),T(Vt),T(Gt),T(vt),T(ss),T(Ot),T(Ts),T(Zt),T(Js),T(Ft),T(Wt),T($t),T(Yt),T(C),T(zt),T(xt),T(Ht),T(Us),T(_t),T(as),T(Xt),T(is),T(Dt),T(ys),T(qt),T(ps),T(Lt),T(ws),T(Pt),T(k),T(Kt),T(ln),T(Is),T(sn),T(Tn),T(Jn),T(tn),T(nn),T(Cs),T(en),T(cs),T(Mn),T(Es),T(Un),T(an),T(Ns),T(yn),T(pn),T(wn),T(jn),T(In),T(ds),T(on),T(gs),T(rn),T(Cn),T(cn),T(En),T(un),T(Nn),T(Qs),T(hn),T(ks),T(mn),T(Rs),T(dn),T(gn),T(fs),T(An),T(bn),T(Gs),T(Bn),T(vs),T(Qn),T(Os),T(kn),T(Rn),T(Sn),T(Ws),T(fn),T(Vn),T(Gn),T(vn),T(On),T(zs),T(Zn),T(Fn),T(Wn),T($n),T(Yn),T(zn),T(xn),T(Hn),T(_n),T(Xn),T(Dn),T(qn),T(TT),T(Ln),T(JT),T(Pn),T(tT),T(Kn),T(le),T(se),T(nT),T(Te),T(Je),T(te),T(ZT),T(ne),T(ee),T(pT),T(Me),T(R),T(Ue),T(ae),T(ie),T(ye),T(pe),T(IT),T(we),T(je),T(rT),T(Ie),T(oe),T(cT),T(re),T(ET),T(Ce),T(uT),T(ce),T(NT),T(Ee),T(hT),T(ue),T(mT),T(Ne),T(dT),T(he),T(me),T(de),T(ge),T(AT),T(Ae),T(be),T(lJ)),T(b),j(f,l),j(V,l),j(v),j(O,l),j(X,l),j(q,l),j(L,l),j(K,l),j(sl,l),j(Jl,l),j(nl,l),j(Ml,l),j(il,l),j(wl,l),j(Il,l),j(ol,l),j(rl,l),j(El,l),j(ml,l),j(dl,l),j(gl),j(Al,l),j(Ql,l),j(Rl,l),j(Sl,l),j(fl,l),j(Vl,l),j(vl,l),j(Zl,l),j(Fl,l),j(Wl,l),j(Yl,l),j(_l,l),j(Dl,l),j(ql,l),j(Ll,l),j(Kl,l),j(ls,l),j(ts,l),j(ns),j(es,l),j(Ms,l),j(js,l),j(os,l),j(rs,l),j(us,l),j(hs,l),j(ms,l),j(As,l),j(bs,l),j(Bs,l),j(Ss,l),j(Vs,l),j(Zs,l),j(Fs,l),j($s,l),j(Ys,l),j(xs,l),j(Hs,l),j(_s,l),j(Xs,l),j(Ds,l),j(qs,l),j(Ls,l),j(Ps,l),j(Ks,l),j(lT,l),j(sT,l),j(eT,l),j(MT,l),j(aT),j(iT),j(yT,l),j(wT,l),j(jT,l),j(oT,l),j(CT,l),j(gT,l),j(bT,l)}}}const Ma='{"title":"OpenEnv: Production RL Made Simple","local":"openenv-production-rl-made-simple","sections":[{"title":"From “Hello World” to RL Training in 5 Minutes ✨","local":"from-hello-world-to-rl-training-in-5-minutes-","sections":[],"depth":2},{"title":"Why OpenEnv?","local":"why-openenv","sections":[],"depth":2},{"title":"📋 What You’ll Learn","local":"-what-youll-learn","sections":[],"depth":2},{"title":"📑 Table of Contents","local":"-table-of-contents","sections":[{"title":"Foundation","local":"foundation","sections":[],"depth":3},{"title":"Architecture","local":"architecture","sections":[],"depth":3},{"title":"Hands-On Demo","local":"hands-on-demo","sections":[],"depth":3},{"title":"Advanced","local":"advanced","sections":[],"depth":3},{"title":"Wrap Up","local":"wrap-up","sections":[],"depth":3}],"depth":2},{"title":"Part 1: RL in 60 Seconds ⏱️","local":"part-1-rl-in-60-seconds-","sections":[],"depth":2},{"title":"Part 2: The Problem with Traditional RL 😤","local":"part-2-the-problem-with-traditional-rl-","sections":[{"title":"🤔 Why Can’t We Just Use OpenAI Gym?","local":"-why-cant-we-just-use-openai-gym","sections":[],"depth":3},{"title":"💡 The OpenEnv Philosophy","local":"-the-openenv-philosophy","sections":[],"depth":3},{"title":"The Architecture","local":"the-architecture","sections":[],"depth":3}],"depth":2},{"title":"Part 3: Setup 🛠️","local":"part-3-setup-","sections":[],"depth":2},{"title":"Part 4: The OpenEnv Pattern 🏗️","local":"part-4-the-openenv-pattern-","sections":[{"title":"Every OpenEnv Environment Has 3 Components:","local":"every-openenv-environment-has-3-components","sections":[],"depth":3}],"depth":2},{"title":"Part 5: Example Integration - OpenSpiel 🎮","local":"part-5-example-integration---openspiel-","sections":[{"title":"What is OpenSpiel?","local":"what-is-openspiel","sections":[],"depth":3},{"title":"OpenEnv’s Integration","local":"openenvs-integration","sections":[],"depth":3},{"title":"Type-Safe Models","local":"type-safe-models","sections":[],"depth":3},{"title":"How the Client Works","local":"how-the-client-works","sections":[],"depth":3}],"depth":2},{"title":"Part 6: Using Real OpenSpiel 🎮","local":"part-6-using-real-openspiel-","sections":[{"title":"Now let’s USE a production environment!","local":"now-lets-use-a-production-environment","sections":[],"depth":3},{"title":"The Game: Catch 🔴🏓","local":"the-game-catch-","sections":[],"depth":3}],"depth":2},{"title":"Part 7: Four Policies 🤖","local":"part-7-four-policies-","sections":[],"depth":2},{"title":"Part 8: Policy Competition! 🏆","local":"part-8-policy-competition-","sections":[],"depth":2},{"title":"Part 9: Switching to Other Games 🎮","local":"part-9-switching-to-other-games-","sections":[{"title":"What We Just Used: Real OpenSpiel! 🎉","local":"what-we-just-used-real-openspiel-","sections":[],"depth":3},{"title":"🎮 6 Games Available - Same Interface!","local":"-6-games-available---same-interface","sections":[],"depth":3},{"title":"Try Another Game (Optional):","local":"try-another-game-optional","sections":[],"depth":3}],"depth":2},{"title":"Part 10: Create Your Own Integration 🛠️","local":"part-10-create-your-own-integration-","sections":[{"title":"The 5-Step Pattern","local":"the-5-step-pattern","sections":[],"depth":3},{"title":"Step 1: Define Types ( models.py )","local":"step-1-define-types--modelspy-","sections":[],"depth":3},{"title":"Step 2: Implement Environment ( server/environment.py )","local":"step-2-implement-environment--serverenvironmentpy-","sections":[],"depth":3},{"title":"Step 3: Create Client ( client.py )","local":"step-3-create-client--clientpy-","sections":[],"depth":3},{"title":"Step 4: Create Server ( server/app.py )","local":"step-4-create-server--serverapppy-","sections":[],"depth":3},{"title":"Step 5: Dockerize ( server/Dockerfile )","local":"step-5-dockerize--serverdockerfile-","sections":[],"depth":3},{"title":"🎓 Examples to Study","local":"-examples-to-study","sections":[],"depth":3}],"depth":2},{"title":"🎓 Summary: Your Journey","local":"-summary-your-journey","sections":[{"title":"What You Learned","local":"what-you-learned","sections":[],"depth":3},{"title":"📚 Concepts","local":"-concepts","sections":[],"depth":3},{"title":"🛠️ Skills","local":"-skills","sections":[],"depth":3},{"title":"OpenEnv vs Traditional RL","local":"openenv-vs-traditional-rl","sections":[],"depth":3}],"depth":2},{"title":"📚 Resources","local":"-resources","sections":[{"title":"🔗 Essential Links","local":"-essential-links","sections":[],"depth":3},{"title":"📖 Documentation Deep Dives","local":"-documentation-deep-dives","sections":[],"depth":3},{"title":"🎓 Community & Support","local":"-community--support","sections":[],"depth":3},{"title":"🌈 What’s Next?","local":"-whats-next","sections":[],"depth":3}],"depth":2}],"depth":1}';function Ua(sM){return la(()=>{new URLSearchParams(window.location.search).get("fw")}),[]}class wa extends sa{constructor(b){super(),Ta(this,b,Ua,ea,LU,{})}}export{wa as component}; | |
Xet Storage Details
- Size:
- 173 kB
- Xet hash:
- c583ab199fa0a8d180feb9f9ede7b5a9d2d978b917f9481281f6a45cfbafe31f
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.