<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title>Chemaclass - golang</title><subtitle>Tech Lead sharing practical insights on software craftsmanship, TDD, leadership, Bitcoin, and AI. Blog posts, book summaries, and conference talks.</subtitle><link rel="self" type="application/atom+xml" href="https://chemaclass.com/tags/golang/atom.xml"/><link rel="alternate" type="text/html" href="https://chemaclass.com"/><generator uri="https://www.getzola.org/">Zola</generator><updated>2024-04-02T00:00:00+00:00</updated><id>https://chemaclass.com/tags/golang/atom.xml</id><entry xml:lang="en"><title>Learning Concurrency in Golang</title><subtitle>A horse racing emulator explained step by step</subtitle><category term="golang" scheme="https://chemaclass.com/tags/golang/" label="Golang"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><published>2024-04-02T00:00:00+00:00</published><updated>2024-04-02T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/blog/learning-concurrency-in-golang/"/><id>https://chemaclass.com/blog/learning-concurrency-in-golang/</id><summary type="html">I wanted to learn a new programming language, so after trying some, I ended up with Golang as one of my favorites for its simplicity and capabilities. It has features I haven’t used in years, like multithreading and concurrency.</summary><content type="html">&lt;p>I wanted to learn a new language, so after trying some, I ended up with Golang as one of my favorites for its simplicity and capabilities. It has features I haven’t used in years, like multithreading and concurrency.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>&lt;a rel="external" href="https://go.dev/">Golang&lt;/a> (or &lt;code>Go&lt;/code>) supports concurrency through lightweight threads called goroutines. These are different from traditional multithreading, like in Java, where you have to handle sync and coordination to manage shared resources safely. In contrast, Go’s goroutines are lightweight, managed by the Go runtime, and cheaper to create and manage.&lt;/p>
&lt;p>While parallelism is &lt;strong>doing&lt;/strong> several things simultaneously, concurrency is about &lt;strong>dealing&lt;/strong> with several things at the same time. When we talk about concurrency and parallelism, we don’t know the order of things. We don’t know what’s going to happen first or what’s going to end first. There is an undefined order of execution.&lt;/p>
&lt;blockquote>
&lt;p>Imagine you cooking: preparing a soup, a salad and an omelet. You would be one single unit, but you are preparing different dishes. You might finish the salad first or the soup or the omelet… We cannot guarantee that! This would be concurrency, as you are alone dealing with several things. As soon as your partner comes and helps you cook, then we will be talking about parallelism.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="/images/blog/2024-04-02/concurrency-vs-multithreading.jpg" alt="concurrency vs multithreading" />&lt;/p>
&lt;p>I remember building a similar game in &lt;code>Java&lt;/code> when I was learning multithreading ten years ago… let’s use this opportunity to do it again with modern &lt;code>Go&lt;/code>.&lt;/p>
&lt;p>I built a terminal game emulator that mimics one horse racing. Each horse is a goroutine that runs in a shared bidimensional matrix. Once a horse reaches the end, it notifies the shared channel between all other horses (running in different processes) and they all stop, showing in the terminal the winner of the race.&lt;/p>
&lt;p>I separated the code into four areas to help visualize it:&lt;/p>
&lt;ul>
&lt;li>Entry point&lt;/li>
&lt;li>Generating the board&lt;/li>
&lt;li>Rendering the game&lt;/li>
&lt;li>Moving the horses&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="/images/blog/2024-04-02/race-horses-demo.gif" alt="horse racing terminal demo" />&lt;/p>
&lt;h3 id="entry-point">Entry point
&lt;a class="heading-anchor" href="#entry-point" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>The struct &lt;code>Horse&lt;/code> represents each Horse in the race.
The game consists of a list of lines, in which each Horse is running.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="go">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">type&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Horse&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> struct&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> Name&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> string&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> The name of the horse&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> Line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> int&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> The competition line&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span> (&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">h &lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Letter&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> string&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span> fmt&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Sprintf&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">%c&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span> h&lt;/span>&lt;span>.&lt;/span>&lt;span>Name&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">0&lt;/span>&lt;span>]&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span> (&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">h &lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Equals&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">other&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> bool&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span> other&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> !=&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> nil&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;amp;&amp;amp;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> h&lt;/span>&lt;span>.&lt;/span>&lt;span>Line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> ==&lt;/span>&lt;span> other&lt;/span>&lt;span>.&lt;/span>&lt;span>Line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;amp;&amp;amp;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> h&lt;/span>&lt;span>.&lt;/span>&lt;span>Name&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> ==&lt;/span>&lt;span> other&lt;/span>&lt;span>.&lt;/span>&lt;span>Name&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span> (&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">h &lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> String&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> string&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span> fmt&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Sprintf&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">%s&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> (line:&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">%d&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">)&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span> h&lt;/span>&lt;span>.&lt;/span>&lt;span>Name&lt;/span>&lt;span>,&lt;/span>&lt;span> h&lt;/span>&lt;span>.&lt;/span>&lt;span>Line&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>You can spawn a new process using the keyword &lt;code>go&lt;/code> when invoking any function.
In this game, this is used 1) to render the game &lt;code>RenderGame()&lt;/code> and 2) for each horse’s movement &lt;code>startRuningHorseInLine()&lt;/code>. The goal is to keep the “rendering” and “movement logic” working in parallel.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="go">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> main&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> const&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> lines&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> lineLength&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 12&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 30&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span> board&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> NewRaceBoard&lt;/span>&lt;span>(&lt;/span>&lt;span>lines&lt;/span>&lt;span>,&lt;/span>&lt;span> lineLength&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> go&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> RenderGame&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span> winnerChan&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> make&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">chan&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Horse&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> range&lt;/span>&lt;span> board&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> each horse will be moved in different processes&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> go&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> startRunningHorseInLine&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>,&lt;/span>&lt;span> line&lt;/span>&lt;span>,&lt;/span>&lt;span> winnerChan&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> wait until one horse reaches the end&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> winner&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;lt;-&lt;/span>&lt;span>winnerChan&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> render one last time to ensure the latest board state&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> RenderRaceBoard&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;amp;&lt;/span>&lt;span>winner&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span> fmt&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Println&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Race finished!&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> fmt&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Printf&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"># Winner: &lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">%s&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">\n&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span> winner&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="generating-the-board">Generating the board
&lt;a class="heading-anchor" href="#generating-the-board" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>The race board is a bidimensional matrix of pointers to Horses. Each line “contains” only one Horse; aka only one pointer will point to an actual Horse, the rest will be pointers to &lt;code>nil&lt;/code>. During the generation of the Board, we will create one Horse at the first position of each line.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="go">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> NewRaceBoard&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">lines&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);"> lineLength&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> int&lt;/span>&lt;span>)&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> board&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> make&lt;/span>&lt;span>(&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;span> lines&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> range&lt;/span>&lt;span> board&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> make&lt;/span>&lt;span>(&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;span> lineLength&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">0&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;amp;&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> Name&lt;/span>&lt;span>:&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> generateHorseName&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> Line&lt;/span>&lt;span>:&lt;/span>&lt;span> line&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span> board&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>The names are randomly generated using &lt;code>HorseNames&lt;/code>.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="go">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">var&lt;/span>&lt;span> HorseNames&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">2&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">string&lt;/span>&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Alloping&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Giggles&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>}&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">A-lot&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Gallop&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>}&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">BoJack&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Jack&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>}&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Baroness&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Belle&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>}&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ...&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> generateHorseName&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> string&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> name&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span> HorseNames&lt;/span>&lt;span>[&lt;/span>&lt;span>rand&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Intn&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">len&lt;/span>&lt;span>(&lt;/span>&lt;span>HorseNames&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">0&lt;/span>&lt;span>]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> surname&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span> HorseNames&lt;/span>&lt;span>[&lt;/span>&lt;span>rand&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Intn&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">len&lt;/span>&lt;span>(&lt;/span>&lt;span>HorseNames&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span> name&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> +&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> +&lt;/span>&lt;span> surname&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="rendering-the-game">Rendering the game
&lt;a class="heading-anchor" href="#rendering-the-game" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Then &lt;code>RenderGame()&lt;/code>, &lt;code>renderRaceBoard()&lt;/code>, &lt;code>renderRaceLine()&lt;/code> and &lt;code>renderRacePosition()&lt;/code> are separated to help focus on each method’s responsibility, identifying what is the subject to be rendered.&lt;/p>
&lt;blockquote>
&lt;p>&lt;code>RenderGame()&lt;/code> is being executed in another process using &lt;code>go&lt;/code>.&lt;/p>
&lt;/blockquote>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="go">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> RenderGame&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">board&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> time&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Sleep&lt;/span>&lt;span>(&lt;/span>&lt;span>renderDelay&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span> time&lt;/span>&lt;span>.&lt;/span>&lt;span>Millisecond&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> RenderRaceBoard&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> nil&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> RenderRaceBoard&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">board&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);"> winner&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> use a &amp;quot;string buffer&amp;quot; to save the whole board state&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> so we can later use one IO call to render it&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> var&lt;/span>&lt;span> buffer&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> bytes&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Buffer&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">\n&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> range&lt;/span>&lt;span> board&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> renderRaceLine&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>,&lt;/span>&lt;span> line&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;amp;&lt;/span>&lt;span>buffer&lt;/span>&lt;span>,&lt;/span>&lt;span> winner&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> clearScreen&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> fmt&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Println&lt;/span>&lt;span>(&lt;/span>&lt;span>buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">String&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> clearScreen&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> cmd&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span> exec&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Command&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">clear&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> cmd&lt;/span>&lt;span>.&lt;/span>&lt;span>Stdout&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> os&lt;/span>&lt;span>.&lt;/span>&lt;span>Stdout&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> cmd&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Run&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> renderRaceLine&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> board&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> int&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> buffer&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">bytes&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Buffer&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> winner&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span>fmt&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Sprintf&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> %.2d&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> | &lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span> line&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> var&lt;/span>&lt;span> current&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Horse&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> range&lt;/span>&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> h&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> renderRacePosition&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>,&lt;/span>&lt;span> line&lt;/span>&lt;span>,&lt;/span>&lt;span> col&lt;/span>&lt;span>,&lt;/span>&lt;span> buffer&lt;/span>&lt;span>,&lt;/span>&lt;span> winner&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> if&lt;/span>&lt;span> h&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> !=&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> nil&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> current&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span>h&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span>fmt&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Sprintf&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">| &lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">%s&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>,&lt;/span>&lt;span> current&lt;/span>&lt;span>.&lt;/span>&lt;span>Name&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> if&lt;/span>&lt;span> current&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Equals&lt;/span>&lt;span>(&lt;/span>&lt;span>winner&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> [Won!]&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">\n&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> renderRacePosition&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> board&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> line&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);"> col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> int&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> buffer&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">bytes&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Buffer&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#E36209, #FFAB70);"> winner&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> if&lt;/span>&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>col&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> ==&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> nil&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> nil&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span> current&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>col&lt;/span>&lt;span>]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> if&lt;/span>&lt;span> current&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Equals&lt;/span>&lt;span>(&lt;/span>&lt;span>winner&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> removeChars&lt;/span>&lt;span>(&lt;/span>&lt;span>buffer&lt;/span>&lt;span>,&lt;/span>&lt;span> col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">+&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> range&lt;/span>&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">-&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span> buffer&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">WriteString&lt;/span>&lt;span>(&lt;/span>&lt;span>current&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Letter&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span> current&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="moving-the-horses">Moving the horses
&lt;a class="heading-anchor" href="#moving-the-horses" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>In &lt;code>main(...)&lt;/code>, the &lt;code>winnerChan&lt;/code> is a shared channel that will be used by the first Horse reaching the last position in their line.&lt;/p>
&lt;p>Each Horse will run a loop until reaching the end of the line OR receiving (via the shared channel &lt;code>winnerChan&lt;/code>) the message that another Horse already won the race. Until then, each horse will move independently by randomly sleeping milliseconds before moving to the next position in their line.&lt;/p>
&lt;blockquote>
&lt;p>&lt;code>startRuningHorseInLine()&lt;/code> runs in another process using &lt;code>go&lt;/code>.&lt;/p>
&lt;/blockquote>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="go">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> main&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">...&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> winnerChan&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> make&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">chan&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Horse&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> range&lt;/span>&lt;span> board&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> each horse will be moved in different processes&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> go&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> startHorseRunning&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>,&lt;/span>&lt;span> line&lt;/span>&lt;span>,&lt;/span>&lt;span> winnerChan&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> wait until one horse reaches the end&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> winner&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;lt;-&lt;/span>&lt;span>winnerChan&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">...&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> startRunningHorseInLine&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">board&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);"> line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> int&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);"> winnerChan&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> chan&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Horse&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> select&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> case&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;lt;-&lt;/span>&lt;span>winnerChan&lt;/span>&lt;span>:&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> check if another horse finished&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> in such a case, then stop the for loop&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> default&lt;/span>&lt;span>:&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> time&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Sleep&lt;/span>&lt;span>(&lt;/span>&lt;span>time&lt;/span>&lt;span>.&lt;/span>&lt;span>Millisecond&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span> time&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Duration&lt;/span>&lt;span>(&lt;/span>&lt;span>rand&lt;/span>&lt;span>.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Intn&lt;/span>&lt;span>(&lt;/span>&lt;span>maxSleepDelay&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> moveHorseOnePos&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>,&lt;/span>&lt;span> line&lt;/span>&lt;span>,&lt;/span>&lt;span> winnerChan&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">func&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> moveHorseOnePos&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);">board&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">*&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">Horse&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);"> line&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> int&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#E36209, #FFAB70);"> winnerChan&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> chan&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> Horse&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> cols&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> len&lt;/span>&lt;span>(&lt;/span>&lt;span>board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> for&lt;/span>&lt;span> col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> :=&lt;/span>&lt;span> cols&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> -&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 1&lt;/span>&lt;span>;&lt;/span>&lt;span> col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;gt;&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 0&lt;/span>&lt;span>;&lt;/span>&lt;span> col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">--&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> if&lt;/span>&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">-&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> ==&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> nil&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> continue&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> here we identify that there is a horse in&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> the following column, so we move it to the&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> current column, and we set `nil` the other one&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>col&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">-&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">-&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>]&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> nil&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> if&lt;/span>&lt;span> col&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">+&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> ==&lt;/span>&lt;span> cols&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> winnerChan&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;lt;-&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> *&lt;/span>&lt;span>board&lt;/span>&lt;span>[&lt;/span>&lt;span>line&lt;/span>&lt;span>]&lt;/span>&lt;span>[&lt;/span>&lt;span>col&lt;/span>&lt;span>]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> break&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="source-code">Source code
&lt;a class="heading-anchor" href="#source-code" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>The code displayed in this post is a simplified version, so if you would like to check the working source, you can do it here: &lt;a rel="external" href="https://github.com/Chemaclass/go-horse-racing">Chemaclass/go-horse-racing&lt;/a>.&lt;/p>
&lt;aside class="kudos">
&lt;span class="kudos__icon" aria-hidden="true">🧠&lt;/span>
&lt;div class="kudos__content">
&lt;p>Thanks to my former Team Lead, Andrei Boar, who helped me review my first original solution and provided an &lt;a rel="external" href="https://gist.github.com/zuzuleinen/79413aa7933d7d6c6d84ec6ba8c3910a">alternative solution&lt;/a> (simpler and better!), which I applied to my original code. The main learning was using a &lt;code>chan Horse&lt;/code> to pass the winner Horse from &lt;code>main()&lt;/code>, instead of using a &lt;code>chan bool&lt;/code> and a &lt;code>sync.WaitGroup&lt;/code> between all threads.&lt;/p>
&lt;/div>
&lt;/aside></content></entry></feed>