<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>All Posts - Ateon</title><link>https://ateon.ch/posts/</link><description>All Posts | Ateon</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Fri, 29 May 2026 19:00:00 +0200</lastBuildDate><atom:link href="https://ateon.ch/posts/" rel="self" type="application/rss+xml"/><item><title>Formally Verified ASN.1 Encoders and Decoders</title><link>https://ateon.ch/posts/formally-verified-asn1/</link><pubDate>Fri, 29 May 2026 19:00:00 +0200</pubDate><author>Luca Schafroth</author><guid>https://ateon.ch/posts/formally-verified-asn1/</guid><description><![CDATA[<p>When a satellite sends telemetry data to a ground station, both sides need to agree on exactly how that data is structured in binary. The same goes for network protocols, aircraft systems, and anything else where machines exchange precisely formatted messages. Get the encoding wrong and you get garbage. Get the decoding wrong and you may silently recover incorrect data.</p>
<h2 id="why-does-asn1-need-formal-verification">Why Does ASN.1 Need Formal Verification?</h2>
<p>In safety-critical systems, bugs in communication protocol implementations can produce incorrect encodings or silent decoding errors that a finite test suite may not catch. <strong>ASN.1</strong> (Abstract Syntax Notation One) is an international standard for describing data structures independently of any programming language or platform.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> You define your types once (integers, strings, sequences, enumerations). A separate set of encoding rules then determines how those types map to bytes on the wire.</p>
<p>A simple definition looks like this:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-asn1"><span class="code-title has-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i>
                <span class="code-filename">ASN1</span>
            </span>
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Temperature ::= INTEGER (0..100)</span></span></code></pre></div></div><p>This says <code>Temperature</code> is an integer constrained to the range 0–100. The encoding rules then pack that value into as few bits as possible.</p>
<p>The encoding rules used in this thesis are <strong>uPER</strong> (Unaligned Packed Encoding Rules). uPER is compact, which makes it a natural fit for embedded systems and satellite communication where bandwidth is limited. The European Space Agency uses ASN.1 with uPER for telemetry and telecommand data between spacecraft and ground stations.</p>
<h2 id="what-is-asn1scc">What Is ASN1SCC?</h2>
<p>Writing encoders and decoders by hand for every type in a specification is tedious and error-prone. The ESA developed <a href="https://github.com/esa/asn1scc" target="_blank" rel="noopener noreffer ">ASN1SCC</a> to automate this: an open-source compiler that takes an ASN.1 specification as input and generates the corresponding encoding and decoding code.<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> It supports C, Ada, and Scala, with a Python backend under active development.</p>
<p>Given the <code>Temperature</code> definition above, ASN1SCC generates a Python class with <code>encode</code> and <code>decode</code> methods. Using them looks roughly like this:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-python"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">encoder</span> <span class="o">=</span> <span class="n">UPEREncoder</span><span class="o">.</span><span class="n">of_size</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">val</span> <span class="o">=</span> <span class="n">Temperature</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">val</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">encoder</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">data</span> <span class="o">=</span> <span class="n">encoder</span><span class="o">.</span><span class="n">get_bitstream_buffer</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">decoder</span> <span class="o">=</span> <span class="n">UPERDecoder</span><span class="o">.</span><span class="n">from_buffer</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">result</span> <span class="o">=</span> <span class="n">Temperature</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">decoder</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Is result == val?</span></span></span></code></pre></div></div><p>The question my thesis set out to answer: can we <strong>prove</strong> that <code>result == val</code> holds for every valid input, not just the ones we happened to test?</p>
<h2 id="why-testing-alone-isnt-enough">Why Testing Alone Isn&rsquo;t Enough</h2>
<p>Tests are the standard answer. Write inputs, check outputs, add edge cases. Done carefully, this catches a lot of bugs.</p>
<p>But tests only cover the cases you thought to write. A <code>Temperature</code> value of 42 passes. What about 127? What about 128, where the bit-packing crosses a byte boundary? What about the exact edges of the constraint range? What about a complex nested structure with a dozen fields, where the encoder for each field must leave the stream in exactly the right state for the next one?</p>
<div class="details admonition info">
    <div class="details-summary admonition-title">
        <i class="icon fas fa-info" aria-hidden="true"></i>Automated testing variants<i class="details-icon fas fa-angle-right" aria-hidden="true"></i>
    </div>
    <div class="details-content">
        <div class="admonition-content"><p>Testing has more sophisticated variants. <strong>Symbolic execution</strong> (e.g., KLEE) treats inputs as symbolic variables and automatically generates concrete inputs to cover different code paths, which is far more systematic than writing tests by hand. <strong>Fuzzing</strong> generates large volumes of random or mutation-based inputs and can find bugs that deterministic test suites miss entirely.</p>
<p>Both techniques close some of the coverage gap. But they still explore a finite set of execution paths. For programs with unbounded inputs or complex loop structures, neither can guarantee that every case has been covered. Formal verification closes that gap.</p>
</div>
    </div>
</div>
<p>Formal verification is a different game. You write a mathematical statement about what the code must do for <em>all</em> inputs, and a tool proves or disproves it automatically. No enumeration of cases.</p>
<h2 id="what-i-set-out-to-prove">What I Set Out to Prove</h2>
<p>The property I focused on is <strong>round-trip correctness</strong>:</p>
<blockquote>
<p>For all valid inputs, decoding the output of an encoder recovers the original value.</p>
</blockquote>
<p>Formally: $\forall x . decode(encode(x)) = x$</p>
<p>The proof is scoped to valid inputs: the precondition requires constraint-satisfying values on the encoder side and a well-formed buffer on the decoder side. It says nothing about how the decoder handles malformed input from an untrusted source. But within that scope it gives a precise, unconditional correctness statement: the encoder cannot silently corrupt a value, and the decoder cannot misread what the encoder wrote.</p>
<h2 id="nagini-formal-verification-for-python">Nagini: Formal Verification for Python</h2>
<p>The verifier I used is <a href="https://github.com/marcoeilers/nagini" target="_blank" rel="noopener noreffer ">Nagini</a>, a static analysis tool for Python developed by Dr. Marco Eilers at ETH Zurich.<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> Nagini lets you annotate Python functions with preconditions and postconditions, then uses an SMT solver to prove those statements hold for every possible execution. Under the hood it translates Python to Viper, an intermediate verification language.<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup></p>
<p>An annotated encode function looks like this:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-python"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">encode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">codec</span><span class="p">:</span> <span class="n">UPEREncoder</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">Requires</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">is_constraint_valid</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">    <span class="n">Ensures</span><span class="p">(</span><span class="n">codec</span><span class="o">.</span><span class="n">segments</span> <span class="o">==</span> <span class="n">Old</span><span class="p">(</span><span class="n">codec</span><span class="o">.</span><span class="n">segments</span><span class="p">)</span> <span class="o">+</span> <span class="n">segments_of</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># ... implementation ...</span></span></span></code></pre></div></div><p><code>Requires</code> is the precondition: the value being encoded must satisfy its constraints. <code>Ensures</code> is the postcondition: the encoder&rsquo;s state has been extended by exactly the segments representing this value. Once Nagini accepts this, no test needs to cover that contract. It holds unconditionally.</p>
<h2 id="the-segment-abstraction">The Segment Abstraction</h2>
<p>Encoding writes bits into a shared byte buffer. A single write can span two bytes, and you need to reason precisely about which bits changed and which didn&rsquo;t. Tracking this at the bit level throughout the whole proof would be unmanageable.</p>
<p>The approach I used is a three-layer architecture. The bottom two layers handle actual bit manipulation: individual bits within a byte, then multi-bit writes across the full buffer. Above those sits a <strong>segment abstraction</strong> used purely for verification. Instead of tracking which bits changed, each write is recorded as a <code>(value, length)</code> pair called a segment.</p>
<div class="mermaid" id="id-1">graph TB
    A[&#34;Segment abstraction&lt;br/&gt;Encoders and decoders reason at this level&#34;]
    B[&#34;Byte-sequence layer&lt;br/&gt;Tracks bit writes across the buffer&#34;]
    C[&#34;Bit-level layer&lt;br/&gt;Individual bit read/write within a byte&#34;]
    A --- B --- C</div>
<p>Once the bottom layers are proved correct, the segment abstraction guarantees that the sequence of segments corresponds exactly to the buffer contents. Encoder and decoder proofs then work entirely with segments, without bit arithmetic. That separation is what makes the round-trip proofs tractable, and it distinguishes this approach from the bit-list intermediate representation used in the prior Scala verification work.<sup id="fnref:5"><a href="#fn:5" class="footnote-ref" role="doc-noteref">5</a></sup></p>
<p>I&rsquo;ll cover the segment abstraction and compositional proof structure in more detail in a follow-up post.</p>
<h2 id="what-was-formally-verified">What Was Formally Verified</h2>
<p>The first component verified was <code>BitStream</code>, the core data structure shared by all generated codecs. The verification establishes absence of runtime errors (index out-of-bounds, overflow) and full functional correctness of all read and write operations: each written value is correctly retrieved by a subsequent read, and previously written data is unchanged. Everything else rests on this.</p>
<p>Building on <code>BitStream</code>, six ASN.1 types were proved to have round-trip correctness under uPER:</p>
<ul>
<li><code>BOOLEAN</code></li>
<li><code>NULL</code></li>
<li><code>ENUMERATED</code></li>
<li><code>INTEGER</code> (constrained range)</li>
<li><code>OCTET STRING</code> (fixed size)</li>
<li><code>SEQUENCE</code> (with fixed-size, non-optional fields)</li>
</ul>
<p>Types like <code>SEQUENCE OF</code>, <code>CHOICE</code>, <code>BIT STRING</code>, and <code>REAL</code> were not verified. Most follow the same proof pattern and are primarily a matter of implementing type-specific auxiliary functions. <code>REAL</code> is the exception: it requires further development in Nagini&rsquo;s floating-point support before it can be tackled at the codec level.</p>
<h2 id="the-cost-annotation-overhead">The Cost: Annotation Overhead</h2>
<p>Formal verification is not free. Proofs require writing specifications alongside the implementation. Across the verified runtime files, annotation lines account for <strong>39.9%</strong> of the codebase: 1,636 specification lines alongside 2,461 lines of implementation.</p>
<p>The distribution is uneven by design. <code>bitstream.py</code>, which establishes the segment abstraction at the byte-sequence level, has more specification than implementation (68% annotation overhead). The encoder and decoder, working at the segment level rather than at the bit level, need far less: 12.6% and 13.5% respectively. The annotation burden concentrates at the foundation, so the higher-level proofs stay comparatively lightweight.</p>
<p><code>segment.py</code> and <code>verification.py</code> consist entirely of specification code with no runtime counterparts; they exist solely to support the proof.</p>
<p>The generated data classes sit at 54% specification, since each class needs its own postconditions and helper lemmas. That&rsquo;s the cost of annotating code you didn&rsquo;t write.</p>
<h2 id="two-bugs-found-before-running-the-prover">Two Bugs Found Before Running the Prover</h2>
<p>Writing formal specifications sometimes finds bugs before the prover even runs. Precisely stating what the code <em>should</em> do exposes gaps between that and what it <em>actually</em> does. Two bugs turned up in the ASN1SCC Python backend this way:</p>
<ol>
<li>The <code>is_constraint_valid</code> check for <code>INTEGER</code> was missing the lower bound of zero, accepting negative values as valid.</li>
<li>The <code>is_constraint_valid</code> check for <code>OCTET STRING</code> did not enforce the fixed-size constraint, accepting arrays of any length.</li>
</ol>
<p>Both were caught just from writing the specification, before running a single proof.</p>
<h2 id="how-i-extended-nagini">How I Extended Nagini</h2>
<p>The verification also required extending Nagini to handle Python features it couldn&rsquo;t verify before:</p>
<ul>
<li><code>bytearray</code>: a mutable heap-allocated type, modelled as a <code>Seq[Int]</code> in Viper with a permission predicate governing access, plus a pure <code>PByteSeq</code> counterpart for use in specifications</li>
<li>Shift operators (<code>&lt;&lt;</code> and <code>&gt;&gt;</code>): encoded via integer arithmetic, since SMT integers don&rsquo;t support bitwise shifts directly; left shift by <em>k</em> becomes multiplication by 2^k, resolved through a case distinction over the shift amount</li>
<li>Dataclasses: <code>@dataclass</code>-decorated classes with implicit <code>__init__</code>, supporting frozen and non-frozen forms and factory defaults</li>
<li><code>IntEnum</code>: integer-backed enumerations, encoded with boxing/unboxing functions that enforce the set of valid values at the type level</li>
</ul>
<p>Beyond new features, six crashes and three soundness issues in Nagini were identified and reported to the <a href="https://github.com/marcoeilers/nagini/issues" target="_blank" rel="noopener noreffer ">issue tracker</a>, each with a minimal reproducing test case. All were subsequently fixed. One soundness bug was particularly subtle: because a Python integer subclass satisfies <code>A(5) == 5</code>, Nagini was misled into accepting the trivially false assertion <code>assert 2 == 1</code> as valid, which I found while writing tests that were supposed to fail.</p>
<p>I&rsquo;ll cover these extensions in more detail in a follow-up post.</p>
<h2 id="artifacts-and-prior-work">Artifacts and Prior Work</h2>
<p>The full thesis is available on the <a href="https://www.pm.inf.ethz.ch/education/student-projects/completedprojects.html" target="_blank" rel="noopener noreffer ">completed projects page</a> of the Programming Methodology Group at ETH Zurich.
Changes to Nagini have been committed to the <a href="https://github.com/marcoeilers/nagini" target="_blank" rel="noopener noreffer ">Nagini repository</a> directly.
ASN1SCC is open source on <a href="https://github.com/esa/asn1scc" target="_blank" rel="noopener noreffer ">GitHub</a>.</p>
<p>This work builds on a prior project that applied the same round-trip verification approach to ASN1SCC&rsquo;s Scala backend.<sup id="fnref1:5"><a href="#fn:5" class="footnote-ref" role="doc-noteref">5</a></sup> The aim was to show the same correctness class is achievable in Python.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>ITU-T, <em>X.680: Information Technology – Abstract Syntax Notation One (ASN.1)</em>, 2021. <a href="https://www.itu.int/rec/T-REC-X.680/" target="_blank" rel="noopener noreffer ">https://www.itu.int/rec/T-REC-X.680/</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>G. Mamais, T. Tsiodras, D. Lesens, M. Perrotin, &ldquo;An ASN.1 compiler for embedded/space systems,&rdquo; <em>ERTS 2012</em>, Toulouse, France. <a href="https://hal.science/hal-02263447" target="_blank" rel="noopener noreffer ">https://hal.science/hal-02263447</a>&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>M. Eilers, P. Müller, &ldquo;Nagini: A Static Verifier for Python,&rdquo; <em>Computer Aided Verification (CAV)</em>, 2018, pp. 596–603.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p>P. Müller, M. Schwerhoff, A. J. Summers, &ldquo;Viper: A Verification Infrastructure for Permission-Based Reasoning,&rdquo; <em>VMCAI</em>, 2016. <a href="https://viper.ethz.ch" target="_blank" rel="noopener noreffer ">https://viper.ethz.ch</a>&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:5">
<p>M. Bucev, S. Chassot, S. Felix, F. Schramka, V. Kunčak, &ldquo;Formally Verifiable Generated ASN.1/ACN Encoders and Decoders: A Case Study,&rdquo; arXiv:2412.07235, 2024. <a href="https://arxiv.org/abs/2412.07235" target="_blank" rel="noopener noreffer ">https://arxiv.org/abs/2412.07235</a>&#160;<a href="#fnref:5" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref1:5" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>]]></description></item><item><title>Bundling a Game Made with MonoGame</title><link>https://ateon.ch/posts/monogame_bundle/</link><pubDate>Thu, 05 Jun 2025 21:24:00 +0200</pubDate><author>Luca Schafroth</author><guid>https://ateon.ch/posts/monogame_bundle/</guid><description><![CDATA[<p>While developing <strong>Vulcard</strong> for this year&rsquo;s iteration of the <a href="https://gtc.inf.ethz.ch/education/game-programming-laboratory/previous-years/2025.html" target="_blank" rel="noopener noreffer ">Game Programming Lab</a> at ETH Zurich, we wanted to integrate the Steam API and package the game for multiple platforms. This process came with a few unexpected hurdles.</p>
<p>In this post, I&rsquo;ll walk through the complete solution we ended up using. If you&rsquo;re looking to publish a MonoGame project on Steam, this might save you some time.</p>
<div class="details admonition tip">
    <div class="details-summary admonition-title">
        <i class="icon far fa-lightbulb" aria-hidden="true"></i>What&#39;s Monogame?<i class="details-icon fas fa-angle-right" aria-hidden="true"></i>
    </div>
    <div class="details-content">
        <div class="admonition-content"><a href="https://monogame.net/" target="_blank" rel="noopener noreffer ">MonoGame</a>  is a cross-platform .NET framework for game development. It has for example been used to develop Stardew Valley.</div>
    </div>
</div>
<h2 id="general-setup">General Setup</h2>
<p>I assume you already have a working .NET 6+ (MonoGame) project and the corresponding SDK installed. You’ll also need a <a href="https://partner.steamgames.com/" target="_blank" rel="noopener noreffer ">Steamworks</a> developer account to access the Steamworks SDK.</p>
<p>To make platform-specific builds easier, define platform detection constants in your <code>.csproj</code> file:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-xml"><span class="code-title has-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i>
                <span class="code-filename">Vulcard.csproj</span>
            </span>
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt">&lt;PropertyGroup&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;IsWindows</span> <span class="na">Condition=</span><span class="s">&#34;&#39;$(RuntimeIdentifier)&#39; == &#39;win-x64&#39; or (&#39;$(RuntimeIdentifier)&#39; == &#39;&#39; and $([MSBuild]::IsOSPlatform(&#39;Windows&#39;)))&#34;</span><span class="nt">&gt;</span>true<span class="nt">&lt;/IsWindows&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;IsOSX</span> <span class="na">Condition=</span><span class="s">&#34;&#39;$(RuntimeIdentifier)&#39; == &#39;osx-x64&#39; or (&#39;$(RuntimeIdentifier)&#39; == &#39;&#39; and $([MSBuild]::IsOSPlatform(&#39;OSX&#39;)))&#34;</span><span class="nt">&gt;</span>true<span class="nt">&lt;/IsOSX&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;IsLinux</span> <span class="na">Condition=</span><span class="s">&#34;&#39;$(RuntimeIdentifier)&#39; == &#39;linux-x64&#39; or (&#39;$(RuntimeIdentifier)&#39; == &#39;&#39; and $([MSBuild]::IsOSPlatform(&#39;Linux&#39;)))&#34;</span><span class="nt">&gt;</span>true<span class="nt">&lt;/IsLinux&gt;</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;IsWindows</span> <span class="na">Condition=</span><span class="s">&#34;&#39;$(IsWindows)&#39; == &#39;&#39;&#34;</span><span class="nt">&gt;</span>false<span class="nt">&lt;/IsWindows&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;IsOSX</span> <span class="na">Condition=</span><span class="s">&#34;&#39;$(IsOSX)&#39; == &#39;&#39;&#34;</span><span class="nt">&gt;</span>false<span class="nt">&lt;/IsOSX&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;IsLinux</span> <span class="na">Condition=</span><span class="s">&#34;&#39;$(IsLinux)&#39; == &#39;&#39;&#34;</span><span class="nt">&gt;</span>false<span class="nt">&lt;/IsLinux&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/PropertyGroup&gt;</span></span></span></code></pre></div></div><h2 id="add-steamworks-dependencies">Add Steamworks Dependencies</h2>
<p>Download the Facepunch.Steamworks library directly from the <a href="https://github.com/Facepunch/Facepunch.Steamworks/releases/" target="_blank" rel="noopener noreffer ">GitHub releases page</a> and extract the contents of the <code>net6.0</code> folder into a new folder in your project root called <code>Steamworks</code>.</p>
<p>Also, download the official Steamworks SDK directly from <a href="https://partner.steamgames.com/downloads/list" target="_blank" rel="noopener noreffer ">Steamworks</a>. As of writing, SDK version 1.61 works with the latest release of Facepunch.Steamworks. Copy the redistributable binaries (steam_api64.dll, libsteam_api.so, etc.) into the same Steamworks folder.</p>
<p>Your <code>Steamworks/</code> folder should now include:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-txt"><span class="code-title has-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i>
                <span class="code-filename">Steamworks/</span>
            </span>
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">Facepunch.Steamworks.Posix.deps.json
</span></span><span class="line"><span class="cl">Facepunch.Steamworks.Posix.dll
</span></span><span class="line"><span class="cl">Facepunch.Steamworks.Posix.pdb
</span></span><span class="line"><span class="cl">Facepunch.Steamworks.Posix.xml
</span></span><span class="line"><span class="cl">Facepunch.Steamworks.Win64.deps.json
</span></span><span class="line"><span class="cl">Facepunch.Steamworks.Win64.dll
</span></span><span class="line"><span class="cl">Facepunch.Steamworks.Win64.pdb
</span></span><span class="line"><span class="cl">Facepunch.Steamworks.Win64.xml
</span></span><span class="line"><span class="cl">libsteam_api.dylib
</span></span><span class="line"><span class="cl">libsteam_api.so
</span></span><span class="line"><span class="cl">steam_api64.dll</span></span></code></pre></div></div><div class="details admonition tip">
    <div class="details-summary admonition-title">
        <i class="icon far fa-lightbulb" aria-hidden="true"></i>32-bit Support<i class="details-icon fas fa-angle-right" aria-hidden="true"></i>
    </div>
    <div class="details-content">
        <div class="admonition-content">To support 32-bit Windows systems, you’ll need to include the appropriate 32-bit versions of the Steam libraries as well.</div>
    </div>
</div>
<p>Update the <code>.csproj</code> to reference the Facepunch.Steamworks and native libraries for the correct platform:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-xml"><span class="code-title has-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i>
                <span class="code-filename">Vulcard.csproj</span>
            </span>
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt">&lt;ItemGroup&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="c">&lt;!-- Reference Facepunch.Steamworks --&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;Reference</span> <span class="na">Include=</span><span class="s">&#34;Facepunch.Steamworks, Version=2.4.1, Culture=neutral, processorArchitecture=MSIL&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;SpecificVersion&gt;</span>False<span class="nt">&lt;/SpecificVersion&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;HintPath</span> <span class="na">Condition=</span><span class="s">&#34;$(IsWindows)&#34;</span><span class="nt">&gt;</span>Steamworks/Facepunch.Steamworks.Win64.dll<span class="nt">&lt;/HintPath&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;HintPath</span> <span class="na">Condition=</span><span class="s">&#34;$(IsOSX) or $(IsLinux)&#34;</span><span class="nt">&gt;</span>Steamworks/Facepunch.Steamworks.Posix.dll<span class="nt">&lt;/HintPath&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;CopyToOutputDirectory&gt;</span>Always<span class="nt">&lt;/CopyToOutputDirectory&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/Reference&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c">&lt;!-- Include native Steamworks libaries --&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;Content</span> <span class="na">Include=</span><span class="s">&#34;Steamworks/steam_api64.dll&#34;</span> <span class="na">Condition=</span><span class="s">&#34;$(IsWindows)&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;Link&gt;</span>steam_api64.dll<span class="nt">&lt;/Link&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;CopyToOutputDirectory&gt;</span>Always<span class="nt">&lt;/CopyToOutputDirectory&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/Content&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;Content</span> <span class="na">Include=</span><span class="s">&#34;Steamworks/libsteam_api.dylib&#34;</span> <span class="na">Condition=</span><span class="s">&#34;$(IsOSX)&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;Link&gt;</span>Lib/libsteam_api.dylib<span class="nt">&lt;/Link&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;CopyToOutputDirectory&gt;</span>Always<span class="nt">&lt;/CopyToOutputDirectory&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/Content&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;Content</span> <span class="na">Include=</span><span class="s">&#34;Steamworks/libsteam_api.so&#34;</span> <span class="na">Condition=</span><span class="s">&#34;$(IsLinux)&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;Link&gt;</span>libsteam_api.so<span class="nt">&lt;/Link&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;CopyToOutputDirectory&gt;</span>Always<span class="nt">&lt;/CopyToOutputDirectory&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/Content&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/ItemGroup&gt;</span></span></span></code></pre></div></div><div class="details admonition note open">
    <div class="details-summary admonition-title">
        <i class="icon far fa-pen-to-square" aria-hidden="true"></i>libsteam_api.dylib<i class="details-icon fas fa-angle-right" aria-hidden="true"></i>
    </div>
    <div class="details-content">
        <div class="admonition-content"><p>The native steam library for macOS <code>libsteam_api.dylib</code> is copied directly into the <code>Lib</code> folder to conform with the app bundle structure for macOS.</p>
<p>This might mess with your setup if you are using macOS for development. If you know of a good way to force NetBeauty to automatically copy the file to the <code>Lib</code> folder during bundling, let me know.</p>
</div>
    </div>
</div>
<p>If everything is working, you can initialize the Steam API in your code and check the connection.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-cs"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cs" data-lang="cs"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">Initialize</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Steamworks</span><span class="p">.</span><span class="n">SteamClient</span><span class="p">.</span><span class="n">Init</span><span class="p">(</span><span class="m">480</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="n">playername</span> <span class="p">=</span> <span class="n">Steamworks</span><span class="p">.</span><span class="n">SteamClient</span><span class="p">.</span><span class="n">Name</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Debug</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&#34;{0}&#34;</span><span class="p">,</span> <span class="n">e</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><div class="details admonition warning open">
    <div class="details-summary admonition-title">
        <i class="icon fas fa-exclamation" aria-hidden="true"></i>App ID<i class="details-icon fas fa-angle-right" aria-hidden="true"></i>
    </div>
    <div class="details-content">
        <div class="admonition-content">Replace <code>480</code> with your actual Steam App ID for a release. Facepunch.Steamworks also doesn&rsquo;t require a <code>steam_appid.txt</code> file.</div>
    </div>
</div>
<h2 id="bundling-windows--linux">Bundling Windows &amp; Linux</h2>
<p>Download <a href="https://github.com/Ellpeck/GameBundle" target="_blank" rel="noopener noreffer ">GameBundle</a>. This neat tool greatly simplifies the bundling process and provides a clean looking folder structure by using <a href="https://github.com/nulastudio/NetBeauty2" target="_blank" rel="noopener noreffer ">NetBeauty</a> internally.</p>
<p>And that is it. You can now use the Steam API and bundle your game for Windows and Linux:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-bash"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">gamebundle -wl -z --mg
</span></span><span class="line"><span class="cl"><span class="c1"># -w: Build for Windows</span>
</span></span><span class="line"><span class="cl"><span class="c1"># -l: Build for Linux</span>
</span></span><span class="line"><span class="cl"><span class="c1"># -z: Zip output</span>
</span></span><span class="line"><span class="cl"><span class="c1"># --mg: Don&#39;t move MonoGame&#39;s native libraries to the Lib folder</span></span></span></code></pre></div></div><p>Note that Linux users will need to add the permissions to execute the game.</p>
<h2 id="bundling-macos">Bundling macOS</h2>
<p>Bundling for macOS is a bit more involved and additionally requires a property list file and a separate icon.</p>
<p>Convert your existing game icon to the <code>icns</code> format and store the new file under <code>Icon.icns</code> directly in the root. Then create a new file called <code>Info.plist</code> also in the project root.</p>
<p>Add the following content to the <code>Info.plist</code>. Replace <code>MyApp</code> with the name of your application and <code>com.example.MyApp</code> with your identifier.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-xml"><span class="code-title has-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i>
                <span class="code-filename">Info.plist</span>
            </span>
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="cp">&lt;!DOCTYPE plist PUBLIC &#34;-//Apple//DTD PLIST 1.0//EN&#34; &#34;http://www.apple.com/DTDs/PropertyList-1.0.dtd&#34;&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;plist</span> <span class="na">version=</span><span class="s">&#34;1.0&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;dict&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;key&gt;</span>CFBundleIconFile<span class="nt">&lt;/key&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;string&gt;</span>Icon<span class="nt">&lt;/string&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;key&gt;</span>CFBundleName<span class="nt">&lt;/key&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;string&gt;</span>MyApp<span class="nt">&lt;/string&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;key&gt;</span>CFBundleIdentifier<span class="nt">&lt;/key&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;string&gt;</span>com.example.MyApp<span class="nt">&lt;/string&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;key&gt;</span>CFBundlePackageType<span class="nt">&lt;/key&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;string&gt;</span>APPL<span class="nt">&lt;/string&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;key&gt;</span>CFBundleVersion<span class="nt">&lt;/key&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;string&gt;</span>1.0<span class="nt">&lt;/string&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;key&gt;</span>CFBundleShortVersionString<span class="nt">&lt;/key&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;string&gt;</span>1.0<span class="nt">&lt;/string&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/dict&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/plist&gt;</span></span></span></code></pre></div></div><p>Finally, adjust your <code>.csproj</code> to include them during the build for macOS:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-xml"><span class="code-title has-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i>
                <span class="code-filename">Vulcard.csproj</span>
            </span>
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt">&lt;ItemGroup</span> <span class="na">Condition=</span><span class="s">&#34;$(IsOSX)&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;Content</span> <span class="na">Include=</span><span class="s">&#34;./Info.plist&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;CopyToOutputDirectory&gt;</span>Always<span class="nt">&lt;/CopyToOutputDirectory&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/Content&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;Content</span> <span class="na">Include=</span><span class="s">&#34;./Icon.icns&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;CopyToOutputDirectory&gt;</span>Always<span class="nt">&lt;/CopyToOutputDirectory&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/Content&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/ItemGroup&gt;</span></span></span></code></pre></div></div><p>Now you can also bundle your game for macOS again using GameBundle.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-bash"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">gamebundle -m -bz --mg --nbeauty2
</span></span><span class="line"><span class="cl"><span class="c1"># -m: Bundle for macOS</span>
</span></span><span class="line"><span class="cl"><span class="c1"># -b: Output correct structure and create app bundle for macOS</span>
</span></span><span class="line"><span class="cl"><span class="c1"># -z: Zip output</span>
</span></span><span class="line"><span class="cl"><span class="c1"># --mg: Don&#39;t move MonoGame&#39;s native libraries to the Lib folder</span>
</span></span><span class="line"><span class="cl"><span class="c1"># --nbeauty2: Use NetBeauty2 instead of NetCoreBeauty</span></span></span></code></pre></div></div><div class="details admonition info">
    <div class="details-summary admonition-title">
        <i class="icon fas fa-info" aria-hidden="true"></i>Why --nbeauty2?<i class="details-icon fas fa-angle-right" aria-hidden="true"></i>
    </div>
    <div class="details-content">
        <div class="admonition-content"><p>The .Net version I used (8.0.410) does not have a patched .Net SDK for macOS in NetCoreBeauty.</p>
<p>NetBeauty2 uses a different setup, which works in that case. However, there are other drawbacks with NetBeauty2.</p>
</div>
    </div>
</div>
<div class="details admonition warning">
    <div class="details-summary admonition-title">
        <i class="icon fas fa-exclamation" aria-hidden="true"></i>Signing &amp; Notarization<i class="details-icon fas fa-angle-right" aria-hidden="true"></i>
    </div>
    <div class="details-content">
        <div class="admonition-content">The setup shown here does not include signing and notarizing the app, which is required by Apple if you want to distribute the app.</div>
    </div>
</div>
<h2 id="conclusion">Conclusion</h2>
<p>You can now use the Steamworks API in your .Net project and bundle it for Windows, Linux and macOS. Hope this saves you some time.</p>
<p>See the <a href="https://github.com/gewlar/monogame_example" target="_blank" rel="noopener noreffer ">github repository</a> for a basic setup that includes project structure, and configuration files.</p>
<div class="details admonition note">
    <div class="details-summary admonition-title">
        <i class="icon far fa-pen-to-square" aria-hidden="true"></i>Note<i class="details-icon fas fa-angle-right" aria-hidden="true"></i>
    </div>
    <div class="details-content">
        <div class="admonition-content">By the way you can find Vulcard on <a href="https://store.steampowered.com/app/3764530/Vulcard" target="_blank" rel="noopener noreffer ">Steam</a>.</div>
    </div>
</div>]]></description></item><item><title>Loading Sass files with Lit</title><link>https://ateon.ch/posts/lit-scss-loading/</link><pubDate>Mon, 18 Jul 2022 16:11:44 +0200</pubDate><author>Luca Schafroth</author><guid>https://ateon.ch/posts/lit-scss-loading/</guid><description><![CDATA[<p>Like <a href="https://polymer-library.polymer-project.org/" target="_blank" rel="noopener noreffer ">Polymer</a> before, <a href="https://lit.dev/" target="_blank" rel="noopener noreffer ">Lit-Element</a> uses javascript or typescript files for code, templates and styles by default, to enable the use of javascript variables. While this may be useful in some cases, personally I prefer having my style definitions in separate files mainly to benefit from <a href="https://sass-lang.com/" target="_blank" rel="noopener noreffer ">Sass</a>, but also the added benefit of editor assistance like highlighting and autocompletion. Fortunately this can be changed with a bundler like <a href="https://webpack.js.org/" target="_blank" rel="noopener noreffer ">Webpack</a>.</p>
<div class="details admonition tip">
    <div class="details-summary admonition-title">
        <i class="icon far fa-lightbulb" aria-hidden="true"></i>What is Lit?<i class="details-icon fas fa-angle-right" aria-hidden="true"></i>
    </div>
    <div class="details-content">
        <div class="admonition-content"><p>Lit Element is a <a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components" target="_blank" rel="noopener noreffer ">Web Component</a> library. It adds some useful boilerplate and typescript definitions on top of the Web Component standards.
A Web Component itself is simply a custom element like any other default html element. But they encapsulate their code and styling from the rest of the page, which makes them highly modular. In a way their job is similar to classes in object-oriented programming languages.</p>
<p>Many well known Libraries like <a href="https://angular.io/" target="_blank" rel="noopener noreffer ">Angular</a> or <a href="https://reactjs.org/" target="_blank" rel="noopener noreffer ">React</a> make heavy use of Web Components.</p>
</div>
    </div>
</div>
<h3 id="previous-setup">Previous Setup</h3>
<p>Previously with Polymer I used the <a href="https://github.com/superjose/polymer-css-loader" target="_blank" rel="noopener noreffer ">polymer-css-loader</a> alongside its requirements to import stylesheets in javascript modules.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-js"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">config</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="p">...,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">module</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">rules</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">...,</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">test</span><span class="o">:</span> <span class="sr">/\.css|\.s(c|a)ss$/</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">use</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="nx">babel</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">loader</span><span class="o">:</span> <span class="s1">&#39;polymer-css-loader&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">options</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nx">minify</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nx">url</span><span class="o">:</span> <span class="kc">false</span>
</span></span><span class="line"><span class="cl">          <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span> <span class="s1">&#39;extract-loader&#39;</span><span class="p">,</span> <span class="s1">&#39;css-loader&#39;</span><span class="p">,</span> <span class="s1">&#39;resolve-url-loader&#39;</span><span class="p">,</span><span class="s1">&#39;sass-loader?sourceMap&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">test</span><span class="o">:</span> <span class="sr">/\.(png|jpg|gif|svg)$/</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">use</span><span class="o">:</span> <span class="p">[{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">loader</span><span class="o">:</span> <span class="s1">&#39;url-loader&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">options</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nx">limit</span><span class="o">:</span> <span class="mi">10</span> <span class="o">*</span> <span class="mi">1024</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nx">outputPath</span><span class="o">:</span> <span class="s1">&#39;assets&#39;</span>
</span></span><span class="line"><span class="cl">          <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}]</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><p>There actually exists a continuation of it for lit elements called <a href="https://github.com/bennypowers/lit-css" target="_blank" rel="noopener noreffer ">lit-css-loader</a>. Unfortunately <a href="https://github.com/peerigon/extract-loader" target="_blank" rel="noopener noreffer ">extract-loader</a> seems to be broken in Webpack 5, especially when loading images from Sass files.</p>
<h3 id="new-setup">New Setup</h3>
<p>Instead the <a href="https://webpack.js.org/loaders/css-loader/" target="_blank" rel="noopener noreffer ">css-loader</a> can now be used on its own to export the stylesheets in the required format.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-js"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">config</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="p">...,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">module</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">rules</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">...,</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">test</span><span class="o">:</span> <span class="sr">/\.css|\.s(c|a)ss$/</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">use</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nx">loader</span><span class="o">:</span> <span class="s1">&#39;css-loader&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nx">options</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">              <span class="nx">esModule</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="nx">exportType</span><span class="o">:</span> <span class="s2">&#34;css-style-sheet&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="p">},</span>
</span></span><span class="line"><span class="cl">          <span class="s1">&#39;resolve-url-loader&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nx">loader</span><span class="o">:</span> <span class="s1">&#39;sass-loader&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nx">options</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">              <span class="nx">sourceMap</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="p">}]</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">test</span><span class="o">:</span> <span class="sr">/\.(png|jpg|gif|svg)$/</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;asset&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">parser</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">dataUrlCondition</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nx">maxSize</span><span class="o">:</span> <span class="mi">4</span> <span class="o">*</span> <span class="mi">1024</span> <span class="c1">// 4kb
</span></span></span><span class="line"><span class="cl">          <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="nx">generator</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">filename</span><span class="o">:</span> <span class="s1">&#39;assets/images/[name].[ext]&#39;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><p>Some details about the different loaders used:</p>
<ul>
<li><a href="https://www.npmjs.com/package/sass-loader" target="_blank" rel="noopener noreffer ">sass-loader</a> is needed to compile sass to pure css.</li>
<li>Webpack expects relative paths to be in relation to the root file. To fix this <a href="https://www.npmjs.com/package/resolve-url-loader" target="_blank" rel="noopener noreffer ">resolve-url-loader</a> re-writes those paths to correctly load files.</li>
<li>Then css-loader translates CSS to Javascript.</li>
<li>The url-loader to load images has now been replaced by the <a href="https://webpack.js.org/guides/asset-modules/" target="_blank" rel="noopener noreffer ">Asset Module</a> from Webpack 5. Images smaller than 4kb will be inlined, while larger images are stores as a separate file.</li>
</ul>
<p>Hopefully this quick summary will save you some time if you are working with Lit-Elements.</p>
<h3 id="additional-remarks">Additional remarks</h3>
<p>As the <a href="https://web.dev/css-module-scripts/" target="_blank" rel="noopener noreffer ">CSS Module Scripts</a> feature gets deployed to all browsers this setup might become simpler.</p>]]></description></item><item><title>Randomized Algorithms: Game Tree Evaluation</title><link>https://ateon.ch/posts/game_tree_evaluation/</link><pubDate>Sat, 09 Jul 2022 17:40:00 +0200</pubDate><author>Luca Schafroth</author><guid>https://ateon.ch/posts/game_tree_evaluation/</guid><description><![CDATA[<p>Imagine you are playing a game of TicTacToe against your friend. Obviously you want to find an ideal strategy to increase your chances of winning.
How can you determine your next move?</p>
<h3 id="introduction">Introduction</h3>
<p>Let us start by labeling the fields of our grid. Each game is then a series of numbers chosen alternately by you and your opponent.
Instead of writing a list of all possible games that could be played, we draw them up as a tree:</p>
<figure>
    <svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink" width="316.671" height="266.925" viewBox="0 0 237.503 200.194" version="1.2" class="themed">
    <defs>
        <symbol overflow="visible" id="h">
            <path style="stroke:none" d="M4.563-3.172c0-.797-.047-1.594-.391-2.328-.469-.953-1.281-1.11-1.688-1.11-.593 0-1.328.266-1.734 1.188-.313.672-.36 1.453-.36 2.25 0 .735.032 1.64.438 2.39.438.798 1.156 1 1.64 1C3 .219 3.767.017 4.204-.936c.313-.688.36-1.454.36-2.235zM2.469 0c-.39 0-.969-.25-1.156-1.203-.11-.594-.11-1.5-.11-2.094 0-.625 0-1.281.094-1.828.187-1.172.922-1.266 1.172-1.266.328 0 .984.172 1.172 1.157.093.562.093 1.312.093 1.937 0 .75 0 1.422-.109 2.063C3.485-.297 2.922 0 2.469 0zm0 0"/>
        </symbol>
        <symbol overflow="visible" id="a">
            <path style="stroke:none" d="M2.234-6c0-.36.032-.469.813-.469h.25v-.312c-.344.031-1.125.031-1.5.031-.39 0-1.172 0-1.516-.031v.312h.25c.781 0 .813.11.813.469v5.219c0 .36-.032.469-.813.469h-.25V0c.344-.031 1.125-.031 1.5-.031.39 0 1.172 0 1.516.031v-.313h-.25c-.781 0-.813-.109-.813-.468zm0 0"/>
        </symbol>
        <symbol overflow="visible" id="c">
            <path style="stroke:none" d="m1.75-4.39-1.39.109v.312c.656 0 .734.063.734.547V-.75c0 .438-.11.438-.766.438V0c.313-.016.86-.031 1.094-.031.344 0 .687.015 1.031.031v-.313c-.656 0-.703-.046-.703-.437zm.047-1.72a.527.527 0 0 0-.531-.53c-.297 0-.516.265-.516.53a.52.52 0 0 0 .516.516c.28 0 .53-.203.53-.515zm0 0"/>
        </symbol>
        <symbol overflow="visible" id="d">
            <path style="stroke:none" d="M1.719-3.969H3.14v-.312H1.719V-6.11h-.25c-.016.828-.313 1.875-1.282 1.921v.22h.844v2.734c0 1.218.922 1.343 1.282 1.343.703 0 .984-.703.984-1.343v-.563h-.25v.547c0 .734-.297 1.11-.672 1.11-.656 0-.656-.907-.656-1.063zm0 0"/>
        </symbol>
        <symbol overflow="visible" id="e">
            <path style="stroke:none" d="M3.297-.75c.047.39.312.813.781.813.203 0 .813-.141.813-.954v-.546h-.25v.546c0 .579-.25.641-.36.641-.328 0-.36-.438-.36-.5v-1.984c0-.407 0-.797-.358-1.172a1.949 1.949 0 0 0-1.36-.531c-.812 0-1.5.453-1.5 1.109 0 .297.203.469.453.469a.448.448 0 0 0 .469-.454c0-.124-.063-.453-.516-.453.266-.359.75-.468 1.079-.468.484 0 1.046.39 1.046 1.28v.36c-.5.031-1.203.063-1.828.36-.734.343-.984.859-.984 1.296C.422-.14 1.375.11 2 .11c.656 0 1.11-.39 1.297-.859zm-.063-1.625v.984c0 .938-.718 1.282-1.156 1.282-.484 0-.89-.344-.89-.844 0-.547.406-1.375 2.046-1.422zm0 0"/>
        </symbol>
        <symbol overflow="visible" id="f">
            <path style="stroke:none" d="m1.75-6.89-1.422.109v.312c.688 0 .766.063.766.563V-.75c0 .438-.11.438-.766.438V0c.328-.016.86-.031 1.094-.031.25 0 .734.015 1.11.031v-.313c-.673 0-.782 0-.782-.437zm0 0"/>
        </symbol>
        <symbol overflow="visible" id="g">
            <path style="stroke:none" d="M5.781-6.75H.328v.313h.234c.766 0 .782.109.782.468V-.78c0 .36-.016.469-.782.469H.329V0c.344-.031 1.125-.031 1.5-.031.422 0 1.313 0 1.672.031v-.313h-.328c-.938 0-.938-.124-.938-.468V-3.22h.844c.953 0 1.063.313 1.063 1.156h.25v-2.624h-.25c0 .828-.11 1.156-1.063 1.156h-.844v-2.516c0-.328.016-.39.485-.39h1.187c1.485 0 1.735.546 1.89 1.921h.25zm0 0"/>
        </symbol>
        <symbol overflow="visible" id="b">
            <path style="stroke:none" d="M1.094-3.406V-.75c0 .438-.11.438-.782.438V0c.36-.016.86-.031 1.125-.031.266 0 .782.015 1.11.031v-.313c-.656 0-.766 0-.766-.437v-1.828c0-1.031.703-1.594 1.328-1.594.625 0 .735.547.735 1.11V-.75c0 .438-.11.438-.766.438V0a30.36 30.36 0 0 1 1.125-.031c.25 0 .766.015 1.11.031v-.313c-.516 0-.766 0-.782-.296V-2.5c0-.86 0-1.156-.297-1.516-.14-.171-.468-.375-1.046-.375-.735 0-1.188.438-1.47 1.047V-4.39l-1.405.11v.312c.703 0 .78.063.78.563zm0 0"/>
        </symbol>
        <symbol overflow="visible" id="i">
            <path style="stroke:none" d="M2.922-6.344c0-.25 0-.265-.235-.265-.609.64-1.484.64-1.796.64v.297c.187 0 .78 0 1.296-.25v5.14c0 .36-.03.47-.921.47H.937V0c.36-.031 1.22-.031 1.61-.031.406 0 1.265 0 1.61.031v-.313h-.313c-.89 0-.922-.109-.922-.468zm0 0"/>
        </symbol>
        <symbol overflow="visible" id="j">
            <path style="stroke:none" d="M1.906-.531A.524.524 0 1 0 .86-.515a.524.524 0 0 0 1.047-.016zm0 0"/>
        </symbol>
        <symbol overflow="visible" id="l">
            <path style="stroke:none" d="M1.625-4.531c-.469-.297-.5-.64-.5-.813 0-.593.64-1.015 1.344-1.015.719 0 1.36.515 1.36 1.234 0 .563-.392 1.031-.985 1.39zm1.438.937c.718-.36 1.203-.875 1.203-1.531 0-.922-.875-1.484-1.782-1.484-1 0-1.796.734-1.796 1.656 0 .187.015.625.437 1.094.11.125.469.359.719.53C1.266-3.03.422-2.483.422-1.5c0 1.047 1 1.719 2.047 1.719 1.125 0 2.062-.828 2.062-1.89 0-.36-.11-.798-.484-1.22-.188-.203-.344-.296-.984-.703zm-.985.422 1.219.766c.281.187.734.484.734 1.094 0 .734-.734 1.25-1.547 1.25C1.625-.063.906-.672.906-1.5c0-.578.328-1.203 1.172-1.672zm0 0"/>
        </symbol>
        <symbol overflow="visible" id="m">
            <path style="stroke:none" d="M4.719-6.047c.093-.11.093-.14.093-.344H2.406c-1.219 0-1.234-.125-1.281-.312H.891L.562-4.656h.235c.031-.172.125-.797.25-.907.078-.062.844-.062.984-.062h2.047c-.11.156-.89 1.234-1.11 1.563C2.079-2.72 1.75-1.345 1.75-.329c0 .094 0 .547.453.547s.453-.453.453-.547v-.5c0-.547.031-1.094.11-1.625.046-.235.187-1.094.625-1.703zm0 0"/>
        </symbol>
        <symbol overflow="visible" id="k">
            <path style="stroke:none" d="M4.64-3.688c0-.546-.25-.703-.437-.703-.25 0-.484.266-.484.485 0 .125.047.187.156.297.219.203.344.453.344.812 0 .422-.61 2.688-1.766 2.688-.515 0-.734-.344-.734-.86 0-.562.265-1.281.578-2.11.062-.171.11-.312.11-.5 0-.437-.313-.812-.813-.812C.672-4.39.28-2.953.28-2.859c0 .093.11.093.125.093.094 0 .11-.015.156-.171.297-1 .72-1.235 1-1.235.079 0 .25 0 .25.328 0 .235-.093.516-.171.688-.438 1.156-.563 1.61-.563 2.031 0 1.078.875 1.234 1.328 1.234 1.672 0 2.235-3.28 2.235-3.796zm0 0"/>
        </symbol>
        <symbol overflow="visible" id="n">
            <path style="stroke:none" d="M1.906-2.484a.524.524 0 1 0-1.047.016.524.524 0 0 0 1.047-.016zm0 0"/>
        </symbol>
    </defs>
    <g style="fill-opacity:1">
        <use xlink:href="#a" x="105.411" y="19.062"/>
        <use xlink:href="#b" x="108.994" y="19.062"/>
        <use xlink:href="#c" x="114.507" y="19.062"/>
        <use xlink:href="#d" x="117.264" y="19.062"/>
        <use xlink:href="#c" x="121.123" y="19.062"/>
        <use xlink:href="#e" x="123.879" y="19.062"/>
        <use xlink:href="#f" x="128.841" y="19.062"/>
    </g>
    <use xlink:href="#g" x="54.666" y="61.357" style="fill-opacity:1"/>
    <use xlink:href="#h" x="64.447" y="61.357" style="fill-opacity:1"/>
    <path style="stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="m-9.306-6.977-38.161-28.619" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#g" x="26.432" y="103.705" style="fill-opacity:1"/>
    <use xlink:href="#i" x="36.214" y="103.705" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="m-61.308-49.444-19.12-28.674" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#j" x="13.606" y="142.197" style="fill-opacity:1"/>
    <use xlink:href="#j" x="13.606" y="146.166" style="fill-opacity:1"/>
    <use xlink:href="#j" x="13.606" y="150.135" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="m-88.119-91.963-10.922-24.579" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#k" x="12.401" y="187.15" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="M-103.94-138.58v-25.837" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#j" x="51.249" y="142.197" style="fill-opacity:1"/>
    <use xlink:href="#j" x="51.249" y="146.166" style="fill-opacity:1"/>
    <use xlink:href="#j" x="51.249" y="150.135" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="m-81.965-91.963 10.927-24.579" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#k" x="50.045" y="187.15" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="M-66.144-138.58v-25.837" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#g" x="82.898" y="103.705" style="fill-opacity:1"/>
    <use xlink:href="#l" x="92.68" y="103.705" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="m-52.08-49.444 19.12-28.674" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#j" x="70.071" y="142.197" style="fill-opacity:1"/>
    <use xlink:href="#j" x="70.071" y="146.166" style="fill-opacity:1"/>
    <use xlink:href="#j" x="70.071" y="150.135" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="m-31.422-91.963-10.927-24.579" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#k" x="68.866" y="187.15" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="M-47.244-138.58v-25.837" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#j" x="107.715" y="142.197" style="fill-opacity:1"/>
    <use xlink:href="#j" x="107.715" y="146.166" style="fill-opacity:1"/>
    <use xlink:href="#j" x="107.715" y="150.135" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="m-25.269-91.963 10.923-24.579" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#k" x="106.51" y="187.15" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="M-9.448-138.58v-25.837" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#g" x="167.597" y="61.357" style="fill-opacity:1"/>
    <use xlink:href="#l" x="177.379" y="61.357" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="m9.303-6.977 38.161-28.619" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#g" x="139.364" y="103.705" style="fill-opacity:1"/>
    <use xlink:href="#h" x="149.145" y="103.705" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="M52.076-49.444 32.961-78.118" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#j" x="126.537" y="142.197" style="fill-opacity:1"/>
    <use xlink:href="#j" x="126.537" y="146.166" style="fill-opacity:1"/>
    <use xlink:href="#j" x="126.537" y="150.135" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="m25.27-91.963-10.927-24.579" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#k" x="125.332" y="187.15" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="M9.448-138.58v-25.837" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#j" x="164.181" y="142.197" style="fill-opacity:1"/>
    <use xlink:href="#j" x="164.181" y="146.166" style="fill-opacity:1"/>
    <use xlink:href="#j" x="164.181" y="150.135" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="m31.423-91.963 10.927-24.579" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#k" x="162.975" y="187.15" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="M47.245-138.58v-25.837" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#g" x="195.829" y="103.705" style="fill-opacity:1"/>
    <use xlink:href="#m" x="205.611" y="103.705" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="m61.309-49.444 19.115-28.674" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#j" x="183.003" y="142.197" style="fill-opacity:1"/>
    <use xlink:href="#j" x="183.003" y="146.166" style="fill-opacity:1"/>
    <use xlink:href="#j" x="183.003" y="150.135" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="m81.966-91.963-10.927-24.579" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#k" x="181.798" y="187.15" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="M66.145-138.58v-25.837" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#j" x="220.646" y="142.197" style="fill-opacity:1"/>
    <use xlink:href="#j" x="220.646" y="146.166" style="fill-opacity:1"/>
    <use xlink:href="#j" x="220.646" y="150.135" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="m88.115-91.963 10.927-24.579" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#k" x="219.441" y="187.15" style="fill-opacity:1"/>
    <path style="fill:none;stroke-width:.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10" d="M103.937-138.58v-25.837" transform="matrix(.99599 0 0 -.99599 118.503 15.617)"/>
    <use xlink:href="#n" x="112.716" y="60.172" style="fill-opacity:1"/>
    <use xlink:href="#n" x="117.129" y="60.172" style="fill-opacity:1"/>
    <use xlink:href="#n" x="121.533" y="60.172" style="fill-opacity:1"/>
    <use xlink:href="#n" x="56.25" y="102.52" style="fill-opacity:1"/>
    <use xlink:href="#n" x="60.664" y="102.52" style="fill-opacity:1"/>
    <use xlink:href="#n" x="65.067" y="102.52" style="fill-opacity:1"/>
    <use xlink:href="#n" x="169.181" y="102.52" style="fill-opacity:1"/>
    <use xlink:href="#n" x="173.595" y="102.52" style="fill-opacity:1"/>
    <use xlink:href="#n" x="177.999" y="102.52" style="fill-opacity:1"/>
    <use xlink:href="#n" x="28.018" y="187.219" style="fill-opacity:1"/>
    <use xlink:href="#n" x="32.431" y="187.219" style="fill-opacity:1"/>
    <use xlink:href="#n" x="36.835" y="187.219" style="fill-opacity:1"/>
    <use xlink:href="#n" x="84.483" y="187.219" style="fill-opacity:1"/>
    <use xlink:href="#n" x="88.897" y="187.219" style="fill-opacity:1"/>
    <use xlink:href="#n" x="93.301" y="187.219" style="fill-opacity:1"/>
    <use xlink:href="#n" x="140.949" y="187.219" style="fill-opacity:1"/>
    <use xlink:href="#n" x="145.363" y="187.219" style="fill-opacity:1"/>
    <use xlink:href="#n" x="149.766" y="187.219" style="fill-opacity:1"/>
    <use xlink:href="#n" x="197.414" y="187.219" style="fill-opacity:1"/>
    <use xlink:href="#n" x="201.827" y="187.219" style="fill-opacity:1"/>
    <use xlink:href="#n" x="206.231" y="187.219" style="fill-opacity:1"/>
</svg>
</figure>
<p>In this case <code>F 0</code> stands for marking the field <code>0</code>. The children of a node now make up all possible next moves from this state of the game. Once the game ends the corresponding branch will stop as well and we have a leaf (labeled by <code>v</code>).</p>
<p>The value of those leaves is given by the final state of the game: <code>-1</code> if your opponent wins, <code>1</code> if you win and <code>0</code> for a draw. Of course you want to pick your next move such that you may end up at a leave resulting in a <code>1</code>, while your opponent will try the opposite. As such one player tries to maximize the root value, while the other tries to miminize it.
So we are interested in the value of the current root of this tree.</p>
<h3 id="problem-definition">Problem Definition</h3>
<div class="details admonition tip open">
    <div class="details-summary admonition-title">
        <i class="icon far fa-lightbulb" aria-hidden="true"></i>Game Tree<i class="details-icon fas fa-angle-right" aria-hidden="true"></i>
    </div>
    <div class="details-content">
        <div class="admonition-content"><p>A game tree is a rooted tree in which internal nodes at an even distance from the root are labeled MIN and internal nodes at odd distance are labeled MAX. Each leaf is associated with a real number, its value. The goal is to determine the value of the root node.</p>
<p>Additionally, we are interested in the number of leaves that need to be evaluated to compute this value, any other operations are ignored.</p>
</div>
    </div>
</div>
<figure>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="237.503pt" height="200.139pt" viewBox="0 0 237.503 200.139" version="1.2" class="themed">
<defs>
<g>
<symbol overflow="visible" id="glyph0-0">
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph0-1">
<path style="stroke:none;" d="M 2.390625 -6.5625 C 2.296875 -6.78125 2.265625 -6.78125 2.046875 -6.78125 L 0.359375 -6.78125 L 0.359375 -6.46875 L 0.609375 -6.46875 C 1.375 -6.46875 1.390625 -6.359375 1.390625 -6 L 1.390625 -1.046875 C 1.390625 -0.78125 1.390625 -0.3125 0.359375 -0.3125 L 0.359375 0 C 0.71875 -0.015625 1.203125 -0.03125 1.53125 -0.03125 C 1.859375 -0.03125 2.34375 -0.015625 2.6875 0 L 2.6875 -0.3125 C 1.671875 -0.3125 1.671875 -0.78125 1.671875 -1.046875 L 1.671875 -6.390625 L 4.0625 -0.21875 C 4.125 -0.09375 4.171875 0 4.265625 0 C 4.375 0 4.40625 -0.078125 4.4375 -0.1875 L 6.890625 -6.46875 L 6.890625 -0.78125 C 6.890625 -0.421875 6.875 -0.3125 6.109375 -0.3125 L 5.875 -0.3125 L 5.875 0 C 6.234375 -0.03125 6.921875 -0.03125 7.296875 -0.03125 C 7.6875 -0.03125 8.359375 -0.03125 8.71875 0 L 8.71875 -0.3125 L 8.484375 -0.3125 C 7.71875 -0.3125 7.703125 -0.421875 7.703125 -0.78125 L 7.703125 -6 C 7.703125 -6.359375 7.71875 -6.46875 8.484375 -6.46875 L 8.71875 -6.46875 L 8.71875 -6.78125 L 7.046875 -6.78125 C 6.78125 -6.78125 6.78125 -6.765625 6.71875 -6.59375 L 4.546875 -1 Z M 2.390625 -6.5625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-2">
<path style="stroke:none;" d="M 2.234375 -6 C 2.234375 -6.359375 2.265625 -6.46875 3.046875 -6.46875 L 3.296875 -6.46875 L 3.296875 -6.78125 C 2.953125 -6.75 2.171875 -6.75 1.796875 -6.75 C 1.40625 -6.75 0.625 -6.75 0.28125 -6.78125 L 0.28125 -6.46875 L 0.53125 -6.46875 C 1.3125 -6.46875 1.34375 -6.359375 1.34375 -6 L 1.34375 -0.78125 C 1.34375 -0.421875 1.3125 -0.3125 0.53125 -0.3125 L 0.28125 -0.3125 L 0.28125 0 C 0.625 -0.03125 1.40625 -0.03125 1.78125 -0.03125 C 2.171875 -0.03125 2.953125 -0.03125 3.296875 0 L 3.296875 -0.3125 L 3.046875 -0.3125 C 2.265625 -0.3125 2.234375 -0.421875 2.234375 -0.78125 Z M 2.234375 -6 "/>
</symbol>
<symbol overflow="visible" id="glyph0-3">
<path style="stroke:none;" d="M 2.296875 -6.640625 C 2.21875 -6.765625 2.203125 -6.78125 2.015625 -6.78125 L 0.328125 -6.78125 L 0.328125 -6.46875 L 0.609375 -6.46875 C 0.765625 -6.46875 0.96875 -6.453125 1.109375 -6.453125 C 1.34375 -6.421875 1.34375 -6.40625 1.34375 -6.21875 L 1.34375 -1.046875 C 1.34375 -0.78125 1.34375 -0.3125 0.328125 -0.3125 L 0.328125 0 C 0.671875 -0.015625 1.15625 -0.03125 1.484375 -0.03125 C 1.8125 -0.03125 2.296875 -0.015625 2.65625 0 L 2.65625 -0.3125 C 1.625 -0.3125 1.625 -0.78125 1.625 -1.046875 L 1.625 -6.203125 C 1.671875 -6.15625 1.6875 -6.140625 1.71875 -6.078125 L 5.78125 -0.125 C 5.859375 -0.015625 5.875 0 5.9375 0 C 6.078125 0 6.078125 -0.0625 6.078125 -0.265625 L 6.078125 -5.734375 C 6.078125 -6 6.078125 -6.46875 7.109375 -6.46875 L 7.109375 -6.78125 C 6.75 -6.765625 6.265625 -6.75 5.9375 -6.75 C 5.609375 -6.75 5.125 -6.765625 4.78125 -6.78125 L 4.78125 -6.46875 C 5.796875 -6.46875 5.796875 -6 5.796875 -5.734375 L 5.796875 -1.5 Z M 2.296875 -6.640625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-4">
<path style="stroke:none;" d="M 3.953125 -6.90625 C 3.90625 -7.03125 3.875 -7.109375 3.71875 -7.109375 C 3.5625 -7.109375 3.53125 -7.046875 3.484375 -6.90625 L 1.421875 -0.96875 C 1.25 -0.46875 0.859375 -0.3125 0.3125 -0.3125 L 0.3125 0 C 0.546875 -0.015625 0.96875 -0.03125 1.328125 -0.03125 C 1.640625 -0.03125 2.15625 -0.015625 2.46875 0 L 2.46875 -0.3125 C 1.96875 -0.3125 1.71875 -0.5625 1.71875 -0.8125 C 1.71875 -0.84375 1.734375 -0.9375 1.75 -0.96875 L 2.203125 -2.265625 L 4.65625 -2.265625 L 5.171875 -0.75 C 5.1875 -0.703125 5.203125 -0.640625 5.203125 -0.609375 C 5.203125 -0.3125 4.65625 -0.3125 4.390625 -0.3125 L 4.390625 0 C 4.75 -0.03125 5.4375 -0.03125 5.8125 -0.03125 C 6.234375 -0.03125 6.703125 -0.015625 7.109375 0 L 7.109375 -0.3125 L 6.9375 -0.3125 C 6.34375 -0.3125 6.203125 -0.375 6.09375 -0.703125 Z M 3.421875 -5.796875 L 4.546875 -2.5625 L 2.3125 -2.5625 Z M 3.421875 -5.796875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-5">
<path style="stroke:none;" d="M 3.984375 -3.828125 L 5.34375 -5.828125 C 5.5625 -6.140625 5.90625 -6.453125 6.78125 -6.46875 L 6.78125 -6.78125 C 6.40625 -6.765625 5.9375 -6.75 5.6875 -6.75 C 5.28125 -6.75 4.8125 -6.75 4.421875 -6.78125 L 4.421875 -6.46875 C 4.8125 -6.453125 5.03125 -6.234375 5.03125 -6.015625 C 5.03125 -5.90625 5.015625 -5.890625 4.9375 -5.78125 L 3.8125 -4.109375 L 2.53125 -6.015625 C 2.515625 -6.046875 2.453125 -6.125 2.453125 -6.171875 C 2.453125 -6.296875 2.671875 -6.453125 3.109375 -6.46875 L 3.109375 -6.78125 C 2.765625 -6.75 2.03125 -6.75 1.65625 -6.75 C 1.34375 -6.75 0.734375 -6.75 0.359375 -6.78125 L 0.359375 -6.46875 L 0.5625 -6.46875 C 1.09375 -6.46875 1.296875 -6.40625 1.484375 -6.125 L 3.296875 -3.359375 L 1.671875 -0.96875 C 1.53125 -0.765625 1.234375 -0.3125 0.234375 -0.3125 L 0.234375 0 C 0.59375 -0.015625 1.015625 -0.03125 1.34375 -0.03125 C 1.703125 -0.03125 2.25 -0.03125 2.609375 0 L 2.609375 -0.3125 C 2.15625 -0.3125 1.984375 -0.578125 1.984375 -0.765625 C 1.984375 -0.859375 2.015625 -0.890625 2.078125 -1 L 3.5 -3.078125 L 5.0625 -0.71875 C 5.078125 -0.671875 5.109375 -0.640625 5.109375 -0.609375 C 5.109375 -0.484375 4.890625 -0.3125 4.46875 -0.3125 L 4.46875 0 C 4.8125 -0.03125 5.53125 -0.03125 5.90625 -0.03125 C 6.328125 -0.03125 6.78125 -0.015625 7.203125 0 L 7.203125 -0.3125 L 7.015625 -0.3125 C 6.5 -0.3125 6.296875 -0.359375 6.078125 -0.671875 Z M 3.984375 -3.828125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-6">
<path style="stroke:none;" d="M 1.90625 -0.53125 C 1.90625 -0.8125 1.671875 -1.046875 1.375 -1.046875 C 1.09375 -1.046875 0.859375 -0.8125 0.859375 -0.53125 C 0.859375 -0.234375 1.09375 0 1.375 0 C 1.671875 0 1.90625 -0.234375 1.90625 -0.53125 Z M 1.90625 -0.53125 "/>
</symbol>
<symbol overflow="visible" id="glyph1-0">
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph1-1">
<path style="stroke:none;" d="M 4.640625 -3.6875 C 4.640625 -4.234375 4.390625 -4.390625 4.203125 -4.390625 C 3.953125 -4.390625 3.71875 -4.125 3.71875 -3.90625 C 3.71875 -3.78125 3.765625 -3.71875 3.875 -3.609375 C 4.09375 -3.40625 4.21875 -3.15625 4.21875 -2.796875 C 4.21875 -2.375 3.609375 -0.109375 2.453125 -0.109375 C 1.9375 -0.109375 1.71875 -0.453125 1.71875 -0.96875 C 1.71875 -1.53125 1.984375 -2.25 2.296875 -3.078125 C 2.359375 -3.25 2.40625 -3.390625 2.40625 -3.578125 C 2.40625 -4.015625 2.09375 -4.390625 1.59375 -4.390625 C 0.671875 -4.390625 0.28125 -2.953125 0.28125 -2.859375 C 0.28125 -2.765625 0.390625 -2.765625 0.40625 -2.765625 C 0.5 -2.765625 0.515625 -2.78125 0.5625 -2.9375 C 0.859375 -3.9375 1.28125 -4.171875 1.5625 -4.171875 C 1.640625 -4.171875 1.8125 -4.171875 1.8125 -3.84375 C 1.8125 -3.609375 1.71875 -3.328125 1.640625 -3.15625 C 1.203125 -2 1.078125 -1.546875 1.078125 -1.125 C 1.078125 -0.046875 1.953125 0.109375 2.40625 0.109375 C 4.078125 0.109375 4.640625 -3.171875 4.640625 -3.6875 Z M 4.640625 -3.6875 "/>
</symbol>
<symbol overflow="visible" id="glyph2-0">
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph2-1">
<path style="stroke:none;" d="M 1.90625 -2.484375 C 1.90625 -2.765625 1.671875 -3 1.375 -3 C 1.09375 -3 0.859375 -2.765625 0.859375 -2.484375 C 0.859375 -2.1875 1.09375 -1.953125 1.375 -1.953125 C 1.671875 -1.953125 1.90625 -2.1875 1.90625 -2.484375 Z M 1.90625 -2.484375 "/>
</symbol>
</g>
</defs>
<g id="surface1">
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-1" x="108.445835" y="18.947488"/>
  <use xlink:href="#glyph0-2" x="117.53943" y="18.947488"/>
  <use xlink:href="#glyph0-3" x="121.121514" y="18.947488"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-1" x="50.066981" y="61.28535"/>
  <use xlink:href="#glyph0-4" x="59.160576" y="61.28535"/>
  <use xlink:href="#glyph0-5" x="66.600519" y="61.28535"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M -9.230607 -6.924719 L -47.464698 -35.598326 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-1" x="23.771107" y="103.622216"/>
  <use xlink:href="#glyph0-2" x="32.864701" y="103.622216"/>
  <use xlink:href="#glyph0-3" x="36.446786" y="103.622216"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M -61.309158 -49.442786 L -80.426204 -78.116393 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="13.634713" y="142.102673"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="13.634713" y="146.070603"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="13.634713" y="150.038533"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M -88.115391 -91.964776 L -99.041099 -116.542714 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph1-1" x="12.429897" y="187.043338"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M -103.937071 -138.578512 L -103.937071 -164.415751 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="51.267815" y="142.102673"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="51.267815" y="146.070603"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="51.267815" y="150.038533"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M -81.964041 -91.964776 L -71.038334 -116.542714 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph1-1" x="50.062999" y="187.043338"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M -66.142362 -138.578512 L -66.142362 -164.415751 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-1" x="80.221257" y="103.622216"/>
  <use xlink:href="#glyph0-2" x="89.314852" y="103.622216"/>
  <use xlink:href="#glyph0-3" x="92.896937" y="103.622216"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M -52.07821 -49.442786 L -32.961165 -78.116393 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="70.084864" y="142.102673"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="70.084864" y="146.070603"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="70.084864" y="150.038533"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M -31.423327 -91.964776 L -42.349035 -116.542714 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph1-1" x="68.880047" y="187.043338"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M -47.245007 -138.578512 L -47.245007 -164.415751 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="107.717966" y="142.102673"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="107.717966" y="146.070603"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="107.717966" y="150.038533"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M -25.271977 -91.964776 L -14.34627 -116.542714 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph1-1" x="106.51315" y="187.043338"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M -9.450298 -138.578512 L -9.450298 -164.415751 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-1" x="162.967283" y="61.28535"/>
  <use xlink:href="#glyph0-4" x="172.060878" y="61.28535"/>
  <use xlink:href="#glyph0-5" x="179.500821" y="61.28535"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M 9.231289 -6.924719 L 47.46538 -35.598326 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-1" x="136.671408" y="103.622216"/>
  <use xlink:href="#glyph0-2" x="145.765003" y="103.622216"/>
  <use xlink:href="#glyph0-3" x="149.347088" y="103.622216"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M 52.078893 -49.442786 L 32.961847 -78.116393 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="126.535015" y="142.102673"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="126.535015" y="146.070603"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="126.535015" y="150.038533"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M 25.268737 -91.964776 L 14.343029 -116.542714 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph1-1" x="125.330198" y="187.043338"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M 9.447057 -138.578512 L 9.45098 -164.415751 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="164.168117" y="142.102673"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="164.168117" y="146.070603"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="164.168117" y="150.038533"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M 31.424009 -91.964776 L 42.349717 -116.542714 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph1-1" x="162.9633" y="187.043338"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M 47.245689 -138.578512 L 47.245689 -164.415751 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-1" x="193.121559" y="103.622216"/>
  <use xlink:href="#glyph0-2" x="202.215154" y="103.622216"/>
  <use xlink:href="#glyph0-3" x="205.797239" y="103.622216"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M 61.30984 -49.442786 L 80.426886 -78.116393 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="182.985166" y="142.102673"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="182.985166" y="146.070603"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="182.985166" y="150.038533"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M 81.964724 -91.964776 L 71.039016 -116.542714 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph1-1" x="181.780349" y="187.043338"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M 66.143044 -138.578512 L 66.143044 -164.415751 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="220.618268" y="142.102673"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="220.618268" y="146.070603"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph0-6" x="220.618268" y="150.038533"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M 88.116073 -91.964776 L 99.041781 -116.542714 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph1-1" x="219.413451" y="187.043338"/>
</g>
<path style="fill:none;stroke-width:0.3985;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:10;" d="M 103.937753 -138.578512 L 103.937753 -164.415751 " transform="matrix(0.995716,0,0,-0.995716,118.503567,15.558069)"/>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph2-1" x="28.04273" y="187.113038"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph2-1" x="32.455112" y="187.113038"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph2-1" x="36.857575" y="187.113038"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph2-1" x="84.492881" y="187.113038"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph2-1" x="88.905263" y="187.113038"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph2-1" x="93.307726" y="187.113038"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph2-1" x="140.943032" y="187.113038"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph2-1" x="145.355414" y="187.113038"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph2-1" x="149.757877" y="187.113038"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph2-1" x="197.392187" y="187.113038"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph2-1" x="201.804569" y="187.113038"/>
</g>
<g style="fill-opacity:1;">
  <use xlink:href="#glyph2-1" x="206.207032" y="187.113038"/>
</g>
</g>
</svg>

</figure>
<p>For ease of presentation I only consider full binary trees with values in $\lbrace 0,1 \rbrace$.
Let such a tree be denoted as $T_{2,k}$, with $k$ layers of MAX nodes and $k$ layers of MIN nodes. Hence, the total height of the tree is $2k$ and it has $4^{k}$ leaves. As the values can be interpreted as boolean values, the two types of internal nodes can be regarded as AND respectively OR operations.</p>
<h3 id="deterministic-algorithm">Deterministic Algorithm</h3>
<p>A Game Tree can be evaluated by recursively calculating the values of its child nodes. At each step the algorithm has to decide which child to regard first. This choice has to be deterministic for a deterministic algorithm. Short-circuiting may be used to skip the evaluation of the second child node if the first already returned 0 for a MIN node or 1 for a MAX node respectively. But for any deterministic choice for the order of evaluation there exists a worst case such that the algorithm needs to evaluate all $d^{2k}$ leaves. Thus, its worst case number of steps is linear in the number of leaves.</p>
<h3 id="randomized-algorithm">Randomized Algorithm</h3>
<p>The randomized algorithm works almost the same as the deterministic one.
But instead of a deterministic order for the evaluation of its children, the algorithm chooses each child node first with equal probability. The expected number of leaves that have to be evaluated can then be reduced to $3^{k}$, which is roughly $n^{0.792}$ with $n$ as the number of leaves.</p>
<h3 id="proof">Proof</h3>
<p>The claimed property is proved by <a href="https://en.wikipedia.org/wiki/Mathematical_induction" target="_blank" rel="noopener noreffer ">induction</a> over $k$. First note that due to short-circuiting a MIN node evaluating to 0 and a MAX node evaluating to 1 are the same case, with the values flipped. The same is true for a MIN node evaluating to 1 and a MAX node evaluating to 0.</p>
<p>First consider the two cases for $k=1$.</p>
<h6 id="min-root-0-k1">MIN root 0, k=1</h6>
<p>If a MIN root evaluates to 0, at least one of its child MAX nodes must evaluate to 0. With probability $\frac{1}{2}$ this node is selected first. In turn both its children must evaluate to 0 as well.
Thus, picking the correct node results in $2$ leaves being evaluated ($\red{\text{red part}}$).</p>
<figure>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="171.156pt" height="117.673pt" viewBox="0 0 171.156 117.673">
<g enable-background="new">
<symbol id="font_0_7">
<path d="M .20400001 .661 C .19500001 .683 .19200002 .683 .16900002 .683 L 0 .683 L 0 .652 L .024000004 .652 C .10100001 .652 .103 .64100006 .103 .605 L .103 .105000007 C .103 .078 .103 .031000002 0 .031000002 L 0 0 C .035000005 .001 .08400001 .003 .11700001 .003 C .15 .003 .19900002 .001 .23400003 0 L .23400003 .031000002 C .13100001 .031000002 .13100001 .078 .13100001 .105000007 L .13100001 .64400008 L .13200002 .64400008 L .37300004 .022000002 C .37800003 .009000001 .38300003 0 .393 0 C .404 0 .40700004 .008 .411 .019000002 L .657 .652 L .65800008 .652 L .65800008 .078 C .65800008 .042000005 .656 .031000002 .57900008 .031000002 L .555 .031000002 L .555 0 C .592 .003 .66 .003 .69900009 .003 C .73800006 .003 .80500009 .003 .84200009 0 L .84200009 .031000002 L .818 .031000002 C .74100008 .031000002 .739 .042000005 .739 .078 L .739 .605 C .739 .64100006 .74100008 .652 .818 .652 L .84200009 .652 L .84200009 .683 L .67300006 .683 C .647 .683 .647 .68200007 .64000007 .66400006 L .42100004 .101 L .20400001 .661 Z "/>
</symbol>
<symbol id="font_0_6">
<path d="M .19700001 .605 C .19700001 .64100006 .20000002 .652 .279 .652 L .305 .652 L .305 .683 C .27 .68 .19100002 .68 .15300001 .68 C .11400001 .68 .035 .68 0 .683 L 0 .652 L .026 .652 C .105000007 .652 .10800001 .64100006 .10800001 .605 L .10800001 .078 C .10800001 .042000005 .105000007 .031000002 .026 .031000002 L 0 .031000002 L 0 0 C .035 .003 .11400001 .003 .15200001 .003 C .19100002 .003 .27 .003 .305 0 L .305 .031000002 L .279 .031000002 C .20000002 .031000002 .19700001 .042000005 .19700001 .078 L .19700001 .605 Z "/>
</symbol>
<symbol id="font_0_8">
<path d="M .199 .67 C .19 .68200007 .18900001 .683 .17000002 .683 L 0 .683 L 0 .652 L .029000003 .652 C .044000009 .652 .064 .651 .079 .65000006 C .102000009 .647 .10300001 .646 .10300001 .62700006 L .10300001 .105000007 C .10300001 .078 .10300001 .031000002 0 .031000002 L 0 0 C .035000005 .001 .08400001 .003 .117000009 .003 C .15 .003 .199 .001 .23400003 0 L .23400003 .031000002 C .13100001 .031000002 .13100001 .078 .13100001 .105000007 L .13100001 .625 C .136 .62 .137 .619 .141 .61300006 L .549 .013 C .558 .001 .559 0 .56600007 0 C .58000007 0 .58000007 .007 .58000007 .026 L .58000007 .578 C .58000007 .605 .58000007 .652 .683 .652 L .683 .683 C .64800009 .68200007 .59900006 .68 .56600007 .68 C .53300008 .68 .48400004 .68200007 .44900004 .683 L .44900004 .652 C .55200007 .652 .55200007 .605 .55200007 .578 L .55200007 .15100001 L .199 .67 Z "/>
</symbol>
<symbol id="font_0_1">
<path d="M .23200003 .00999999 C .23200003 .012999982 .23200003 .014999986 .215 .03199999 C .09 .15799999 .058 .347 .058 .5 C .058 .674 .096 .84800007 .21900001 .97300007 C .23200003 .985 .23200003 .98700007 .23200003 .99 C .23200003 .99700006 .22800002 1 .222 1 C .21200001 1 .12200001 .93200007 .06299999 .805 C .012000002 .69500008 0 .584 0 .5 C 0 .422 .011 .301 .066 .188 C .126 .065 .21200001 0 .222 0 C .22800002 0 .23200003 .0029999912 .23200003 .00999999 Z "/>
</symbol>
<symbol id="font_0_3">
<path d="M .421 .34200005 C .421 .42200003 .416 .50200006 .381 .57600006 C .335 .67200008 .25300003 .688 .211 .688 C .15100001 .688 .07800001 .66200008 .037000006 .56900009 C .0050000029 .5 0 .42200003 0 .34200005 C 0 .26700003 .0040000008 .177 .045000007 .101 C .088 .020000002 .161 0 .21000001 0 C .264 0 .34 .021000002 .384 .116000007 C .416 .185 .421 .263 .421 .34200005 M .21000001 .022000002 C .171 .022000002 .112 .047000003 .094 .143 C .083000008 .20300001 .083000008 .29500003 .083000008 .35400004 C .083000008 .41800005 .083000008 .48400004 .091000009 .53800007 C .11 .65700009 .185 .66600009 .21000001 .66600009 C .243 .66600009 .30900003 .64800009 .328 .549 C .338 .49300004 .338 .41700004 .338 .35400004 C .338 .279 .338 .21100001 .32700003 .147 C .312 .052 .255 .022000002 .21000001 .022000002 Z "/>
</symbol>
<symbol id="font_0_2">
<path d="M .232 .5 C .232 .578 .22100002 .699 .16600001 .81200006 C .106 .93500009 .020000004 1 .009999998 1 C .0040000008 1 0 .99600008 0 .99 C 0 .98700007 0 .985 .019000002 .967 C .117000009 .86800006 .174 .709 .174 .5 C .174 .329 .137 .153 .012999997 .026999996 C 0 .014999986 0 .012999982 0 .00999999 C 0 .003999993 .0040000008 0 .009999998 0 C .020000004 0 .11000001 .06799999 .169 .195 C .22 .305 .232 .416 .232 .5 Z "/>
</symbol>
<use xlink:href="#font_0_7" transform="matrix(9.9626,0,0,-9.9626,67.82062,19.692994)" class="fill"/>
<use xlink:href="#font_0_6" transform="matrix(9.9626,0,0,-9.9626,76.86666,19.692994)" class="fill"/>
<use xlink:href="#font_0_8" transform="matrix(9.9626,0,0,-9.9626,80.51297,19.692994)" class="fill"/>
<use xlink:href="#font_0_1" transform="matrix(9.9626,0,0,-9.9626,91.96,22.183644)" class="fill"/>
<use xlink:href="#font_0_3" transform="matrix(9.9626,0,0,-9.9626,95.23769,19.91217)" class="fill"/>
<use xlink:href="#font_0_2" transform="matrix(9.9626,0,0,-9.9626,100.39832,22.183644)" class="fill"/>
<symbol id="font_0_5">
<path d="M .36600004 .69600006 C .361 .70900008 .35900004 .716 .34300003 .716 C .32700003 .716 .324 .71000006 .319 .69600006 L .112 .098000008 C .094 .047000003 .054 .032 0 .031000002 L 0 0 C .023000002 .001 .066 .003 .102 .003 C .133 .003 .185 .001 .21700001 0 L .21700001 .031000002 C .16700001 .031000002 .142 .056 .142 .082 C .142 .085 .143 .095000009 .14400001 .097 L .19000001 .22800002 L .437 .22800002 L .49 .075 C .491 .071 .49300004 .065000008 .49300004 .061000006 C .49300004 .031000002 .437 .031000002 .41000004 .031000002 L .41000004 0 C .446 .003 .51600006 .003 .554 .003 C .597 .003 .643 .002 .685 0 L .685 .031000002 L .66700008 .031000002 C .60700008 .031000002 .593 .038000004 .582 .071 L .36600004 .69600006 M .31300003 .58400008 L .42600004 .259 L .201 .259 L .31300003 .58400008 Z "/>
</symbol>
<symbol id="font_0_9">
<path d="M .37800003 .386 L .51500007 .587 C .53700008 .619 .57100006 .651 .66 .652 L .66 .683 C .62100008 .68200007 .57400009 .68 .549 .68 C .50900009 .68 .46100004 .68 .42100004 .683 L .42100004 .652 C .46100004 .651 .48300005 .629 .48300005 .606 C .48300005 .596 .481 .59400007 .47400005 .583 L .36 .41400004 L .23100002 .60700008 C .22900002 .61 .224 .61800006 .224 .62200006 C .224 .634 .246 .651 .28900004 .652 L .28900004 .683 C .25400005 .68 .18100001 .68 .143 .68 C .112 .68 .05 .68100008 .013 .683 L .013 .652 L .032 .652 C .08700001 .652 .106000009 .64500007 .125 .61700007 L .30900003 .33900003 L .14500001 .097 C .131 .07700001 .100999999 .031000002 0 .031000002 L 0 0 C .036000004 .001 .07800001 .003 .111 .003 C .148 .003 .20300001 .003 .23900001 0 L .23900001 .031000002 C .193 .032 .176 .059000005 .176 .07700001 C .176 .086 .179 .09 .186 .101 L .32800005 .31100003 L .48600007 .072000008 C .48800005 .068 .49100007 .064 .49100007 .061000006 C .49100007 .049000004 .46900005 .032 .42600004 .031000002 L .42600004 0 C .46100004 .003 .53400006 .003 .572 .003 C .614 .003 .66 .002 .702 0 L .702 .031000002 L .683 .031000002 C .63100007 .031000002 .61 .036000004 .58900007 .067 L .37800003 .386 Z "/>
</symbol>
<use xlink:href="#font_0_7" transform="matrix(9.9626,0,0,-9.9626,23.363619,62.21199)" class="fill red"/>
<use xlink:href="#font_0_5" transform="matrix(9.9626,0,0,-9.9626,32.44951,62.21199)" class="fill red"/>
<use xlink:href="#font_0_9" transform="matrix(9.9626,0,0,-9.9626,39.841764,62.21199)" class="fill red"/>
<use xlink:href="#font_0_1" transform="matrix(9.9626,0,0,-9.9626,51.378458,64.70264)" class="fill red"/>
<use xlink:href="#font_0_3" transform="matrix(9.9626,0,0,-9.9626,54.65615,62.431169)" class="fill red"/>
<use xlink:href="#font_0_2" transform="matrix(9.9626,0,0,-9.9626,59.816778,64.70264)" class="fill red"/>
<path transform="matrix(1,0,0,-1,85.578,17.201996)" stroke-width=".3985" stroke-linecap="butt" stroke-miterlimit="10" stroke-linejoin="miter" fill="none" class="stroke" d="M -8.50067 -8.50119 L -34.02211 -34.01901 "/>
<use xlink:href="#font_0_3" transform="matrix(9.9626,0,0,-9.9626,12.609542,105.67117)" class="fill red"/>
<path transform="matrix(1,0,0,-1,85.578,17.201996)" stroke-width=".3985" stroke-linecap="butt" stroke-miterlimit="10" stroke-linejoin="miter" fill="none" class="stroke" d="M -48.18706 -51.02142 L -66.38202 -78.3104 "/>
<use xlink:href="#font_0_3" transform="matrix(9.9626,0,0,-9.9626,69.30254,105.67117)" class="fill red"/>
<path transform="matrix(1,0,0,-1,85.578,17.201996)" stroke-width=".3985" stroke-linecap="butt" stroke-miterlimit="10" stroke-linejoin="miter" fill="none" class="stroke" d="M -36.85335 -51.02142 L -18.65843 -78.3104 "/>
<symbol id="font_0_4">
<path d="M .205 .64000007 C .205 .66400006 .205 .666 .18200003 .666 C .120000008 .60200008 .032000007 .60200008 0 .60200008 L 0 .57100006 C .020000004 .57100006 .07900001 .57100006 .13100001 .597 L .13100001 .079 C .13100001 .043 .128 .031000002 .038000004 .031000002 L .0060000049 .031000002 L .0060000049 0 C .04100001 .003 .128 .003 .168 .003 C .20800002 .003 .29500003 .003 .33000005 0 L .33000005 .031000002 L .29800005 .031000002 C .20800002 .031000002 .205 .042000005 .205 .079 L .205 .64000007 Z "/>
</symbol>
<use xlink:href="#font_0_7" transform="matrix(9.9626,0,0,-9.9626,108.40262,62.21199)" class="fill blue"/>
<use xlink:href="#font_0_5" transform="matrix(9.9626,0,0,-9.9626,117.48851,62.21199)" class="fill blue"/>
<use xlink:href="#font_0_9" transform="matrix(9.9626,0,0,-9.9626,124.88076,62.21199)" class="fill blue"/>
<use xlink:href="#font_0_1" transform="matrix(9.9626,0,0,-9.9626,136.41745,64.70264)" class="fill blue"/>
<use xlink:href="#font_0_4" transform="matrix(9.9626,0,0,-9.9626,140.19329,62.21199)" class="fill blue"/>
<use xlink:href="#font_0_2" transform="matrix(9.9626,0,0,-9.9626,144.85578,64.70264)" class="fill blue"/>
<path transform="matrix(1,0,0,-1,85.578,17.201996)" stroke-width=".3985" stroke-linecap="butt" stroke-miterlimit="10" stroke-linejoin="miter" fill="none" class="stroke" d="M 8.50067 -8.50119 L 34.02216 -34.01901 "/>
<use xlink:href="#font_0_3" transform="matrix(9.9626,0,0,-9.9626,97.64954,105.67117)" class="fill green"/>
<path transform="matrix(1,0,0,-1,85.578,17.201996)" stroke-width=".3985" stroke-linecap="butt" stroke-miterlimit="10" stroke-linejoin="miter" fill="none" class="stroke" d="M 36.8534 -51.02142 L 18.65843 -78.3104 "/>
<use xlink:href="#font_0_4" transform="matrix(9.9626,0,0,-9.9626,154.84069,105.451999)" class="fill blue"/>
<path transform="matrix(1,0,0,-1,85.578,17.201996)" stroke-width=".3985" stroke-linecap="butt" stroke-miterlimit="10" stroke-linejoin="miter" fill="none" class="stroke" d="M 48.1871 -51.02142 L 66.38202 -78.3104 "/>
</g>
</svg>

</figure>
<p>The other node is picked with probability $\frac{1}{2}$ as well. As it evaluates to 1, it must have at least on child with value 1. This child is again picked with probability $\frac{1}{2}$ ($\blue{\text{blue part}}$). In that case the blue and red nodes have to be considered for a total of 3.</p>
<p>With probability $\frac{1}{2}$ the wrong node is selected first again ($\green{\text{green part}}$), which results in all 4 leaves being evaluated.</p>
<p>The expected number of leaves that have to be considered is thus:
<data id="id-1" data-raw></data></p>
<h6 id="min-root-1-k1">MIN root 1, k=1</h6>
<p>On the flip side, if a MIN node evaluates to 1 both its children must be considered. But the child nodes are MAX nodes and must have at least one child node with value 1 again. With probability $\frac{1}{2}$ this node is chosen first in each case.</p>
<figure>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="171.156pt" height="117.673pt" viewBox="0 0 171.156 117.673">
<g enable-background="new">
<symbol id="font_0_7">
<path d="M .20400001 .661 C .19500001 .683 .19200002 .683 .16900002 .683 L 0 .683 L 0 .652 L .024000004 .652 C .10100001 .652 .103 .64100006 .103 .605 L .103 .105000007 C .103 .078 .103 .031000002 0 .031000002 L 0 0 C .035000005 .001 .08400001 .003 .11700001 .003 C .15 .003 .19900002 .001 .23400003 0 L .23400003 .031000002 C .13100001 .031000002 .13100001 .078 .13100001 .105000007 L .13100001 .64400008 L .13200002 .64400008 L .37300004 .022000002 C .37800003 .009000001 .38300003 0 .393 0 C .404 0 .40700004 .008 .411 .019000002 L .657 .652 L .65800008 .652 L .65800008 .078 C .65800008 .042000005 .656 .031000002 .57900008 .031000002 L .555 .031000002 L .555 0 C .592 .003 .66 .003 .69900009 .003 C .73800006 .003 .80500009 .003 .84200009 0 L .84200009 .031000002 L .818 .031000002 C .74100008 .031000002 .739 .042000005 .739 .078 L .739 .605 C .739 .64100006 .74100008 .652 .818 .652 L .84200009 .652 L .84200009 .683 L .67300006 .683 C .647 .683 .647 .68200007 .64000007 .66400006 L .42100004 .101 L .20400001 .661 Z "/>
</symbol>
<symbol id="font_0_6">
<path d="M .19700001 .605 C .19700001 .64100006 .20000002 .652 .279 .652 L .305 .652 L .305 .683 C .27 .68 .19100002 .68 .15300001 .68 C .11400001 .68 .035 .68 0 .683 L 0 .652 L .026 .652 C .105000007 .652 .10800001 .64100006 .10800001 .605 L .10800001 .078 C .10800001 .042000005 .105000007 .031000002 .026 .031000002 L 0 .031000002 L 0 0 C .035 .003 .11400001 .003 .15200001 .003 C .19100002 .003 .27 .003 .305 0 L .305 .031000002 L .279 .031000002 C .20000002 .031000002 .19700001 .042000005 .19700001 .078 L .19700001 .605 Z "/>
</symbol>
<symbol id="font_0_8">
<path d="M .199 .67 C .19 .68200007 .18900001 .683 .17000002 .683 L 0 .683 L 0 .652 L .029000003 .652 C .044000009 .652 .064 .651 .079 .65000006 C .102000009 .647 .10300001 .646 .10300001 .62700006 L .10300001 .105000007 C .10300001 .078 .10300001 .031000002 0 .031000002 L 0 0 C .035000005 .001 .08400001 .003 .117000009 .003 C .15 .003 .199 .001 .23400003 0 L .23400003 .031000002 C .13100001 .031000002 .13100001 .078 .13100001 .105000007 L .13100001 .625 C .136 .62 .137 .619 .141 .61300006 L .549 .013 C .558 .001 .559 0 .56600007 0 C .58000007 0 .58000007 .007 .58000007 .026 L .58000007 .578 C .58000007 .605 .58000007 .652 .683 .652 L .683 .683 C .64800009 .68200007 .59900006 .68 .56600007 .68 C .53300008 .68 .48400004 .68200007 .44900004 .683 L .44900004 .652 C .55200007 .652 .55200007 .605 .55200007 .578 L .55200007 .15100001 L .199 .67 Z "/>
</symbol>
<symbol id="font_0_1">
<path d="M .23200003 .00999999 C .23200003 .012999982 .23200003 .014999986 .215 .03199999 C .09 .15799999 .058 .347 .058 .5 C .058 .674 .096 .84800007 .21900001 .97300007 C .23200003 .985 .23200003 .98700007 .23200003 .99 C .23200003 .99700006 .22800002 1 .222 1 C .21200001 1 .12200001 .93200007 .06299999 .805 C .012000002 .69500008 0 .584 0 .5 C 0 .422 .011 .301 .066 .188 C .126 .065 .21200001 0 .222 0 C .22800002 0 .23200003 .0029999912 .23200003 .00999999 Z "/>
</symbol>
<symbol id="font_0_4">
<path d="M .205 .64000007 C .205 .66400006 .205 .666 .18200003 .666 C .120000008 .60200008 .032000007 .60200008 0 .60200008 L 0 .57100006 C .020000004 .57100006 .07900001 .57100006 .13100001 .597 L .13100001 .079 C .13100001 .043 .128 .031000002 .038000004 .031000002 L .0060000049 .031000002 L .0060000049 0 C .04100001 .003 .128 .003 .168 .003 C .20800002 .003 .29500003 .003 .33000005 0 L .33000005 .031000002 L .29800005 .031000002 C .20800002 .031000002 .205 .042000005 .205 .079 L .205 .64000007 Z "/>
</symbol>
<symbol id="font_0_2">
<path d="M .232 .5 C .232 .578 .22100002 .699 .16600001 .81200006 C .106 .93500009 .020000004 1 .009999998 1 C .0040000008 1 0 .99600008 0 .99 C 0 .98700007 0 .985 .019000002 .967 C .117000009 .86800006 .174 .709 .174 .5 C .174 .329 .137 .153 .012999997 .026999996 C 0 .014999986 0 .012999982 0 .00999999 C 0 .003999993 .0040000008 0 .009999998 0 C .020000004 0 .11000001 .06799999 .169 .195 C .22 .305 .232 .416 .232 .5 Z "/>
</symbol>
<use xlink:href="#font_0_7" transform="matrix(9.9626,0,0,-9.9626,67.82062,19.692994)" class="fill"/>
<use xlink:href="#font_0_6" transform="matrix(9.9626,0,0,-9.9626,76.86666,19.692994)" class="fill"/>
<use xlink:href="#font_0_8" transform="matrix(9.9626,0,0,-9.9626,80.51297,19.692994)" class="fill"/>
<use xlink:href="#font_0_1" transform="matrix(9.9626,0,0,-9.9626,91.96,22.183644)" class="fill"/>
<use xlink:href="#font_0_4" transform="matrix(9.9626,0,0,-9.9626,95.735828,19.692994)" class="fill"/>
<use xlink:href="#font_0_2" transform="matrix(9.9626,0,0,-9.9626,100.39832,22.183644)" class="fill"/>
<symbol id="font_0_5">
<path d="M .36600004 .69600006 C .361 .70900008 .35900004 .716 .34300003 .716 C .32700003 .716 .324 .71000006 .319 .69600006 L .112 .098000008 C .094 .047000003 .054 .032 0 .031000002 L 0 0 C .023000002 .001 .066 .003 .102 .003 C .133 .003 .185 .001 .21700001 0 L .21700001 .031000002 C .16700001 .031000002 .142 .056 .142 .082 C .142 .085 .143 .095000009 .14400001 .097 L .19000001 .22800002 L .437 .22800002 L .49 .075 C .491 .071 .49300004 .065000008 .49300004 .061000006 C .49300004 .031000002 .437 .031000002 .41000004 .031000002 L .41000004 0 C .446 .003 .51600006 .003 .554 .003 C .597 .003 .643 .002 .685 0 L .685 .031000002 L .66700008 .031000002 C .60700008 .031000002 .593 .038000004 .582 .071 L .36600004 .69600006 M .31300003 .58400008 L .42600004 .259 L .201 .259 L .31300003 .58400008 Z "/>
</symbol>
<symbol id="font_0_9">
<path d="M .37800003 .386 L .51500007 .587 C .53700008 .619 .57100006 .651 .66 .652 L .66 .683 C .62100008 .68200007 .57400009 .68 .549 .68 C .50900009 .68 .46100004 .68 .42100004 .683 L .42100004 .652 C .46100004 .651 .48300005 .629 .48300005 .606 C .48300005 .596 .481 .59400007 .47400005 .583 L .36 .41400004 L .23100002 .60700008 C .22900002 .61 .224 .61800006 .224 .62200006 C .224 .634 .246 .651 .28900004 .652 L .28900004 .683 C .25400005 .68 .18100001 .68 .143 .68 C .112 .68 .05 .68100008 .013 .683 L .013 .652 L .032 .652 C .08700001 .652 .106000009 .64500007 .125 .61700007 L .30900003 .33900003 L .14500001 .097 C .131 .07700001 .100999999 .031000002 0 .031000002 L 0 0 C .036000004 .001 .07800001 .003 .111 .003 C .148 .003 .20300001 .003 .23900001 0 L .23900001 .031000002 C .193 .032 .176 .059000005 .176 .07700001 C .176 .086 .179 .09 .186 .101 L .32800005 .31100003 L .48600007 .072000008 C .48800005 .068 .49100007 .064 .49100007 .061000006 C .49100007 .049000004 .46900005 .032 .42600004 .031000002 L .42600004 0 C .46100004 .003 .53400006 .003 .572 .003 C .614 .003 .66 .002 .702 0 L .702 .031000002 L .683 .031000002 C .63100007 .031000002 .61 .036000004 .58900007 .067 L .37800003 .386 Z "/>
</symbol>
<use xlink:href="#font_0_7" transform="matrix(9.9626,0,0,-9.9626,23.363619,62.21199)" class="fill red"/>
<use xlink:href="#font_0_5" transform="matrix(9.9626,0,0,-9.9626,32.44951,62.21199)" class="fill red"/>
<use xlink:href="#font_0_9" transform="matrix(9.9626,0,0,-9.9626,39.841764,62.21199)" class="fill red"/>
<use xlink:href="#font_0_1" transform="matrix(9.9626,0,0,-9.9626,51.378458,64.70264)" class="fill red"/>
<use xlink:href="#font_0_4" transform="matrix(9.9626,0,0,-9.9626,55.15428,62.21199)" class="fill red"/>
<use xlink:href="#font_0_2" transform="matrix(9.9626,0,0,-9.9626,59.816778,64.70264)" class="fill red"/>
<path transform="matrix(1,0,0,-1,85.578,17.201996)" stroke-width=".3985" stroke-linecap="butt" stroke-miterlimit="10" stroke-linejoin="miter" fill="none" class="stroke" d="M -8.50067 -8.50119 L -34.02211 -34.01901 "/>
<symbol id="font_0_3">
<path d="M .421 .34200005 C .421 .42200003 .416 .50200006 .381 .57600006 C .335 .67200008 .25300003 .688 .211 .688 C .15100001 .688 .07800001 .66200008 .037000006 .56900009 C .0050000029 .5 0 .42200003 0 .34200005 C 0 .26700003 .0040000008 .177 .045000007 .101 C .088 .020000002 .161 0 .21000001 0 C .264 0 .34 .021000002 .384 .116000007 C .416 .185 .421 .263 .421 .34200005 M .21000001 .022000002 C .171 .022000002 .112 .047000003 .094 .143 C .083000008 .20300001 .083000008 .29500003 .083000008 .35400004 C .083000008 .41800005 .083000008 .48400004 .091000009 .53800007 C .11 .65700009 .185 .66600009 .21000001 .66600009 C .243 .66600009 .30900003 .64800009 .328 .549 C .338 .49300004 .338 .41700004 .338 .35400004 C .338 .279 .338 .21100001 .32700003 .147 C .312 .052 .255 .022000002 .21000001 .022000002 Z "/>
</symbol>
<use xlink:href="#font_0_3" transform="matrix(9.9626,0,0,-9.9626,12.609542,105.67117)" class="fill blue"/>
<path transform="matrix(1,0,0,-1,85.578,17.201996)" stroke-width=".3985" stroke-linecap="butt" stroke-miterlimit="10" stroke-linejoin="miter" fill="none" class="stroke" d="M -48.18706 -51.02142 L -66.38202 -78.3104 "/>
<use xlink:href="#font_0_4" transform="matrix(9.9626,0,0,-9.9626,69.800678,105.451999)" class="fill red"/>
<path transform="matrix(1,0,0,-1,85.578,17.201996)" stroke-width=".3985" stroke-linecap="butt" stroke-miterlimit="10" stroke-linejoin="miter" fill="none" class="stroke" d="M -36.85335 -51.02142 L -18.65843 -78.3104 "/>
<use xlink:href="#font_0_7" transform="matrix(9.9626,0,0,-9.9626,108.40262,62.21199)" class="fill red"/>
<use xlink:href="#font_0_5" transform="matrix(9.9626,0,0,-9.9626,117.48851,62.21199)" class="fill red"/>
<use xlink:href="#font_0_9" transform="matrix(9.9626,0,0,-9.9626,124.88076,62.21199)" class="fill red"/>
<use xlink:href="#font_0_1" transform="matrix(9.9626,0,0,-9.9626,136.41745,64.70264)" class="fill red"/>
<use xlink:href="#font_0_4" transform="matrix(9.9626,0,0,-9.9626,140.19329,62.21199)" class="fill red"/>
<use xlink:href="#font_0_2" transform="matrix(9.9626,0,0,-9.9626,144.85578,64.70264)" class="fill red"/>
<path transform="matrix(1,0,0,-1,85.578,17.201996)" stroke-width=".3985" stroke-linecap="butt" stroke-miterlimit="10" stroke-linejoin="miter" fill="none" class="stroke" d="M 8.50067 -8.50119 L 34.02216 -34.01901 "/>
<use xlink:href="#font_0_4" transform="matrix(9.9626,0,0,-9.9626,98.147678,105.451999)" class="fill red"/>
<path transform="matrix(1,0,0,-1,85.578,17.201996)" stroke-width=".3985" stroke-linecap="butt" stroke-miterlimit="10" stroke-linejoin="miter" fill="none" class="stroke" d="M 36.8534 -51.02142 L 18.65843 -78.3104 "/>
<use xlink:href="#font_0_3" transform="matrix(9.9626,0,0,-9.9626,154.34255,105.67117)" class="fill blue"/>
<path transform="matrix(1,0,0,-1,85.578,17.201996)" stroke-width=".3985" stroke-linecap="butt" stroke-miterlimit="10" stroke-linejoin="miter" fill="none" class="stroke" d="M 48.1871 -51.02142 L 66.38202 -78.3104 "/>
</g>
</svg>

</figure>
<p>Once again there is also a $\frac{1}{2}$ chance for each MAX node to select the wrong leaf first, in which case both its leaves must be evaluated.</p>
<p>This results in an expected number of leaves to be considered:</p>
<data id="id-2" data-raw></data>
<p>As a tree with a MAX root works the same as a MIN node with all values flipped, it holds that the expected number of leaves to be considered $\mathbb{E}(T_{2,k}) \leq 3^{k}$ for $k=1$.</p>
<h6 id="min-root-0-k--1">MIN root 0, $k &gt; 1$</h6>
<p>We now assume that our statement $\mathbb{E}(T_{2,k-1}) \leq 3^{k-1}$ holds for $k-1$. This case can be thought of and is proved equivalent to the $k=1$ case but each leaf is now another Game Tree $T_{2,k-1}$ instead. Hence, evaluating a leaf instead evaluates $\leq 3^{k-1}$ actual leaves.</p>
<p>Hence, the number of leaves evaluated is given by:</p>
<data id="id-3" data-raw></data>
<h6 id="min-root-1-k--1">MIN root 1, $k &gt; 1$</h6>
<p>The same argument for the equivalence of this case to the case MIN node 1, $k = 1$ holds here as well, with the leaves replaced by smaller Game Trees $T_{2,k-1}$ and the expected number of leaves to be evaluated is then:</p>
<data id="id-4" data-raw></data>
<p>As previously mentioned, the cases for a MAX root can be proved analogously as the MIN cases.</p>
<h3 id="conclusion">Conclusion</h3>
<p>This concludes that in all cases the expected number of leaves that the randomized algorithm has to evaluate is less than or equal to $3^{k}$. Of course the worst case still has to evaluate all leaves.</p>
<p>Using a randomized algorithm it is, thus, possible to achieve an expected number of steps, which is strictly better than the deterministic approach.</p>
<p>For games with a lot of decisions like chess, the randomized algorithm is still much to slow to process the whole tree. In such cases a partial tree that only evaluates to a certain depth can be used. The values of the leaves must then be determined by the state at that time. For example giving each chess piece you hold a value depending on its position and subtracting the score of your opponent.</p>
<h6 id="references">References</h6>
<p>Motwani R. &amp; Raghavan P. (1995). <em>Randomized Algorithms</em></p>]]></description></item><item><title>Some technical information about the Polyring widget</title><link>https://ateon.ch/posts/some-technical-information-about-the-polyring-widgett/</link><pubDate>Tue, 27 Apr 2021 09:03:40 +0200</pubDate><author>Luca Schafroth</author><guid>https://ateon.ch/posts/some-technical-information-about-the-polyring-widgett/</guid><description><![CDATA[<p>As those following the news about the Polyring may have read on <a href="https://xyquadrat.ch/2021/04/24/polyring-widget-theming.html" target="_blank" rel="noopener noreffer ">xyquadrat</a>, our widget can now be styled with themes. For those interested about the inner workings I will provide some technical information here.</p>
<p>The component makes heavy use of <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties" target="_blank" rel="noopener noreffer ">css variables</a> alongside the attribute <code>theme</code>, which can be set on the component. Let&rsquo;s walk through the needed setup, which consists of both javascript code and css descriptions.</p>
<h3 id="javascript-setup">Javascript setup</h3>
<p>Fortunately webcomponents already have the functionally to observe attributes. We can simply declare an attribute as observable using a built-in funciton. This allows for hot-switching instead of only loading the attribute once in the beginning.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-js"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">static</span> <span class="nx">get</span> <span class="nx">observedAttributes</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="k">return</span> <span class="p">[</span><span class="s1">&#39;theme&#39;</span><span class="p">];</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><p>Each time the value changes the triggered event can be observed with yet another built-in method. It&rsquo;s usually a good idea to check for the validity of this <code>newVal</code> and if it actually corresponds to our attribute. This is increasingly important if we observe more than just one attribute.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-js"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">attributeChangedCallback</span><span class="p">(</span><span class="nx">attrName</span><span class="p">,</span> <span class="nx">oldVal</span><span class="p">,</span> <span class="nx">newVal</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span><span class="p">(</span><span class="nx">attrName</span> <span class="o">==</span> <span class="s2">&#34;theme&#34;</span> <span class="o">&amp;&amp;</span> <span class="nx">newVal</span> <span class="o">&amp;&amp;</span> <span class="nx">oldVal</span> <span class="o">!==</span> <span class="nx">newVal</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    	<span class="c1">// act on new theme
</span></span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><p>Using a lookup table we can then handle predefined themes, which makes it easier to embed. If the given value is not found in the table, we assume that it must be an url to an external file.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-js"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">themes</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">default</span><span class="o">:</span> <span class="s2">&#34;assets/themes/default.json&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">dark</span><span class="o">:</span> <span class="s2">&#34;assets/themes/dark.json&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">url</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">themes</span><span class="p">[</span><span class="nx">newVal</span><span class="p">]</span> <span class="o">??</span> <span class="nx">newVal</span><span class="p">;</span></span></span></code></pre></div></div><p>The corresponding internal or external file is then loaded, parsed as json and each css property is updated. You can find an example for such theme file on <a href="https://xyquadrat.ch/polyring/assets/themes/default.json" target="_blank" rel="noopener noreffer ">xyquadrat</a>.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-js"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">fetch</span><span class="p">(</span><span class="nx">url</span><span class="p">).</span><span class="nx">then</span><span class="p">(</span><span class="nx">response</span> <span class="p">=&gt;</span> <span class="nx">response</span><span class="p">.</span><span class="nx">json</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="nx">val</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    	<span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">item</span> <span class="k">in</span> <span class="nx">val</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        	<span class="k">this</span><span class="p">.</span><span class="nx">style</span><span class="p">.</span><span class="nx">setProperty</span><span class="p">(</span><span class="nx">item</span><span class="p">,</span> <span class="nx">val</span><span class="p">[</span><span class="nx">item</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">         <span class="p">}</span>              
</span></span><span class="line"><span class="cl">	<span class="p">}).</span><span class="k">catch</span><span class="p">(</span> <span class="nx">val</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    	<span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">val</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span> 
</span></span></code></pre></div></div><h3 id="css-setup">CSS setup</h3>
<p>A <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties" target="_blank" rel="noopener noreffer ">css variable </a> or css custom property can be used with the <code>var</code> function in css. For example for the webring-banner:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-css"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">.</span><span class="nc">webring-banner</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">background-color</span><span class="p">:</span> <span class="nf">var</span><span class="p">(</span><span class="o">--</span><span class="n">background</span><span class="o">-</span><span class="kc">color</span><span class="p">,</span> <span class="mh">#FFF</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">border</span><span class="p">:</span> <span class="mi">1</span><span class="kt">px</span> <span class="kc">solid</span> <span class="nf">var</span><span class="p">(</span><span class="o">--</span><span class="n">outer</span><span class="o">-</span><span class="n">border</span><span class="o">-</span><span class="kc">color</span><span class="p">,</span> <span class="mh">#DDD</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><p>Take note that <code>var</code>allows passing a default value in the format: <code>var(--my-variable, default_value)</code>, but it is not necessary. Basically every kind of css parameter can be used in a variable, so you could have dynamic borders or even hide an element in one theme. These variables can also be stacked to allow for both broad and specific control:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-css"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">.</span><span class="nc">webring-banner__info</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="k">border</span><span class="p">:</span> <span class="mi">2</span><span class="kt">px</span> <span class="kc">solid</span> <span class="nf">var</span><span class="p">(</span><span class="o">--</span><span class="n">inner</span><span class="o">-</span><span class="n">border</span><span class="o">-</span><span class="kc">color</span><span class="p">,</span> <span class="nf">var</span><span class="p">(</span><span class="o">--</span><span class="n">outer</span><span class="o">-</span><span class="n">border</span><span class="o">-</span><span class="kc">color</span><span class="p">,</span> <span class="mh">#DDD</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><p>Additionally if you&rsquo;re using scss and aren&rsquo;t keen on repeating the same var function for each component that uses these properties, you can integrate them with scss variables:</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-scss"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scss" data-lang="scss"><span class="line"><span class="cl"><span class="nv">$text-color</span><span class="o"> :</span> <span class="nf">var</span><span class="p">(</span><span class="o">--</span><span class="n">core-text-color</span><span class="o">,</span> <span class="no">black</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nc">.text</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="na">color</span><span class="o">:</span> <span class="nv">$text-color</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div><p>Unfortunately these css custom properties can not be used in scss functions like <code>scale-color</code>. As those are parsed at build time, but the value from a css variables is only present at run time. However css variables can be used in css functions like <code>calc</code>.</p>
<h3 id="conclusion">Conclusion</h3>
<p>Css custom properties allow for relatively easy theme support both to your website as well as webcomponents. Many css frameworks like <a href="https://materializecss.com/" target="_blank" rel="noopener noreffer ">Materialize</a> or <a href="https://getbootstrap.com/" target="_blank" rel="noopener noreffer ">Bootstrap</a> make heavy use of css variables to style elements dynamically.</p>]]></description></item><item><title>Using steganography to send messages hidden in an image</title><link>https://ateon.ch/posts/using-steganography-to-send-messages-hidden-in-an-image/</link><pubDate>Mon, 19 Apr 2021 11:17:40 +0200</pubDate><author>Luca Schafroth</author><guid>https://ateon.ch/posts/using-steganography-to-send-messages-hidden-in-an-image/</guid><description><![CDATA[<p>There are multiple ways to send a secret message. The best known and usually used, especially over the internet, is by encrypting the message and later decrypting it.
But it&rsquo;s not the only possibilty. Steganography is the process of hiding information within another carrier medium, fooling everyone else into thinking that the carrier is the only message.</p>
<p>The basic principle ist simple:</p>
<ul>
<li>Add a start and end tag to our message.</li>
<li>Convert the message to a byte string using UTF8.</li>
<li>Overwriting the least significant bits in each pixel with our byte string until the whole message is stored.</li>
</ul>
<p>Let&rsquo;s look at the last step if we want to use the two least significant bits:
As an example we want to store <code>10</code> in a channel that currently stores <code>10100111</code>. First we apply a bit mask with the &lsquo;and&rsquo; operation, then we apply our data with an &lsquo;or&rsquo; operation. This pixel data is then written back into the image.</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-"><span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">	10100111
</span></span><span class="line"><span class="cl">&amp;	11111100
</span></span><span class="line"><span class="cl">|	00000010
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">= 	10100110</span></span></code></pre></div></div><p>If only using the least siginificant bits, the difference can not be seen. Even detecting that the image has been changed is difficult if the original can not be used as a reference.</p>
<p>Here are the <a href="https://github.com/gewlar/steganography" target="_blank" rel="noopener noreffer ">source files</a> if you want to try out the application.</p>
<h3 id="further-reading">Further reading:</h3>
<ul>
<li><a href="https://www.garykessler.net/library/steganography.html" target="_blank" rel="noopener noreffer ">https://www.garykessler.net/library/steganography.html</a></li>
</ul>
]]></description></item></channel></rss>