<?xml version="1.0" encoding="UTF-8"?>
<rss version='2.0' xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Simo Råman</title>
    <description>Software professional with a passion for quality. Likes TDD and working in agile teams. Has worked with wide-range of technologies, backend and frontend, from C++ to Javascript. Currently very interested in functional programming.</description>
    <link>https://simoraman.com/feed</link>
    <atom:link href="https://simoraman.com/feed" rel="self" type="application/rss+xml"/>
    <category domain="simoraman.com">Content Management/Blog</category>
    <language>en-us</language>
      <pubDate>Tue, 19 May 2015 05:15:00 -1200</pubDate>
    <managingEditor>simoraman@gmail.com (Simo Råman)</managingEditor>
      <item>
        <guid>http://simoraman.com/building-roguelike-in-f#14401</guid>
          <pubDate>Tue, 19 May 2015 05:15:00 -1200</pubDate>
        <link>http://simoraman.com/building-roguelike-in-f</link>
        <title>Building Roguelike in F#</title>
        <description></description>
        <content:encoded><![CDATA[<p><img alt="Silvrback blog image" src="https://silvrback.s3.amazonaws.com/uploads/92bdd1c6-220a-411c-b4c1-385eb7874416/Screen%20Shot%202015-05-15%20at%2010.40.02%20_large.png" /></p>

<p>I know many people who started programming because they wanted to write a game of their own. I myself had never done game programming but after I ran into articles about programming <a href="http://en.wikipedia.org/wiki/Roguelike">a roguelike</a> in <a href="http://jamiltron.com/2012/07/Code_Us_Some_Roguelike_in_Haskell.html">Haskell</a> I decided to give it a try using F#.</p>

<p>First I wanted to get hero to move around on map. </p>

<p>These are the types I came up with:</p>
<div class="highlight"><pre><span></span><span class="k">namespace</span> <span class="n">SharpRogue</span>
<span class="k">module</span> <span class="nn">Types</span> <span class="o">=</span>
    <span class="k">type</span> <span class="nc">Coordinate</span> <span class="o">=</span> <span class="o">{</span> <span class="n">x</span><span class="o">:</span><span class="n">int</span><span class="o">;</span> <span class="n">y</span><span class="o">:</span><span class="n">int</span><span class="o">;</span> <span class="o">}</span>

    <span class="k">type</span> <span class="nc">Hero</span> <span class="o">=</span> <span class="o">{</span>
        <span class="n">currentPosition</span> <span class="o">:</span> <span class="n">Coordinate</span><span class="o">;</span>
        <span class="n">oldPosition</span> <span class="o">:</span> <span class="n">Coordinate</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="k">type</span> <span class="nc">MapTile</span> <span class="o">=</span> <span class="o">{</span>
        <span class="n">coordinate</span> <span class="o">:</span> <span class="n">Coordinate</span><span class="o">;</span>
        <span class="n">tile</span> <span class="o">:</span> <span class="kt">char</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="k">type</span> <span class="nc">World</span> <span class="o">=</span> <span class="o">{</span>
        <span class="n">tiles</span> <span class="o">:</span> <span class="n">MapTile</span> <span class="kt">list</span>
        <span class="n">hero</span> <span class="o">:</span> <span class="n">Hero</span>
    <span class="o">}</span>

    <span class="k">type</span> <span class="nc">Input</span> <span class="o">=</span> 
        <span class="n">Up</span> 
        <span class="o">|</span> <span class="n">Down</span>
        <span class="o">|</span> <span class="n">Left</span>
        <span class="o">|</span> <span class="n">Right</span>
        <span class="o">|</span> <span class="n">Open</span>
        <span class="o">|</span> <span class="n">Exit</span>
</pre></div>
<p>Game World consists of MapTiles and Hero. MapTile has a coordinate in the world and a char that symbolises content of the tile, for example symbol for wall is &#39;#&#39;. Hero has data of it&#39;s location(currentPosition) and location on previous turn(oldPosition).  Input is a discriminated union of the possible inputs from the player.</p>
<div class="highlight"><pre><span></span><span class="c1">// Graphics.fs</span>
<span class="k">let</span> <span class="nv">hideCursor</span><span class="bp">()</span> <span class="o">=</span> <span class="nn">System</span><span class="p">.</span><span class="nn">Console</span><span class="p">.</span><span class="n">SetCursorPosition</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span><span class="mi">0</span><span class="o">)</span>

<span class="k">let</span> <span class="nv">drawHero</span> <span class="o">(</span><span class="n">hero</span><span class="o">:</span><span class="n">Hero</span><span class="o">,</span> <span class="n">world</span><span class="o">:</span><span class="n">MapTile</span> <span class="kt">list</span><span class="o">)</span> <span class="o">=</span> 
    <span class="nn">System</span><span class="p">.</span><span class="nn">Console</span><span class="p">.</span>
        <span class="n">SetCursorPosition</span><span class="o">(</span><span class="n">hero</span><span class="o">.</span><span class="n">currentPosition</span><span class="o">.</span><span class="n">x</span><span class="o">,</span> <span class="n">hero</span><span class="o">.</span><span class="n">currentPosition</span><span class="o">.</span><span class="n">y</span><span class="o">)</span>
    <span class="nn">System</span><span class="p">.</span><span class="nn">Console</span><span class="p">.</span><span class="n">Write</span> <span class="sc">&#39;@&#39;</span>
    <span class="k">let</span> <span class="nv">found</span> <span class="o">=</span> <span class="nn">List</span><span class="p">.</span><span class="n">find</span> <span class="o">(</span><span class="nn">Utils</span><span class="p">.</span><span class="n">findTile</span> <span class="n">hero</span><span class="o">.</span><span class="n">oldPosition</span><span class="o">)</span> <span class="n">world</span>
    <span class="nn">System</span><span class="p">.</span><span class="nn">Console</span><span class="p">.</span>
        <span class="n">SetCursorPosition</span><span class="o">(</span><span class="n">hero</span><span class="o">.</span><span class="n">oldPosition</span><span class="o">.</span><span class="n">x</span><span class="o">,</span> <span class="n">hero</span><span class="o">.</span><span class="n">oldPosition</span><span class="o">.</span><span class="n">y</span><span class="o">)</span>
    <span class="n">found</span><span class="o">.</span><span class="n">tile</span> <span class="o">|&gt;</span> <span class="nn">System</span><span class="p">.</span><span class="nn">Console</span><span class="p">.</span><span class="n">Write</span>
    <span class="n">hideCursor</span><span class="bp">()</span>

<span class="k">let</span> <span class="nv">drawTile</span> <span class="o">(</span><span class="n">tile</span><span class="o">:</span><span class="n">MapTile</span><span class="o">)</span> <span class="o">=</span> 
    <span class="nn">System</span><span class="p">.</span><span class="nn">Console</span><span class="p">.</span>
        <span class="n">SetCursorPosition</span><span class="o">(</span><span class="n">tile</span><span class="o">.</span><span class="n">coordinate</span><span class="o">.</span><span class="n">x</span><span class="o">,</span> <span class="n">tile</span><span class="o">.</span><span class="n">coordinate</span><span class="o">.</span><span class="n">y</span><span class="o">)</span>
    <span class="nn">System</span><span class="p">.</span><span class="nn">Console</span><span class="p">.</span><span class="n">Write</span> <span class="n">tile</span><span class="o">.</span><span class="n">tile</span>

<span class="k">let</span> <span class="nv">drawWorld</span> <span class="n">world</span> <span class="o">=</span> 
    <span class="nn">System</span><span class="p">.</span><span class="nn">Console</span><span class="p">.</span><span class="n">Clear</span><span class="bp">()</span>
    <span class="nn">List</span><span class="p">.</span><span class="n">map</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="o">-&gt;</span> <span class="n">drawTile</span><span class="o">(</span><span class="n">x</span><span class="o">))</span> <span class="n">world</span> <span class="o">|&gt;</span> <span class="n">ignore</span>

<span class="k">let</span> <span class="nv">drawOpenDoor</span> <span class="n">coordinate</span> <span class="o">=</span>
    <span class="nn">System</span><span class="p">.</span><span class="nn">Console</span><span class="p">.</span><span class="n">SetCursorPosition</span><span class="o">(</span><span class="n">coordinate</span><span class="o">.</span><span class="n">x</span><span class="o">,</span> <span class="n">coordinate</span><span class="o">.</span><span class="n">y</span><span class="o">)</span>
    <span class="nn">System</span><span class="p">.</span><span class="nn">Console</span><span class="p">.</span><span class="n">Write</span> <span class="sc">&#39;-&#39;</span>
    <span class="n">hideCursor</span><span class="bp">()</span>
</pre></div>
<p>Since my roguelike is basically a console app the &quot;graphics&quot; module deals with writing out chars on the correct coordinate in the console. HideCursor-function is used to set cursor on the upper left corner of screen. Otherwise it will stay where a character has been written last. drawHero draws the @-character representing hero in currentPosition of hero record. Original tile from world record will replace @-character in oldPosition of hero. Originally I reprinted whole map after every move, but that caused screen to flicker. </p>

<p>The game logic is located in the Program.fs-file. Starting at the main function:</p>
<div class="highlight"><pre><span></span><span class="o">[&lt;</span><span class="n">EntryPoint</span><span class="o">&gt;]</span>
<span class="k">let</span> <span class="nv">main</span> <span class="n">argv</span> <span class="o">=</span> 
    <span class="n">generateCoordinates</span> <span class="o">|&gt;</span> <span class="n">drawWorld</span>
    <span class="k">let</span> <span class="nv">world</span> <span class="o">=</span> <span class="o">{</span>
        <span class="n">hero</span> <span class="o">=</span> <span class="o">{</span> 
                <span class="n">oldPosition</span> <span class="o">=</span> <span class="o">{</span><span class="n">x</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span> <span class="n">y</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;};</span> 
                <span class="n">currentPosition</span> <span class="o">=</span> <span class="o">{</span><span class="n">x</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span> <span class="n">y</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;};</span> 
        <span class="o">};</span> 
        <span class="n">tiles</span> <span class="o">=</span> <span class="n">generateCoordinates</span>
    <span class="o">}</span>
    <span class="n">gameLoop</span> <span class="n">world</span>
    <span class="mi">0</span> <span class="c1">// return an integer exit code</span>
</pre></div>
<p>GenerateCoordinates breaks  level map into coordinates and tiles. World initialized with hero starting from the top left corner.</p>

<p>GameLoop is a recursive function that draws hero, gets player input and calls gameLoop again with new state of the world.</p>
<div class="highlight"><pre><span></span><span class="k">let</span> <span class="nv">rec</span> <span class="n">gameLoop</span> <span class="n">world</span> <span class="o">=</span>
    <span class="n">drawHero</span> <span class="o">(</span><span class="n">world</span><span class="o">.</span><span class="n">hero</span><span class="o">,</span> <span class="n">world</span><span class="o">.</span><span class="n">tiles</span><span class="o">)</span>
    <span class="k">let</span> <span class="nv">input</span> <span class="o">=</span> <span class="n">getInput</span><span class="bp">()</span>
    <span class="k">match</span> <span class="n">input</span> <span class="k">with</span>
        <span class="o">|</span> <span class="n">Exit</span> <span class="o">-&gt;</span> <span class="bp">()</span>
        <span class="o">|</span> <span class="n">Open</span> <span class="o">-&gt;</span> <span class="n">openDoor</span> <span class="n">world</span><span class="o">.</span><span class="n">hero</span> <span class="n">world</span> <span class="o">|&gt;</span> <span class="n">gameLoop</span>
        <span class="o">|</span> <span class="o">_</span> <span class="o">-&gt;</span> <span class="o">{</span><span class="n">world</span> <span class="k">with</span> <span class="n">hero</span> <span class="o">=</span> <span class="o">(</span><span class="n">move</span> <span class="n">input</span> <span class="n">world</span><span class="o">);}</span> <span class="o">|&gt;</span> <span class="n">gameLoop</span> 
</pre></div>
<p>Move returns hero with updated coordinates. Movement is allowed if the wanted location is not a wall(#) or a closed door(+). OpenDoor replaces closed door(+) located next to the hero in the given direction with an open door(-).</p>
<div class="highlight"><pre><span></span><span class="k">let</span> <span class="nv">move</span> <span class="n">direction</span> <span class="n">world</span> <span class="o">=</span> 
    <span class="k">let</span> <span class="nv">hero</span> <span class="o">=</span> <span class="n">world</span><span class="o">.</span><span class="n">hero</span>
    <span class="k">let</span> <span class="nv">newCoordinates</span> <span class="o">=</span> <span class="n">getNextCoordinate</span> <span class="n">hero</span> <span class="n">direction</span>
    <span class="k">let</span> <span class="nv">found</span> <span class="o">=</span> <span class="nn">List</span><span class="p">.</span><span class="n">find</span> <span class="o">(</span><span class="nn">Utils</span><span class="p">.</span><span class="n">findTile</span> <span class="n">newCoordinates</span><span class="o">)</span> <span class="n">world</span><span class="o">.</span><span class="n">tiles</span>   
    <span class="k">match</span> <span class="n">found</span><span class="o">.</span><span class="n">tile</span> <span class="k">with</span>
        <span class="o">|</span> <span class="sc">&#39;#&#39;</span> <span class="o">-&gt;</span> <span class="n">hero</span>
        <span class="o">|</span> <span class="sc">&#39;+&#39;</span> <span class="o">-&gt;</span> <span class="n">hero</span>         
        <span class="o">|</span> <span class="o">_</span> <span class="o">-&gt;</span> <span class="o">{</span><span class="n">hero</span> <span class="k">with</span> <span class="n">currentPosition</span> <span class="o">=</span> <span class="n">newCoordinates</span><span class="o">;</span> 
                <span class="n">oldPosition</span> <span class="o">=</span> <span class="n">hero</span><span class="o">.</span><span class="n">currentPosition</span><span class="o">}</span> 


<span class="k">let</span> <span class="nv">openDoor</span> <span class="n">hero</span> <span class="n">world</span> <span class="o">=</span> 
    <span class="k">let</span> <span class="nv">direction</span> <span class="o">=</span> <span class="n">getInput</span><span class="bp">()</span>
    <span class="k">let</span> <span class="nv">coordinate</span> <span class="o">=</span> <span class="n">getNextCoordinate</span> <span class="n">hero</span> <span class="n">direction</span>
    <span class="k">let</span> <span class="nv">tile</span> <span class="o">=</span> <span class="nn">List</span><span class="p">.</span><span class="n">find</span> <span class="o">(</span><span class="nn">Utils</span><span class="p">.</span><span class="n">findTile</span> <span class="n">coordinate</span><span class="o">)</span> <span class="n">world</span><span class="o">.</span><span class="n">tiles</span>
    <span class="k">if</span> <span class="n">tile</span><span class="o">.</span><span class="n">tile</span> <span class="o">=</span> <span class="sc">&#39;+&#39;</span> <span class="k">then</span> <span class="n">drawOpenDoor</span> <span class="n">tile</span><span class="o">.</span><span class="n">coordinate</span>
    <span class="k">let</span> <span class="nv">newTiles</span> <span class="o">=</span> <span class="nn">List</span><span class="p">.</span><span class="n">map</span> 
        <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="o">-&gt;</span> 
            <span class="k">if</span> <span class="n">x</span><span class="o">.</span><span class="n">coordinate</span> <span class="o">=</span> <span class="n">coordinate</span> <span class="k">then</span> <span class="o">{</span> <span class="n">x</span> <span class="k">with</span> <span class="n">tile</span> <span class="o">=</span> <span class="sc">&#39;-&#39;</span><span class="o">}</span> 
            <span class="k">else</span> <span class="n">x</span><span class="o">)</span> <span class="n">world</span><span class="o">.</span><span class="n">tiles</span>
    <span class="o">{</span><span class="n">world</span> <span class="k">with</span> <span class="n">hero</span> <span class="o">=</span> <span class="n">hero</span><span class="o">;</span> <span class="n">tiles</span> <span class="o">=</span> <span class="n">newTiles</span><span class="o">}</span>
</pre></div>
<p>Here is the amazing result!</p>

<p><img alt="Silvrback blog image" src="https://silvrback.s3.amazonaws.com/uploads/974a3e84-c7b8-46ee-8a89-ebebe8eaedbe/BYtaRL0jle_large.gif" /></p>

<p>Not quite Nethack yet, but we&#39;ll see what features future brings. The codes for SharpRogue can be found on <a href="https://github.com/simoraman/SharpRogue/tree/eaf6145d4b6c185c61b03638295f174adb87c819">GitHub</a>.</p>
]]></content:encoded>
      </item>
      <item>
        <guid>http://simoraman.com/generating-music-in-f-note-values#13321</guid>
          <pubDate>Sat, 04 Apr 2015 22:36:00 -1200</pubDate>
        <link>http://simoraman.com/generating-music-in-f-note-values</link>
        <title>Generating music in F# part 3: Note values</title>
        <description></description>
        <content:encoded><![CDATA[<p>Previous posts in series:<br>
<a href="http://www.simoraman.com/generating-music-with-f">Part 1</a><br>
<a href="http://www.simoraman.com/generating-music-with-f-part-2-markov-chains">Part 2</a></p>

<p>After last post the program can generate melodies using Markov chains generated from seed data. Next important aspect of a catchy melody is note value. Note value means a relative duration of a note. </p>

<p>Just like notes note values are modelled as a type:</p>
<div class="highlight"><pre><span></span><span class="k">type</span> <span class="nc">value</span> <span class="o">=</span>
    <span class="o">|</span> <span class="n">Full</span>
    <span class="o">|</span> <span class="n">Half</span>
    <span class="o">|</span> <span class="n">Quarter</span>
    <span class="o">|</span> <span class="n">Eighth</span>
</pre></div>
<p>The actual duration of a note value in seconds is relative to tempo. A map of durations for values can be created using this function:</p>
<div class="highlight"><pre><span></span><span class="k">let</span> <span class="nv">time</span> <span class="n">beatsPerMinute</span> <span class="o">=</span>
    <span class="k">let</span> <span class="nv">quarterLength</span> <span class="o">=</span> <span class="mi">60</span><span class="o">.</span> <span class="o">/</span> <span class="n">beatsPerMinute</span>     
    <span class="nn">Map</span><span class="p">.</span><span class="n">ofList</span> <span class="o">[</span>
    <span class="o">(</span><span class="n">Eighth</span><span class="o">,</span> <span class="mi">0</span><span class="o">.</span><span class="mi">5</span> <span class="o">*</span> <span class="n">quarterLength</span><span class="o">);</span> 
    <span class="o">(</span><span class="n">Quarter</span><span class="o">,</span> <span class="n">quarterLength</span><span class="o">);</span> 
    <span class="o">(</span><span class="n">Half</span><span class="o">,</span> <span class="mi">2</span><span class="o">.</span> <span class="o">*</span> <span class="n">quarterLength</span><span class="o">);</span>
    <span class="o">(</span><span class="n">Full</span><span class="o">,</span> <span class="mi">4</span><span class="o">.</span> <span class="o">*</span> <span class="n">quarterLength</span><span class="o">)]</span>
</pre></div>
<p>Beats per minute(bpm) means the amount of quarter notes in a minute. Dividing minute(60 seconds) with bpm yields length of quarter note in seconds. Other time values can be counted from that quarter note value.</p>

<p>I wanted some more complex seed data: </p>
<div class="highlight"><pre><span></span><span class="k">let</span> <span class="nv">yesterday</span> <span class="o">=</span> 
    <span class="o">[(</span><span class="n">G</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">F</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">F</span><span class="o">,</span> <span class="n">Half</span><span class="o">);</span>
    <span class="o">(</span><span class="n">A</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">B</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);(</span><span class="n">Cis</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">D</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">E</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);(</span><span class="n">F</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span>
    <span class="o">(</span><span class="n">E</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">D</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">D</span><span class="o">,</span> <span class="n">Half</span><span class="o">);</span>
    <span class="o">(</span><span class="n">D</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">D</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">C</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">Ais</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">A</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">G</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span>
    <span class="o">(</span><span class="n">Ais</span><span class="o">,</span> <span class="n">Quarter</span><span class="o">);</span> <span class="o">(</span><span class="n">A</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">A</span><span class="o">,</span> <span class="n">Quarter</span><span class="o">);</span> <span class="o">(</span><span class="n">G</span><span class="o">,</span> <span class="n">Quarter</span><span class="o">);</span>
    <span class="o">(</span><span class="n">F</span><span class="o">,</span> <span class="n">Quarter</span><span class="o">);</span> <span class="o">(</span><span class="n">A</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">G</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">G</span><span class="o">,</span> <span class="n">Quarter</span><span class="o">);</span> <span class="o">(</span><span class="n">D</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span>
    <span class="o">(</span><span class="n">F</span><span class="o">,</span> <span class="n">Quarter</span><span class="o">);</span> <span class="o">(</span><span class="n">A</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">A</span><span class="o">,</span> <span class="n">Eighth</span><span class="o">);</span> <span class="o">(</span><span class="n">A</span><span class="o">,</span> <span class="n">Half</span><span class="o">);]</span>
</pre></div>
<p>Melody is now represented as list of tuples of note and value. Both types will have their own Markov chain structure </p>
<div class="highlight"><pre><span></span><span class="k">let</span> <span class="nv">createMarkovChains</span> <span class="n">data</span> <span class="o">=</span>
    <span class="n">data</span>
    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">windowed</span> <span class="mi">2</span>
    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">groupBy</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="o">-&gt;</span> <span class="n">x</span><span class="o">.[</span><span class="mi">0</span><span class="o">])</span>
    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">map</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="o">-&gt;</span> 
           <span class="o">(</span><span class="n">fst</span> <span class="n">x</span><span class="o">,</span> 
            <span class="n">x</span>
            <span class="o">|&gt;</span> <span class="n">snd</span>
            <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">map</span> <span class="o">(</span><span class="nn">Seq</span><span class="p">.</span><span class="n">nth</span> <span class="mi">1</span><span class="o">)))</span>
    <span class="o">|&gt;</span> <span class="nn">Map</span><span class="p">.</span><span class="n">ofSeq</span>

<span class="k">let</span> <span class="nv">noteData</span> <span class="o">=</span> 
    <span class="n">yesterday</span>
    <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">map</span><span class="o">(</span><span class="n">fst</span><span class="o">)</span>
    <span class="o">|&gt;</span> <span class="n">createMarkovChains</span>

<span class="k">let</span> <span class="nv">timingsData</span> <span class="o">=</span>
    <span class="n">yesterday</span>
    <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">map</span><span class="o">(</span><span class="n">snd</span><span class="o">)</span>
    <span class="o">|&gt;</span> <span class="n">createMarkovChains</span>
</pre></div>
<p>Creation of random sequence is not dependent of the type of item in this case. Functions can be made more generic by removing type declarations referring to note-type. </p>
<div class="highlight"><pre><span></span><span class="k">let</span> <span class="nv">getNextElement</span> <span class="o">(</span><span class="n">random</span> <span class="o">:</span> <span class="nn">System</span><span class="p">.</span><span class="n">Random</span><span class="o">)</span> <span class="o">(</span><span class="n">data</span> <span class="o">:</span> <span class="n">Map</span><span class="o">&lt;_,_&gt;)</span> <span class="n">currentElement</span> <span class="o">=</span> 
    <span class="k">let</span> <span class="nv">nextSet</span> <span class="o">=</span> <span class="n">data</span><span class="o">.[</span><span class="n">currentElement</span><span class="o">]</span>
    <span class="k">let</span> <span class="nv">nextElementIndex</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">Next</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">length</span> <span class="n">nextSet</span><span class="o">)</span>
    <span class="n">nextSet</span>
    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">skip</span> <span class="n">nextElementIndex</span>
    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">head</span>

<span class="k">let</span> <span class="nv">r</span> <span class="o">=</span> <span class="nn">System</span><span class="p">.</span><span class="n">Random</span><span class="bp">()</span>
<span class="k">let</span> <span class="nv">nextElementFromData</span> <span class="n">x</span> <span class="n">y</span> <span class="o">=</span> <span class="n">getNextElement</span> <span class="n">r</span> <span class="n">x</span> <span class="n">y</span>

<span class="k">let</span> <span class="nv">rec</span> <span class="n">randomSequence</span> <span class="n">wantedLength</span> <span class="n">seedData</span> <span class="n">currentElement</span> <span class="o">(</span><span class="n">acc</span> <span class="o">:</span> <span class="k">&#39;</span><span class="n">a</span> <span class="kt">list</span><span class="o">)</span> <span class="o">=</span> 
    <span class="k">if</span> <span class="n">acc</span><span class="o">.</span><span class="n">Length</span> <span class="o">=</span> <span class="n">wantedLength</span> <span class="k">then</span> <span class="n">acc</span>
    <span class="k">else</span> 
        <span class="k">let</span> <span class="nv">nextElement</span> <span class="o">=</span> <span class="n">nextElementFromData</span> <span class="n">seedData</span> <span class="n">currentElement</span>
        <span class="n">randomSequence</span> <span class="n">wantedLength</span> <span class="n">seedData</span> <span class="n">nextElement</span> <span class="o">(</span><span class="n">acc</span> <span class="o">@</span> <span class="o">[</span> <span class="n">nextElement</span> <span class="o">])</span>
</pre></div>
<p>Here is the main now:</p>
<div class="highlight"><pre><span></span><span class="o">[&lt;</span><span class="n">EntryPoint</span><span class="o">&gt;]</span>
<span class="k">let</span> <span class="nv">main</span> <span class="n">argv</span> <span class="o">=</span> 
    <span class="k">let</span> <span class="nv">availableNotes</span> <span class="o">=</span> 
        <span class="n">noteData</span> <span class="o">|&gt;</span> <span class="nn">Map</span><span class="p">.</span><span class="n">toSeq</span> <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">map</span> <span class="n">fst</span> <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">ofSeq</span>
    <span class="k">let</span> <span class="nv">firstNote</span> <span class="o">=</span> <span class="n">availableNotes</span><span class="o">.[</span><span class="n">r</span><span class="o">.</span><span class="n">Next</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="n">availableNotes</span><span class="o">.</span><span class="n">Length</span><span class="o">)]</span>
    <span class="k">let</span> <span class="nv">melody</span> <span class="o">=</span> <span class="n">randomSequence</span> <span class="mi">24</span> <span class="n">noteData</span> <span class="n">firstNote</span> <span class="o">[</span> <span class="n">firstNote</span> <span class="o">]</span> 
                    <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">map</span><span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="o">-&gt;</span> <span class="n">frequency</span><span class="o">.[</span><span class="n">x</span><span class="o">])</span>

    <span class="k">let</span> <span class="nv">timingsForTempo</span> <span class="o">=</span> <span class="o">(</span><span class="n">time</span> <span class="mi">120</span><span class="o">.)</span>
    <span class="k">let</span> <span class="nv">availableTimes</span> <span class="o">=</span> 
        <span class="n">timingsData</span> <span class="o">|&gt;</span> <span class="nn">Map</span><span class="p">.</span><span class="n">toSeq</span> <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">map</span> <span class="n">fst</span> <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">ofSeq</span>
    <span class="k">let</span> <span class="nv">firstTime</span> <span class="o">=</span> <span class="n">availableTimes</span><span class="o">.[</span><span class="n">r</span><span class="o">.</span><span class="n">Next</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="n">availableTimes</span><span class="o">.</span><span class="n">Length</span><span class="o">)]</span>
    <span class="k">let</span> <span class="nv">timings</span> <span class="o">=</span> <span class="n">randomSequence</span> <span class="mi">24</span> <span class="n">timingsData</span> <span class="n">firstTime</span> <span class="o">[</span> <span class="n">firstTime</span> <span class="o">]</span> 
                    <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">map</span><span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="o">-&gt;</span> <span class="n">timingsForTempo</span><span class="o">.[</span><span class="n">x</span><span class="o">])</span>

    <span class="nn">List</span><span class="p">.</span><span class="n">zip</span> <span class="n">melody</span> <span class="n">timings</span> <span class="o">|&gt;</span> <span class="nn">Synth</span><span class="p">.</span><span class="n">writeMelody</span>
    <span class="mi">0</span>
</pre></div>
<p>Random sequences are created for both notes and time values. Then they are zipped into list of tuples and written to wav-file.</p>

<p>Full source on <a href="https://github.com/simoraman/mrWest/releases/tag/0.3">GitHub</a>. Here is an example output:</p>
<iframe width="100%" height="166" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/199184429&amp;color=ff5500&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false"></iframe>
]]></content:encoded>
      </item>
      <item>
        <guid>http://simoraman.com/generating-music-with-f-part-2-markov-chains#13039</guid>
          <pubDate>Sun, 29 Mar 2015 00:14:37 -1200</pubDate>
        <link>http://simoraman.com/generating-music-with-f-part-2-markov-chains</link>
        <title>Generating music with F# part 2: Markov chains</title>
        <description></description>
        <content:encoded><![CDATA[<p>Continuing from the previous <a href="http://www.simoraman.com/generating-music-with-f">post</a>. </p>

<p>To make melody generation more interesting I decided to try applying statistical process called <a href="http://en.wikipedia.org/wiki/Markov_chain">Markov chain</a>. In the context of this post by Markov chain I mean that the next state of the system is not completely random but next states have different probabilities that depend on the current state.</p>

<p>There is a Finnish children&#39;s song and a Swedish drinking song called <a href="http://en.wikipedia.org/wiki/Gubben_Noak">&quot;Ukko-Nooa&quot;</a> or &quot;Gubben Noak&quot; that has a simple melody that goes like this:</p>
<div class="highlight"><pre><span></span><span class="k">let</span> <span class="nv">nooaMelody</span> <span class="o">=</span>
    <span class="o">[</span><span class="n">C</span><span class="o">;</span> <span class="n">C</span><span class="o">;</span> <span class="n">C</span><span class="o">;</span> <span class="n">E</span><span class="o">;</span> <span class="n">D</span><span class="o">;</span> <span class="n">D</span><span class="o">;</span> <span class="n">D</span><span class="o">;</span> <span class="n">F</span><span class="o">;</span> <span class="n">E</span><span class="o">;</span> <span class="n">E</span><span class="o">;</span> <span class="n">D</span><span class="o">;</span> <span class="n">D</span><span class="o">;</span> <span class="n">C</span><span class="o">;</span>
    <span class="n">E</span><span class="o">;</span> <span class="n">E</span><span class="o">;</span> <span class="n">E</span><span class="o">;</span> <span class="n">E</span><span class="o">;</span> <span class="n">G</span><span class="o">;</span> <span class="n">F</span><span class="o">;</span> <span class="n">D</span><span class="o">;</span> <span class="n">D</span><span class="o">;</span> <span class="n">D</span><span class="o">;</span> <span class="n">D</span><span class="o">;</span> <span class="n">F</span><span class="o">;</span> <span class="n">E</span><span class="o">;</span>
    <span class="n">C</span><span class="o">;</span> <span class="n">C</span><span class="o">;</span> <span class="n">C</span><span class="o">;</span> <span class="n">E</span><span class="o">;</span> <span class="n">D</span><span class="o">;</span> <span class="n">D</span><span class="o">;</span> <span class="n">D</span><span class="o">;</span> <span class="n">F</span><span class="o">;</span> <span class="n">E</span><span class="o">;</span> <span class="n">E</span><span class="o">;</span> <span class="n">D</span><span class="o">;</span> <span class="n">D</span><span class="o">;</span> <span class="n">C</span><span class="o">;]</span>
</pre></div>
<p>We create a map of notes to sequence of notes. Sequence consists of notes that can follow the note that is used as key.</p>
<div class="highlight"><pre><span></span><span class="k">let</span> <span class="nv">noteData</span> <span class="o">=</span> 
    <span class="n">nooaMelody</span>
    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">windowed</span> <span class="mi">2</span>
    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">groupBy</span> <span class="o">(</span><span class="k">fun</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">note</span> <span class="bp">[]</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">x</span><span class="o">.[</span><span class="mi">0</span><span class="o">])</span>
    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">map</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="o">-&gt;</span> 
           <span class="o">(</span><span class="n">fst</span> <span class="n">x</span><span class="o">,</span> 
            <span class="n">x</span>
            <span class="o">|&gt;</span> <span class="n">snd</span>
            <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">map</span> <span class="o">(</span><span class="nn">Seq</span><span class="p">.</span><span class="n">nth</span> <span class="mi">1</span><span class="o">)))</span>
    <span class="o">|&gt;</span> <span class="nn">Map</span><span class="p">.</span><span class="n">ofSeq</span>
</pre></div>
<p>This is how to get next random note based on current note.</p>
<div class="highlight"><pre><span></span><span class="k">let</span> <span class="nv">getNextNote</span> <span class="o">(</span><span class="n">random</span> <span class="o">:</span> <span class="nn">System</span><span class="p">.</span><span class="n">Random</span><span class="o">)</span> <span class="o">(</span><span class="n">data</span> <span class="o">:</span> <span class="n">Map</span><span class="o">&lt;</span><span class="n">note</span><span class="o">,</span><span class="n">seq</span><span class="o">&lt;</span><span class="n">note</span><span class="o">&gt;&gt;)</span> <span class="o">(</span><span class="n">currentNote</span> <span class="o">:</span> <span class="n">note</span><span class="o">)</span> <span class="o">=</span> 
    <span class="k">let</span> <span class="nv">nextSet</span> <span class="o">:</span> <span class="n">seq</span><span class="o">&lt;</span><span class="n">note</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">data</span><span class="o">.[</span><span class="n">currentNote</span><span class="o">]</span>
    <span class="k">let</span> <span class="nv">nextNoteIndex</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">Next</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">length</span> <span class="n">nextSet</span><span class="o">)</span>
    <span class="n">nextSet</span>
    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">skip</span> <span class="n">nextNoteIndex</span>
    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">head</span>
</pre></div>
<p>The more times a note is contained in the sequence where currentNote acts as a key, the more likely it is to become next note.</p>

<p>Rest of the program looks like this:</p>
<div class="highlight"><pre><span></span><span class="k">let</span> <span class="nv">r</span> <span class="o">=</span> <span class="nn">System</span><span class="p">.</span><span class="n">Random</span><span class="bp">()</span>
<span class="k">let</span> <span class="nv">nextNoteFromData</span> <span class="o">:</span> <span class="n">Map</span><span class="o">&lt;</span><span class="n">note</span><span class="o">,</span><span class="n">seq</span><span class="o">&lt;</span><span class="n">note</span><span class="o">&gt;&gt;</span> <span class="o">-&gt;</span> <span class="n">note</span> <span class="o">-&gt;</span> <span class="n">note</span> <span class="o">=</span> <span class="n">getNextNote</span> <span class="n">r</span>

<span class="k">let</span> <span class="nv">rec</span> <span class="n">randomMelody</span> <span class="n">wantedLength</span> <span class="n">noteData</span> <span class="n">currentNote</span> <span class="o">(</span><span class="n">melody</span> <span class="o">:</span> <span class="n">note</span> <span class="kt">list</span><span class="o">)</span> <span class="o">=</span> 
    <span class="k">if</span> <span class="n">melody</span><span class="o">.</span><span class="n">Length</span> <span class="o">=</span> <span class="n">wantedLength</span> <span class="k">then</span> <span class="n">melody</span>
    <span class="k">else</span> 
        <span class="k">let</span> <span class="nv">nextNote</span> <span class="o">=</span> <span class="n">nextNoteFromData</span> <span class="n">noteData</span> <span class="n">currentNote</span>
        <span class="n">randomMelody</span> <span class="n">wantedLength</span> <span class="n">noteData</span> <span class="n">nextNote</span> <span class="o">(</span><span class="n">melody</span> <span class="o">@</span> <span class="o">[</span><span class="n">nextNote</span><span class="o">])</span>

<span class="o">[&lt;</span><span class="n">EntryPoint</span><span class="o">&gt;]</span>
<span class="k">let</span> <span class="nv">main</span> <span class="n">argv</span> <span class="o">=</span> 
    <span class="k">let</span> <span class="nv">availableNotes</span> <span class="o">=</span> 
        <span class="n">noteData</span> <span class="o">|&gt;</span> <span class="nn">Map</span><span class="p">.</span><span class="n">toSeq</span> <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">map</span> <span class="n">fst</span> <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">ofSeq</span>
    <span class="k">let</span> <span class="nv">firstNote</span> <span class="o">=</span> <span class="n">availableNotes</span><span class="o">.[</span><span class="n">r</span><span class="o">.</span><span class="n">Next</span><span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="n">availableNotes</span><span class="o">.</span><span class="n">Length</span><span class="o">)]</span>
    <span class="n">randomMelody</span> <span class="mi">8</span> <span class="n">noteData</span> <span class="n">firstNote</span> <span class="o">[</span> <span class="n">firstNote</span> <span class="o">]</span>
    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">map</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="o">-&gt;</span> <span class="n">frequency</span><span class="o">.[</span><span class="n">x</span><span class="o">])</span>
    <span class="o">|&gt;</span> <span class="nn">Synth</span><span class="p">.</span><span class="n">writeMelody</span>
    <span class="mi">0</span> <span class="c1">// return an integer exit code</span>
</pre></div>
<p>nextNoteFromData is partially applied function of getNextNote that can be used without passing an instance of System.Random along. randomMelody recursively creates list of notes until given length is achieved.</p>

<p>That&#39;s it! Here is an example of the output. Much better than the completely random version from previous post.</p>
<iframe width="100%" height="450" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/197323160&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;visual=true"></iframe>


<p>The full source code is on <a href="https://github.com/simoraman/mrWest/releases/tag/0.2">GitHub</a></p>
]]></content:encoded>
      </item>
  </channel>
</rss>