<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Amori in corso</title>
	<atom:link href="http://www.lucaamore.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.lucaamore.com</link>
	<description>blog personale di Luca Amore: &#34;pensieri in una bottiglia http&#34;</description>
	<lastBuildDate>Tue, 20 Dec 2011 00:24:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>AI: Pac-Man and Ms Pac-Man</title>
		<link>http://www.lucaamore.com/?p=710</link>
		<comments>http://www.lucaamore.com/?p=710#comments</comments>
		<pubDate>Tue, 20 Dec 2011 00:24:15 +0000</pubDate>
		<dc:creator>luca</dc:creator>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[Computational Intelligence]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Machine Learning]]></category>
		<category><![CDATA[Pac-Man]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.lucaamore.com/?p=710</guid>
		<description><![CDATA[E&#8217; da molto che non scrivo in questo blog; semplicemente sono stato impegnato in alcuni progetti che non reputo ancora pubblicabili. Voglio segnalarvi due interessanti riferimenti nel campo dell&#8217;AI, computational intelligence, machine learning; argomenti di cui mi sto occupando in &#8230; <a href="http://www.lucaamore.com/?p=710">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>E&#8217; da molto che non scrivo in questo blog; semplicemente sono stato impegnato in alcuni progetti che non reputo ancora pubblicabili.</p>
<p>Voglio segnalarvi due interessanti riferimenti nel campo dell&#8217;AI, computational intelligence, machine learning; argomenti di cui mi sto occupando in questo periodo.</p>
<p><strong>The Pac-Man Projects</strong></p>
<p>Come base degli esercizi per un corso di intelligenza artificiale, presso l&#8217;università di Berkeley, viene proposto agli studenti di sviluppare in python alcuni algoritmi all&#8217;interno del famoso gioco del Pac-Man; il corso termina con un multi-player contest.</p>
<p><a title="The Pac-Man Projects" href="http://inst.eecs.berkeley.edu/~cs188/pacman/pacman.html">The Pac-Man Projects</a></p>
<p>Trovo questa idea geniale e molto efficace dal punto di vista didattico.</p>
<p>Il materiale può essere liberamente utilizzato come base per corsi di intelligenza artificiale ma si richiede di non pubblicare online le soluzioni dei problemi posti.</p>
<p><a href="http://www.lucaamore.com/wp-content/uploads/2011/12/pacman_multi_agent.png"><img class="aligncenter size-full wp-image-711" title="pacman_multi_agent" src="http://www.lucaamore.com/wp-content/uploads/2011/12/pacman_multi_agent.png" alt="Pac-Man" width="451" height="249" /></a></p>
<p><strong>Ms Pac-Man vs Ghost Team Competition</strong></p>
<p>Per chi volesse cimentarsi nello sviluppo in java di algoritmi che pilotano Ms Pac-Man o la squadra dei quattro fantasmi è stata organizzata un&#8217;avvincente competizione:</p>
<p><a title="Ms Pac-Man vs Ghost Team Competition" href="http://www.pacman-vs-ghosts.net">Ms Pac-Man vs Ghost Team Competition</a></p>
<p>Un risultato interessante (che mi sorprende) è che i punteggi ottenuti dai migliori giocatori artificiali sono molto più bassi di quelli umani.</p>
<p>Tra i vari algoritmi utilizzati: Ant Colony Optimization, Genetic Programming, Neural Networks, Influence Maps, Minimax, Rule Based.</p>
<h3><span style="color: #000000;"><span style="line-height: 25px;"><br />
</span></span></h3>
]]></content:encoded>
			<wfw:commentRss>http://www.lucaamore.com/?feed=rss2&#038;p=710</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Computer vision: OpenCV realtime face detection in Python</title>
		<link>http://www.lucaamore.com/?p=638</link>
		<comments>http://www.lucaamore.com/?p=638#comments</comments>
		<pubDate>Sat, 11 Jun 2011 01:29:18 +0000</pubDate>
		<dc:creator>luca</dc:creator>
				<category><![CDATA[Computer Vision]]></category>
		<category><![CDATA[Face Detection]]></category>
		<category><![CDATA[OpenCV]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.lucaamore.com/?p=638</guid>
		<description><![CDATA[Per festeggiare degnamente l&#8217;arrivo del mio nuovo portatile in famiglia ho pensato di renderlo in grado di riconoscere volti umani da una sorgente video in tempo reale. Video dell&#8217;applicazione realizzata Segue il video dimostrativo dell&#8217;applicazione realizzata: OpenCV (Open Source Computer &#8230; <a href="http://www.lucaamore.com/?p=638">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Per festeggiare degnamente l&#8217;arrivo del mio nuovo portatile in famiglia ho pensato di renderlo in grado di riconoscere volti umani da una sorgente video in tempo reale.</p>
<p><strong>Video dell&#8217;applicazione realizzata</strong></p>
<p>Segue il video dimostrativo dell&#8217;applicazione realizzata:</p>
<p><iframe src="http://www.youtube.com/embed/HTk_UwAYzVk" frameborder="0" width="640" height="385"></iframe></p>
<p><strong>OpenCV (Open Source Computer Vision Library)</strong></p>
<p>Era da tempo che desideravo utilizzare la libreria <a title="OpenCV" href="http://opencv.willowgarage.com/wiki/">Open CV</a> per tornare a fare qualche esperimento di Computer Vision e per esplorare le sue tanto decantate potenzialità.</p>
<p>OpenCV è una libreria rilasciata sotto licenza <a title="BSD-license" href="http://opensource.org/licenses/bsd-license.php">BSD</a> dalla Intel per l&#8217;elaborazione realtime delle immagini e la Computer Vision.</p>
<p>Scritta in C e C++ è utilizzabile, tramite wrapper (sia ufficiali che non) in diversi linguaggi: Python, Ruby, Java, C# ed è stata portata sui principali sistemi operativi: GNU/Linux, FreeBSD, Mac OS X, Windows ma anche Android e iOS per lo sviluppo di applicazioni su dispositivi mobili.</p>
<p>Alcuni wrapper esportano solo un limitato sottoinsieme di funzionalità.</p>
<p><a href="http://www.lucaamore.com/wp-content/uploads/2011/06/test-0009.jpg"><img class="alignleft size-medium wp-image-642" title="face-detection-009" src="http://www.lucaamore.com/wp-content/uploads/2011/06/test-0009-300x226.jpg" alt="face-detection demo 009" width="300" height="226" /></a>Mi sono reso conto che le potenzialità di tale libreria sono superiori alle mie più rosee aspettative: c&#8217;è tutto quello che può servire (e si può sognare) per realizzare applicazioni avanzate di Computer Vision ed elaborazione delle immagini.</p>
<p><a title="Video di applicazioni possibili (Computer Vision)" href="http://www.youtube.com/playlist?p=PLFF718978F8808567">Video di alcune interessanti applicazioni che è possibile realizzare</a></p>
<p>Sviluppare un&#8217;applicazione di ottima qualità per la face detection in realtime, problema normalmente complesso, diventa banale a tal punto che mi sono limitato a fare qualche ricerca su internet ed assemblare poche righe di codice Python trovate in alcuni blog.</p>
<p><strong>Face Detection ed Haar-like features</strong></p>
<p>L&#8217;algoritmo molto efficiente che viene utilizzato per la rilevazione dei volti, basato sulle Haar wavelet, è stato elaborato da Viola-Jones nell&#8217;ambito dell&#8217;object detection ed è stato pensato proprio per il problema della face detection in tempo reale.</p>
<p>Con OpenCV è possibile addestrare nuovi identificatori di oggetti tuttavia sono già presenti i seguenti classificatori (in formato xml):</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
haarcascade_eye_tree_eyeglasses.xml
haarcascade_eye.xml
haarcascade_frontalface_alt2.xml
haarcascade_frontalface_alt_tree.xml
haarcascade_frontalface_alt.xml
haarcascade_frontalface_default.xml
haarcascade_fullbody.xml
haarcascade_lefteye_2splits.xml
haarcascade_lowerbody.xml
haarcascade_mcs_eyepair_big.xml
haarcascade_mcs_eyepair_small.xml
haarcascade_mcs_lefteye.xml
haarcascade_mcs_mouth.xml
haarcascade_mcs_nose.xml
haarcascade_mcs_righteye.xml
haarcascade_mcs_upperbody.xml
haarcascade_profileface.xml
haarcascade_righteye_2splits.xml
haarcascade_upperbody.xml
</pre>
<p>Nelle mie prove, dopo aver individuato il volto, ho provato a rilevare anche gli occhi e la bocca ma in questo caso i risultati non mi hanno soddisfatto.</p>
<p><strong>Sorgente Python<br />
</strong></p>
<p><a href="http://www.lucaamore.com/wp-content/uploads/2011/06/test-0069.jpg"><img class="alignright size-medium wp-image-678" title="test-0069" src="http://www.lucaamore.com/wp-content/uploads/2011/06/test-0069-300x226.jpg" alt="" width="300" height="226" /></a>I miei esperimenti sono stati effettuati su una macchina GNU/Linux Ubuntu 11.04 con OpenCV 2.1.</p>
<p>E&#8217; richiesto il pacchetto python-opencv, presente nei repository ufficiali e si assume che nel path dello script sia presente una directory haarcascades contenente i vari xml necessari per la detection.</p>
<p>Su Ubuntu 11.04 è possibile trovarli nella directory:</p>
<p>/usr/share/doc/opencv-doc/examples/haarcascades/haarcascades/</p>
<p>segue il codice sorgente utilizzato per la realizzazione del video:</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/python

#----------------------------------------------------------------------------
# Face Detection Test (OpenCV)
#
# thanks to:
# http://japskua.wordpress.com/2010/08/04/detecting-eyes-with-python-opencv
#----------------------------------------------------------------------------

import cv
import time
import Image

def DetectFace(image, faceCascade):

    min_size = (20,20)
    image_scale = 2
    haar_scale = 1.1
    min_neighbors = 3
    haar_flags = 0

    # Allocate the temporary images
    grayscale = cv.CreateImage((image.width, image.height), 8, 1)
    smallImage = cv.CreateImage(
            (
                cv.Round(image.width / image_scale),
                cv.Round(image.height / image_scale)
            ), 8 ,1)

    # Convert color input image to grayscale
    cv.CvtColor(image, grayscale, cv.CV_BGR2GRAY)

    # Scale input image for faster processing
    cv.Resize(grayscale, smallImage, cv.CV_INTER_LINEAR)

    # Equalize the histogram
    cv.EqualizeHist(smallImage, smallImage)

    # Detect the faces
    faces = cv.HaarDetectObjects(
            smallImage, faceCascade, cv.CreateMemStorage(0),
            haar_scale, min_neighbors, haar_flags, min_size
        )

    # If faces are found
    if faces:
        for ((x, y, w, h), n) in faces:
            # the input to cv.HaarDetectObjects was resized, so scale the
            # bounding box of each face and convert it to two CvPoints
            pt1 = (int(x * image_scale), int(y * image_scale))
            pt2 = (int((x + w) * image_scale), int((y + h) * image_scale))
            cv.Rectangle(image, pt1, pt2, cv.RGB(255, 0, 0), 5, 8, 0)

    return image

#----------
# M A I N
#----------

capture = cv.CaptureFromCAM(0)
#capture = cv.CaptureFromFile(&quot;test.avi&quot;)

#faceCascade = cv.Load(&quot;haarcascades/haarcascade_frontalface_default.xml&quot;)
#faceCascade = cv.Load(&quot;haarcascades/haarcascade_frontalface_alt2.xml&quot;)
faceCascade = cv.Load(&quot;haarcascades/haarcascade_frontalface_alt.xml&quot;)
#faceCascade = cv.Load(&quot;haarcascades/haarcascade_frontalface_alt_tree.xml&quot;)

while (cv.WaitKey(15)==-1):
    img = cv.QueryFrame(capture)
    image = DetectFace(img, faceCascade)
    cv.ShowImage(&quot;face detection test&quot;, image)

cv.ReleaseCapture(capture)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lucaamore.com/?feed=rss2&#038;p=638</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Cammelli labirinti e depth-first search: realizzazione di un generatore e risolutore di labirinti in Perl</title>
		<link>http://www.lucaamore.com/?p=583</link>
		<comments>http://www.lucaamore.com/?p=583#comments</comments>
		<pubDate>Thu, 05 May 2011 00:33:16 +0000</pubDate>
		<dc:creator>luca</dc:creator>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[Deepth-First Search]]></category>
		<category><![CDATA[FreeSoftware]]></category>
		<category><![CDATA[GD]]></category>
		<category><![CDATA[labirinto]]></category>
		<category><![CDATA[maze]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.lucaamore.com/?p=583</guid>
		<description><![CDATA[Se Téseo (Θησεύς), eroe spregiudicato nonchè figlio del re ateniese Ègeo (Αἰγεύς), avesse conosciuto qualche rudimento di Perl, avrebbe potuto risolvere brillantemente il problema del Labirinto di Cnosso adottando l&#8217;algoritmo deep-first search, sconfiggere il Minotauro (Μινώταυρος) Asterione ma &#8211; soprattutto &#8230; <a href="http://www.lucaamore.com/?p=583">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div id="attachment_612" class="wp-caption alignright" style="width: 210px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/05/maze20x20.png"><img class="size-full wp-image-612" title="maze20x20" src="http://www.lucaamore.com/wp-content/uploads/2011/05/maze20x20.png" alt="" width="200" height="200" /></a><p class="wp-caption-text">labirinto 20 x 20 generato da maze.pl</p></div>
<p>Se <a title="Téseo" href="http://it.wikipedia.org/wiki/Teseo">Téseo</a> (Θησεύς), eroe spregiudicato nonchè figlio del re ateniese <a title="Egeo" href="http://it.wikipedia.org/wiki/Egeo">Ègeo</a> (Αἰγεύς), avesse conosciuto qualche rudimento di Perl, avrebbe potuto risolvere brillantemente il problema del <a title="Labirinto di Cnosso" href="http://it.wikipedia.org/wiki/Labirinto_di_Cnosso">Labirinto di Cnosso</a> adottando l&#8217;algoritmo <a href="http://en.wikipedia.org/wiki/Depth-first_search">deep-first search</a>, sconfiggere il <a title="Minotauro" href="http://it.wikipedia.org/wiki/Minotauro">Minotauro</a> (Μινώταυρος) Asterione ma &#8211; soprattutto &#8211; non avrebbe spezzato il cuore della povera <a title="Arianna" href="http://it.wikipedia.org/wiki/Arianna_%28mitologia%29">Arianna</a> (Αριάδνη), figlia di Minosse e Pasifae (ed anche madre del Minotauro), seducendola per ottenere il risolutivo gomitolo di filo rosso (un surrogato di stack analogico ideato da <a title="Dedalo" href="http://it.wikipedia.org/wiki/Dedalo">Dedalo</a><em> </em>) per poi abbandonarla ancora dormiente nell&#8217;isola deserta di <a title="Nasso" href="http://it.wikipedia.org/wiki/Nasso">Nasso</a> (pare pure dopo una lunga notte di &#8220;festeggiamenti&#8221; nella sua nave).</p>
<p>A chi mi obietta &#8211; ingiustamente &#8211; che ai tempi non era disponibile un interprete Perl così come un notebook agevolmente trasportabile in un Labirinto, ma anche a tutti gli altri che gridano vendetta contro il comportamento di Téseo nei confronti della povera Arianna, consiglio vivamente la lettura dell&#8217;avvincente <a title="Minotauro" href="http://it.wikipedia.org/wiki/Minotauro">leggenda del Minotauro</a>; scoprirete che la storia di Téseo, per opera di Poseidone, si conclude in modo tragico a causa dell&#8217;inversione di un&#8217;informazione booleana (1 bit) ma vitale: il colore delle vele della sua imbarcazione.</p>
<p>Dopo questa mitologica premessa, certo di esser perdonato per eventuali errori sulla mitologia greca, sperando di non deludere il forse unico temerario lettore che avrà avuto l&#8217;ardore di proseguire nella lettura di questo articolo, vi presento un semplicissimo<strong> generatore e risolutore di labirinti scritto interamente in Perl</strong>.</p>
<div id="attachment_620" class="wp-caption alignnone" style="width: 310px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/05/maze60x40.png"><img class="size-medium wp-image-620" title="maze60x40" src="http://www.lucaamore.com/wp-content/uploads/2011/05/maze60x40-300x200.png" alt="" width="300" height="200" /></a><p class="wp-caption-text">Labirinto 60 x 40 generato da maze.pl</p></div>
<p>Questo progetto è ispirato da <a title="Maze in Python" href="http://mornie.org/blog/2007/08/02/generating-maze-using-python/">un articolo</a> che ho letto nel blog di Eriol in cui il problema viene affrontato in Python.</p>
<p>In rete esistono anche molti riferimenti sui labirinti (storia, classificazione, generazione, risoluzione, miti e leggende) dove è piacevole perdersi:</p>
<ul>
<li><a title="Maze Generation" href="http://en.wikipedia.org/wiki/Maze_generation">Maze Generation</a></li>
<li><a title="Think Labyrinth: Maze algorithms" rel="nofollow" href="http://www.astrolog.org/labyrnth/algrithm.htm">Think Labyrinth: Maze algorithms</a></li>
<li><a title="Maze Solving Algorithm" href="http://en.wikipedia.org/wiki/Maze_solving_algorithm">Maze Solving Algorithm</a></li>
<li><a title="Maze" href="http://en.wikipedia.org/wiki/Maze">Maze</a></li>
<li><a title="Mazework - how to build a maze" href="http://www.mazeworks.com/mazegen/mazetut/">Mazework &#8211; How to build a Maze</a> citato nell&#8217;articolo</li>
<li><a title="Labirinto" href="http://it.wikipedia.org/wiki/Labirinto">Labirinto</a></li>
<li><a title="Labirinti e matematica" rel="nofollow" href="http://areeweb.polito.it/didattica/polymath/htmlS/probegio/GAMEMATH/Labirinti/Matematica%20e%20labirinti.htm">labirinti e matematica</a></li>
</ul>
<p>Nella mia implementazione, esaltando alcune caratteristiche tipiche del Perl, ho progettato delle strutture dati leggere ed efficienti (memorizzo solo le aperture del labirinto) ed ho adottato la versione dell&#8217;algoritmo <a title="depth-first search" href="http://en.wikipedia.org/wiki/Depth-first_search">depth-first search</a> ricorsiva sia per la costruzione del labirinto (metodo <em>Maze::asterione)</em> che per la ricerca del percorso che conduce dall&#8217;ingresso all&#8217;uscita (metodo <em>Maze::teseo</em>).</p>
<p>Sono disponibili:</p>
<p>l&#8217;output del labirinto generato e risolto in modalità ASCII (<em>Maze::toText</em>):</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">

lookee@grog:~/devel/maze$ ./maze.pl

+..+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|..|.. ..|              |  |           |           |        |
+..+..+..+  +--+--+--+  +  +  +  +--+  +  +  +--+  +  +--+  +
|.. ..|..|  |              |  |  |     |  |     |     |     |
+--+--+..+  +--+--+--+--+  +  +  +  +--+--+--+  +--+--+  +--+
|.. .. ..|              |  |  |  |              |     |  |  |
+..+--+--+--+  +--+--+  +--+  +  +--+--+  +--+--+--+  +  +  +
|..|.. .. ..|  |     |        |     |     |        |     |  |
+..+..+--+..+  +  +  +--+--+--+--+  +--+--+  +--+  +  +--+  +
|.. ..|  |..|     |  |           |  |        |     |        |
+--+--+  +..+--+--+  +--+  +--+  +  +  +--+--+  +--+--+--+--+
|        |.. ..|  |     |     |  |     |.. ..|     |        |
+  +--+--+--+..+  +--+  +--+  +--+--+  +..+..+--+  +  +--+  +
|           |..|              |.. ..|  |..|.. ..|        |  |
+--+--+--+  +..+  +--+--+--+--+..+..+--+..+--+..+--+--+--+  +
|           |..|  |     |.. ..|..|.. .. ..|  |.. .. ..|     |
+  +--+--+  +..+  +  +--+..+..+..+--+--+--+  +--+--+..+..+  +
|  |     |  |..|     |.. ..|..|.. ..|     |        |.. ..|  |
+  +  +  +--+..+--+--+..+--+..+--+..+  +  +  +  +--+--+..+--+
|     |      .. .. .. ..|   .. .. ..|  |     |         .. ..|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+..+
</pre>
<p>l&#8217;output in formato PNG(<em>Maze::toImage</em>):</p>
<div id="attachment_614" class="wp-caption alignnone" style="width: 310px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/05/maze200x100.png"><img class="size-medium wp-image-614" title="maze200x100" src="http://www.lucaamore.com/wp-content/uploads/2011/05/maze200x100-300x150.png" alt="" width="300" height="150" /></a><p class="wp-caption-text">labirinto 200 x 100 generato da maze.pl</p></div>
<p>Per la generazione dell&#8217;immagine si richiedono le librerie GD.</p>
<p>Il tutto sarebbe ottimizzabile e migliorabile ma al momento sono già abbastanza soddisfatto dei risultati ottenuti!</p>
<p><a title="repository maze (github)" href="https://github.com/lookee/maze">Potete scaricare i sorgenti di maze.pl nel repository del progetto su github</a> (software libero rilasciato sotto licenza GNU/GPL v. 3)</p>
<pre class="brush: perl; title: ; notranslate">

#!/usr/bin/perl

#------------------------------------------------------------------------
# M A Z E
#------------------------------------------------------------------------

use strict;
use warnings;

package Maze;

use Carp qw(croak verbose);
use GD;

sub new {
    my ($class, $x, $y) = @_; 

    my $self = {
        x =&gt; $x,
        y =&gt; $y,
        doors =&gt; [],
        solution =&gt; [],
    };

    bless $self;
    $self-&gt;openWall(0, 0, 'N');
    $self-&gt;openWall($x - 1, $y - 1, 'S');

    return $self;
}

sub _getWallIndex($$$){
    my ($self, $x, $y, $dir) = @_;

    my @idx =
        $dir eq 'N' ? ($x,      $y,     'N') :
        $dir eq 'S' ? ($x,      $y + 1, 'N') :
        $dir eq 'W' ? ($x,      $y,     'E') :
        $dir eq 'E' ? ($x + 1,  $y,     'E') :
            croak &quot;wrong direction&quot;;

    return @idx;
}

sub isWallOpen($$$){
    my ($self, $x, $y, $dir) = @_;

    my ($wx, $wy, $wdir) = $self-&gt;_getWallIndex($x, $y, $dir);    

    return $self-&gt;{door}[$wx][$wy]{$wdir} || 0;
}

sub openWall($$$) {
    my ($self, $x, $y, $dir) = @_;

    my ($wx, $wy, $wdir) = $self-&gt;_getWallIndex($x, $y, $dir);    

    $self-&gt;{door}[$wx][$wy]{$wdir} = 1;
}

sub getCellNeighbors($$$){
    my ($self, $x, $y) = @_;
    grep {
        $_-&gt;[0] &gt;= 0 and $_-&gt;[0] &lt; $self-&gt;{x} and
        $_-&gt;[1] &gt;= 0 and $_-&gt;[1] &lt; $self-&gt;{y}
    } (
        [$x - 1, $y    , 'W'],
        [$x + 1, $y    , 'E'],
        [$x    , $y - 1, 'N'],
        [$x    , $y + 1, 'S']
    );
}

sub getCellOpenedNeighbors($$$){
    my ($self, $x, $y) = @_;
    grep {
        my (undef, undef, $dir) = @$_;
        $self-&gt;isWallOpen($x, $y, $dir)
    } $self-&gt;getCellNeighbors($x, $y);
}

sub isCellExit($$$){
    my ($self, $x, $y) = @_;
    return
        ($x == $self-&gt;{x} -1 ) &amp;&amp; ($y == $self-&gt;{y} -1 );
} 

sub markSolution($$$){
    my ($self, $x, $y) = @_;
    $self-&gt;{solution}[$x][$y] = 1;
}

sub isSolution($$$){
    my ($self, $x, $y) = @_;
    $self-&gt;{solution}[$x][$y];
}

# generate maze
sub asterione($$$$){
    no warnings 'recursion';
    my ($self, $x, $y, $visited) = @_;
    $visited-&gt;[$x][$y] = 1;
    return if $self-&gt;isCellExit($x,$y);
    my @neighbors = $self-&gt;getCellNeighbors($x, $y);
    while (scalar @neighbors){
        my ($tox, $toy, $dir) =
            @{ splice(@neighbors, rand(@neighbors), 1) };
        next if $visited-&gt;[$tox][$toy];
        $self-&gt;openWall($x, $y, $dir);
        $self-&gt;asterione($tox, $toy, $visited);
    }
}

# solve maze
sub teseo($$$$){
    no warnings 'recursion';
    my ($self, $x, $y, $visited) = @_;
    $visited-&gt;[$x][$y] = 1;
    if ($self-&gt;isCellExit($x, $y)){
        $self-&gt;markSolution($x, $y);
        return 1;
    }
    my @neighbors = $self-&gt;getCellOpenedNeighbors($x, $y);
    while (scalar @neighbors){
        my ($tox, $toy, $dir) =
            @{ splice(@neighbors, rand(@neighbors), 1) };
        next if $visited-&gt;[$tox][$toy];
        my $isSolution = $self-&gt;teseo($tox, $toy, $visited);
        if ($isSolution){
            $self-&gt;markSolution($x, $y);
            return 1;
        }
    }
    return 0;
}

sub toText(){

    my $self = shift;

    my ($x, $y, @l1, @l2);
    my $out = '';
    for ($y = 0; $y &lt; $self-&gt;{y}; $y++){
        @l1 = @l2 = ();
        for ($x = 0; $x &lt; $self-&gt;{x}; $x++){
            my $solution = $self-&gt;isSolution($x, $y) ? '.' : ' ';
            push(@l1, $self-&gt;isWallOpen($x, $y, 'N') ? $solution x 2 : '-' x 2);
            push(@l2, $self-&gt;isWallOpen($x, $y, 'W') ? ' ' : '|');
            push(@l2, $solution x 2);
        }
        push(@l2, $self-&gt;isWallOpen($x, $y, 'E') ? ' ' : '|');
        $out .=
            '+' . join('+',@l1) . '+' . &quot;\n&quot; .
            join('',@l2) . &quot;\n&quot;;
    }

    @l1 = ();
    for ($x = 0; $x &lt; $self-&gt;{x}; $x++){
        my $solution = $self-&gt;{solution}[$x][$self-&gt;{y} -1] ? '.' : ' ';
        push(@l1,
            $self-&gt;isWallOpen($x, $self-&gt;{y} -1, 'S') ?
                $solution x 2 : '-' x 2
        );
    }

    $out .= '+' . join('+', @l1) . '+' . &quot;\n&quot;;

    print $out;
}

sub toImage($$){

    my ($self, $FILENAME) = @_;

    my ($WX, $WY) = (10, 10);

    my ($SIZEX, $SIZEY) = ($self-&gt;{x} * $WX, $self-&gt;{y} * $WY);

    my $img = new GD::Image-&gt;newTrueColor($SIZEX,$SIZEY)
        or croak &quot;Can't create GD::Image&quot;;

    my $cl_white = $img-&gt;colorAllocate(255,255,255);
    my $cl_black = $img-&gt;colorAllocate(  0,  0,  0);
    my $cl_red   = $img-&gt;colorAllocate(255,  0,  0);

    $img-&gt;fill( 0, 0, $cl_white);

    open(my $fh, '&gt;', $FILENAME)
        or croak &quot;Can't open $FILENAME: $!&quot;;

    binmode $fh;

    my ($xx, $yy);

    YY: for ($yy = 0; $yy &lt; $self-&gt;{y}; $yy++){

        XX: for ($xx = 0; $xx &lt; $self-&gt;{x}; $xx++){

            $img-&gt;filledRectangle(
                $xx * $WX, $yy * $WY, ($xx + 1) * $WX, ($yy + 1) * $WY,
                $cl_red
            )
                if $self-&gt;isSolution($xx, $yy);

            $img-&gt;line(
                    $xx * $WX, $yy * $WY, ($xx + 1) * $WX, $yy * $WY,
                    $cl_black
            )
                unless $self-&gt;isWallOpen($xx, $yy, 'N');

            $img-&gt;line(
                    $xx * $WX, $yy * $WY, $xx * $WX, ($yy + 1) * $WY,
                    $cl_black
            )
                unless $self-&gt;isWallOpen($xx, $yy, 'W');
        }

        $img-&gt;line(
            $xx * $WX - 1, $yy * $WY, $xx * $WX -1, ($yy + 1) * $WY,
            $cl_black
        )
            unless $self-&gt;isWallOpen($xx - 1, $yy, 'E');
    }

    for ($xx = 0; $xx &lt; $self-&gt;{x}; $xx++){
        $img-&gt;line(
            $xx * $WX, $yy * $WY - 1, ($xx + 1) * $WX, $yy * $WY - 1,
            $cl_black
    )
                unless $self-&gt;isWallOpen($xx, $yy - 1, 'S');
    }

    print $fh $img-&gt;png(0);
    close $fh;
}

package main;

# init
my $m = Maze-&gt;new(60,40);

# generate paths
$m-&gt;asterione(0,0,[]);

# solve maze
$m-&gt;teseo(0,0,[]);

# generate PNG
$m-&gt;toImage('out.png');

# print ASCII
#$m-&gt;toText();
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lucaamore.com/?feed=rss2&#038;p=583</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Erlang e frattali: fuga verso l&#8217;infinito&#8230;</title>
		<link>http://www.lucaamore.com/?p=283</link>
		<comments>http://www.lucaamore.com/?p=283#comments</comments>
		<pubDate>Fri, 22 Apr 2011 01:27:30 +0000</pubDate>
		<dc:creator>luca</dc:creator>
				<category><![CDATA[Calcolo Parallelo]]></category>
		<category><![CDATA[caos]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[frattali]]></category>
		<category><![CDATA[FreeSoftware]]></category>
		<category><![CDATA[Julia]]></category>
		<category><![CDATA[Mandelbrot]]></category>

		<guid isPermaLink="false">http://www.lucaamore.com/?p=283</guid>
		<description><![CDATA[Nello scorso articolo, tramite poche righe di codice perl, abbiamo curiosato all&#8217;interno del frastagliato universo frattale, rappresentando gli insiemi di Mandelbrot e Julia in modalità rigorosamente monocromatica. E&#8217; davvero meraviglioso quando la natura ci sorprende facendo coesistere l&#8217;infinitamente semplice con &#8230; <a href="http://www.lucaamore.com/?p=283">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Nello <a title="Rappresentazione dell’insieme frattale di Mandelbrot in perl" href="http://www.lucaamore.com/?p=331">scorso articolo</a>, tramite poche righe di codice perl, abbiamo curiosato all&#8217;interno del frastagliato universo frattale, rappresentando gli insiemi di Mandelbrot e Julia in modalità rigorosamente monocromatica.</p>
<div id="attachment_540" class="wp-caption alignleft" style="width: 310px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/04/m1.png"><img class="size-medium wp-image-540 " title="Mandelbrot" src="http://www.lucaamore.com/wp-content/uploads/2011/04/m1-300x171.png" alt="" width="300" height="171" /></a><p class="wp-caption-text">Mandelbrot, I: 40 Z: -2.5, 1.0 x -1.0, 1.0</p></div>
<p>E&#8217; davvero meraviglioso quando la natura ci sorprende facendo coesistere l&#8217;infinitamente semplice con lo smisuratamente complesso come in questo caso. Solo Lei può permettersi di farlo in modo così raffinato ed esuberante: una banale successione quadratica nel dominio dei numeri complessi, apparentemente insignificante ed innocua, è in grado di generare ricorsivamente &#8220;uno dei più complessi oggetti della matematica&#8221;; così è stato definito l&#8217;insieme di Mandelbrot da <a title="Benoît Mandelbrot" href="http://en.wikipedia.org/wiki/Benoit_Mandelbrot">Benoît Mandelbrot</a>, <a title="Heinz-Otto Peitge" href="http://en.wikipedia.org/wiki/Heinz-Otto_Peitgen">Heinz-Otto Peitgen</a> e <a title="John H. Hubbard" href="http://en.wikipedia.org/wiki/John_H._Hubbard">John H. Hubbard</a> suoi iniziali divulgatori.</p>
<p>Il comportamento dei sistemi caotici ha ancora misteriose proprietà che l&#8217;uomo non è stato ancora in grado di decifrare; mattoncini matematici che la natura ha combinato per la costruzione dell&#8217;universo e di cui &#8211; forse &#8211; potremmo parlare nei prossimi articoli.</p>
<p><strong>Erlang e frattali</strong></p>
<p>In questo articolo, ho deciso di realizzare un&#8217;applicazione distribuita per la rappresentazione in Erlang degli insiemi frattali di Mandelbrot e Julia in Erlang introducendo anche i colori.</p>
<div id="attachment_564" class="wp-caption alignright" style="width: 310px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/04/m4.png"><img class="size-medium wp-image-564" title="Mandelbrot" src="http://www.lucaamore.com/wp-content/uploads/2011/04/m4-300x300.png" alt="" width="300" height="300" /></a><p class="wp-caption-text">Mandelbrot, I: 500 Z: -0.981,-0.6457 x 0.0169, 0.3527</p></div>
<p>Un bel frullato di: caos, frattali, colori, concorrenza, programmazione funzionale, emozioni, infinito. Una frizzante e fatale alchimia di argomenti dalla quale non è possibile esser risucchiati!</p>
<p><strong>Erlang</strong></p>
<p>L&#8217;<a title="Erlang" href="http://en.wikipedia.org/wiki/Erlang_(programming_language)">Erlang</a> è un <a title="Functional Language" href="http://en.wikipedia.org/wiki/Functional_language">linguaggio funzionale</a> progettato da <a title="Joe Armstrong's blog" href="http://armstrongonsoftware.blogspot.com/">Joe Armstrong</a>, per conto di Ericsson, con lo scopo di favorire lo sviluppo di applicazioni: distribuite, soft-realtime, con un elevato grado di concorrenza ed affidabilità nel campo delle telecomunicazioni. La prima versione proprietaria del linguaggio è stata rilasciata internamente nel 1986 mentre, dopo varie vicessitudini, nel 1998 Erlang è stato distribuito opensource.</p>
<p><strong>Concorrenza e gestione dei processi</strong></p>
<blockquote><p>The world is concurrent<br />
Things in the world don&#8217;t share data<br />
Things communicate with messages<br />
Things fail - Joe Armstrong</p></blockquote>
<p>Erlang è progettato per la concorrenza massiva. Per spingere tale caratteristica a livelli estremi, si è ben pensato di progettare un gestore di processi ed uno scheduler interni alla virtual-machine. Tali componenti non delegano i loro compiti al kernel del sistema operativo (come fa la quasi totalità degli altri linguaggi) e sono in grado di gestire processi con un&#8217;efficientissima gestione della memoria e dello scheduling.</p>
<div id="attachment_546" class="wp-caption alignleft" style="width: 310px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/04/J1.png"><img class="size-medium wp-image-546" title="Julia" src="http://www.lucaamore.com/wp-content/uploads/2011/04/J1-300x300.png" alt="" width="300" height="300" /></a><p class="wp-caption-text">Julia, I: 150 K: -0.835+0.2321i Z: -1.8,1.8 x -1.0, 1.0</p></div>
<p>Scrivere applicazioni distribuite, scalabili e robuste in Erlang è normalmente più semplice che in altri linguaggi. I processi possono esser distribuiti trasparentemente su più core oppure su più macchine e comunicano tramite message-passing asincrono.</p>
<p><strong>Apprendere l&#8217;Erlang</strong></p>
<p>Se siete semplicemente curiosi di conoscere la sintassi del linguaggio, potreste provare questo breve tutorial online che simula via web la shell di Erlang: <a title="Try Erlang" href="http://www.tryerlang.org/">Tryerlang</a>.</p>
<p>Per un corso online è possibile visitare: <a title="Learn You Some Erlang" href="http://learnyousomeerlang.com/">Learn You Some Erlang</a> oppure <a title="Erlang for Skeptics" rel="nofollow" href="http://www.erlangforsceptics.com/" class="broken_link">Erlang for Skeptics</a></p>
<p>I libri che non possono mancare nella biblioteca di chi ama tale linguaggio (sui quali ho studiato l&#8217;Erlang):</p>
<ul>
<li><a title="Erlang Programming, O'Reilly Media" href="http://www.amazon.com/ERLANG-Programming-Francesco-Cesarini/dp/0596518188">Erlang Programming: A Concurrent Approach to Software Development, Francesco Cesarini and Simon Thompson, O&#8217;Reilly Media</a></li>
<li><a title="Programming Erlang, The Pragmatic Bookshelf" href="http://pragprog.com/titles/jaerlang/programming-erlang">Programming Erlang: Software for a Concurrent World, Joe Armstrong, The Pragmatic Bookshelf</a></li>
</ul>
<p><strong>Applicazione Erlang: frk</strong></p>
<p>Segue il codice sorgente in Erlang, del modulo principale, che ho scritto per la mia applicazione: frk.</p>
<pre class="brush: erlang; title: ; notranslate">
-module(frk).
-author('LucaAmore').
-export([save/11, save/9, julia/9, mandelbrot/7]).

%------------------------------------------------------------------------
%    Copyright (C) 2011 Luca Amore &lt;luca.amore at gmail.com&gt;
%------------------------------------------------------------------------

% extract all screen coords
screen(W, H)-&gt;
    [ {X,Y} || Y &lt;- lists:seq(0, H - 1), X &lt;- lists:seq(0, W - 1) ].

% convert bitmap point to complex point
complex(X, Y, MinX, MinY, FactX, FactY)-&gt;
    { MinX + X * FactX, MinY + Y * FactY }.

iterate(_, _, _, _, MaxIterations, Iterations)
    when Iterations &gt;= MaxIterations -&gt; Iterations;

iterate(Zre, Zim, _, _,  _, Iterations)
    when Zre * Zre + Zim * Zim  &gt; 4 -&gt; Iterations;

iterate(Zre, Zim, Cre, Cim, MaxIterations, Iterations)-&gt;
    iterate(
        Zre * Zre - Zim * Zim + Cre,
        2 * Zre * Zim + Cim,
        Cre, Cim,
        MaxIterations, Iterations+1
    ).

%------------------------------------------------------------------------
% Julia's set
%
% Z1 = C0, Zn+1 = Zn^2 + K
%------------------------------------------------------------------------
julia(X, Y, MinX, MinY, FactX, FactY, Kre, Kim, MaxIterations)-&gt;
    {Cre, Cim} = complex(X, Y, MinX, MinY, FactX, FactY),
    iterate(Cre, Cim, Kre, Kim, MaxIterations, 0).

%------------------------------------------------------------------------
% Mandelbrot's set
%
% Z1 = 0, Zn+1 = Zn^2 + C0
%------------------------------------------------------------------------
mandelbrot(X, Y, MinX, MinY, FactX, FactY, MaxIterations)-&gt;
    {Cre, Cim} = complex(X, Y, MinX, MinY, FactX, FactY),
    iterate(0, 0, Cre, Cim, MaxIterations, 0).

% Julia's set exploration
generate(julia, W, H, MinX, MaxX, MinY, MaxY, Kre, Kim, MaxIterations)
    when W &gt; 0, H &gt; 0, MaxX &gt; MinX, MaxY &gt; MinY, MaxIterations &gt; 0 -&gt;
    FactX = (MaxX - MinX) / W,
    FactY = (MaxY - MinY) / H,
    [ julia(X, Y, MinX, MinY, FactX, FactY, Kre, Kim, MaxIterations) ||
        {X, Y} &lt;- screen(W, H) ].

% Mandelbrot's set exploration
generate(mandelbrot, W, H, MinX, MaxX, MinY, MaxY, MaxIterations)
    when W &gt; 0, H &gt; 0, MaxX &gt; MinX, MaxY &gt; MinY, MaxIterations &gt; 0 -&gt;
    FactX = (MaxX - MinX) / W,
    FactY = (MaxY - MinY) / H,
    [ mandelbrot(X, Y, MinX, MinY, FactX, FactY, MaxIterations) ||
        {X, Y} &lt;- screen(W, H) ].

% save Julia's set in ppm format
save(julia, W, H, MinX, MaxX, MinY, MaxY, Kre, Kim, MaxIterations, FileName)
    when W &gt; 0, H &gt; 0, MaxX &gt; MinX, MaxY &gt; MinY, MaxIterations &gt; 0 -&gt;
    M = [
            paletteblu:color(Iterations, MaxIterations) ||
                Iterations &lt;- generate(
                    julia, W, H, MinX, MaxX, MinY, MaxY, Kre, Kim, MaxIterations
                )
    ],
    ppm:save(image, W, H, 255, FileName, M).

% save Mandelbrot's set in ppm format
save(mandelbrot, W, H, MinX, MaxX, MinY, MaxY, MaxIterations, FileName)
    when W &gt; 0, H &gt; 0, MaxX &gt; MinX, MaxY &gt; MinY, MaxIterations &gt; 0 -&gt;
    M = [
            palettered:color(Iterations, MaxIterations) ||
                Iterations &lt;- generate(
                    mandelbrot, W, H, MinX, MaxX, MinY, MaxY, MaxIterations
                )
    ],
    ppm:save(image, W, H, 255, FileName, M).
</pre>
<div id="attachment_542" class="wp-caption alignright" style="width: 310px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/04/m3.png"><img class="size-medium wp-image-542" title="MiniMandelbrot" src="http://www.lucaamore.com/wp-content/uploads/2011/04/m3-300x300.png" alt="" width="300" height="300" /></a><p class="wp-caption-text">Mandelbrot, I: 40 Z: -1.825,-1.705 x -0.06, 0.06</p></div>
<p>Per non appesantire troppo il codice ho deciso di utilizzare come formato delle immagini di output <a title="PPM" href="http://netpbm.sourceforge.net/doc/ppm.html">PPM</a> (tra i più semplici disponibili) e poi convertirlo in PNG, tramite script bash, utilizzando l&#8217;utility <a title="convert" href="http://www.imagemagick.org/script/convert.php">convert</a> di <a title="ImageMagick" href="http://www.imagemagick.org/script/index.php">ImageMagick</a>.</p>
<p>Tutte le immagini dei frattali di questo articolo sono stati generati da frk.</p>
<p>L&#8217;applicazione frk. rilasciata come <a title="Software Libero" href="http://www.gnu.org/philosophy/free-sw.it.html">software libero</a> sotto <a title="GNU General Public License" href="http://www.gnu.org/licenses/gpl.html">licenza GNU/GPL</a>, è disponibile presso:</p>
<p><a title="frk on github" href="https://github.com/lookee/frk">Repository GIT su GITHUB di FRK</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucaamore.com/?feed=rss2&#038;p=283</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rappresentazione dell&#8217;insieme frattale di Mandelbrot in Perl</title>
		<link>http://www.lucaamore.com/?p=331</link>
		<comments>http://www.lucaamore.com/?p=331#comments</comments>
		<pubDate>Thu, 07 Apr 2011 00:17:39 +0000</pubDate>
		<dc:creator>luca</dc:creator>
				<category><![CDATA[algoritmi]]></category>
		<category><![CDATA[caos]]></category>
		<category><![CDATA[frattali]]></category>
		<category><![CDATA[FreeSoftware]]></category>
		<category><![CDATA[GD]]></category>
		<category><![CDATA[Julia]]></category>
		<category><![CDATA[Mandelbrot]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.lucaamore.com/?p=331</guid>
		<description><![CDATA[La rappresentazione dell&#8217;insieme di Mandelbrot, considerato uno dei frattali più popolari, è tra i miei algoritmi di prova preferiti quando studio un nuovo linguaggio di programmazione. L&#8217;algoritmo di base è estremamente semplice e si presta facilmente ad esser parallelizzato. Recentemente, &#8230; <a href="http://www.lucaamore.com/?p=331">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div id="attachment_375" class="wp-caption alignleft" style="width: 310px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/04/800px-Mandelset_hires.png"><img class="size-medium wp-image-375" title="Mandelset" src="http://www.lucaamore.com/wp-content/uploads/2011/04/800px-Mandelset_hires-300x217.png" alt="" width="300" height="217" /></a><p class="wp-caption-text">Mandelbrot</p></div>
<p>La rappresentazione dell&#8217;insieme di <a title="Mandelbrot set Wikipedia" href="http://en.wikipedia.org/wiki/Mandelbrot_set">Mandelbrot</a>, considerato uno dei <a title="Fractal Wikipedia" href="http://en.wikipedia.org/wiki/Fractal">frattali</a> più popolari, è tra i miei algoritmi di prova preferiti quando studio un nuovo linguaggio di programmazione.</p>
<p>L&#8217;algoritmo di base è estremamente semplice e si presta facilmente ad esser parallelizzato.</p>
<p>Recentemente, all&#8217;interno dei Google Labs, è stata rilasciata un&#8217;<a title="Juliamap" href="http://juliamap.googlelabs.com/">applicazione Web</a> che, sfruttando le API di Google Maps e canvas di HTML5, permette la navigazione all&#8217;interno dell&#8217;insieme di Mandelbrot o di altri frattali (es. Julia); vi consiglio di utilizzarla per un tour veloce.</p>
<p><strong>Definizione formale</strong></p>
<p>L&#8217;insieme di Mandelbrot è definito come il sottoinsime del piano complesso per cui la successione ricorsiva:</p>
<img src='http://www.lucaamore.com/wp-content/latex/c9b/c9b85e6ac80d0b9bb07db0a0327e57c3-ffffff-000000-0.png' alt='  P^c_n=  \begin{cases}  &amp; Z_0=0  \\  &amp; Z_{n+1}=Z_n^2+c  \end{cases}  ' title='  P^c_n=  \begin{cases}  &amp; Z_0=0  \\  &amp; Z_{n+1}=Z_n^2+c  \end{cases}  ' class='latex' />
<p>&nbsp;</p>
<p>al tendere di n all&#8217;infinito, rimane limitata nel suo modulo, ovvero:</p>
<img src='http://www.lucaamore.com/wp-content/latex/684/68417579c017727ea2aee2ba8f45a2dd-ffffff-000000-0.png' alt='  M=\left\{c\in \mathbb{C} : \exists s \in \mathbb{R}, \forall n \in \mathbb{N},|P_n^c| \leq s \right\}  ' title='  M=\left\{c\in \mathbb{C} : \exists s \in \mathbb{R}, \forall n \in \mathbb{N},|P_n^c| \leq s \right\}  ' class='latex' />
<p>&nbsp;</p>
<p><strong>Sorgente perl</strong></p>
<p>Ecco un sorgente perl che rappresenta l&#8217;insieme in modalità rigorosamente monocromatica:</p>
<pre class="brush: perl; title: ; notranslate">
#!/usr/bin/perl

##########################
# M A N D E L B R O T
# Luca Amore
##########################

use strict;
use warnings;

use GD;

my $FILENAME = 'mandelbrot.png';
my $ITERATIONS = 30;
my ($SIZEX, $SIZEY) = (700, 400);
my ($RE_MIN, $RE_MAX) = (-2.5, 1.0);
my ($IM_MIN, $IM_MAX) = (-1.0, 1.0);

my $re_factor = ($RE_MAX - $RE_MIN) / $SIZEX;
my $im_factor = ($IM_MAX - $IM_MIN) / $SIZEY;

my $img = new GD::Image-&gt;newTrueColor($SIZEX,$SIZEY)
    or die &quot;Can't create GD::Image&quot;;

# palette
my $cl_black = $img-&gt;colorAllocate(  0,  0,  0);
my $cl_white = $img-&gt;colorAllocate(255,255,255);

open(my $fh, '&gt;', $FILENAME)
    or die &quot;Can't open $FILENAME: $!&quot;;

binmode $fh;

my $C_im = $IM_MIN;

YY: for (my $yy=0; $yy &lt; $SIZEY; $yy++){

    my $C_re = $RE_MIN;

    XX: for (my $xx=0; $xx &lt; $SIZEX; $xx++){

        my ($Z_re, $Z_im, $i) = (0,0);

        # Z0=0, Zn+1 = Zn^2 + C
        ESCAPE_ITERATIONS: for ($i = 1; $i&lt;$ITERATIONS; $i++){

            my ($Z_re2, $Z_im2) = ($Z_re * $Z_re, $Z_im * $Z_im);

            last ESCAPE_ITERATIONS unless ($Z_re2 + $Z_im2 &lt; 4);

            # (a+bi)^2 = a^2 + 2abi - b^2
            $Z_im = 2 * $Z_re * $Z_im + $C_im;
            $Z_re = $Z_re2 - $Z_im2 + $C_re;

        } # end: ESCAPE_ITERATIONS

        # draw pixel
        $img-&gt;setPixel(
            $xx, $yy, $i == $ITERATIONS ? $cl_black : $cl_white
        );

        $C_re += $re_factor;

    } # end: XX

    $C_im += $im_factor;

} # end: YY

# save image
print $fh $img-&gt;png(0);
close $fh;
</pre>
<p>Il codice è stato mantenuto semplice per facilitare le modifiche e la comprensione.</p>
<p>E&#8217; richiesto il package <a title="GD" href="http://search.cpan.org/~lds/GD-2.45/GD.pm">GD</a> per la produzione dell&#8217;immagine di output in formato PNG: &#8220;<em>mandelbrot.png</em>&#8220;.</p>
<div id="attachment_437" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/04/mandelbrot.png"><img class="size-medium wp-image-437  " title="mandelbrot" src="http://www.lucaamore.com/wp-content/uploads/2011/04/mandelbrot-300x171.png" alt="" width="300" height="171" /></a><p class="wp-caption-text">mandelbrot.png generato dal sorgente perl</p></div>
<p style="text-align: center;">&nbsp;</p>
<p><span style="color: #000000;"><strong>Colori</strong></span></p>
<p>Normalmente, per rendere tale frattale più gradevole, nella sua rappresentazione più semplice, si colorano i punti esterni all&#8217;insieme in funzione della velocità con la quale divergono a più infinito. Per la colorazione dei punti interni ed esterni esistono una miriade di algoritmi di complessità crescente; <a title="Colorazione insieme di Mandelbrot" href="http://www.mrob.com/pub/muency/color.html">alcuni spunti interessanti</a>.</p>
<p><strong>Insieme di Julia</strong></p>
<p>Una variante dell&#8217;insieme di Mandelbrot è l&#8217;insieme di <a title="Julia Set Wikipedia" href="http://en.wikipedia.org/wiki/Julia_set">Julia</a> definito in questo modo:</p>
<img src='http://www.lucaamore.com/wp-content/latex/f38/f383e34dffc6491b0494813ebcd7c2b6-ffffff-000000-0.png' alt='  Q_n^K(c)=  \begin{cases}  &amp; Z_0=c  \\  &amp; Z_{n+1}=Z_n^2+K  \end{cases}  ' title='  Q_n^K(c)=  \begin{cases}  &amp; Z_0=c  \\  &amp; Z_{n+1}=Z_n^2+K  \end{cases}  ' class='latex' />
<p>&nbsp;</p>
<p>Rispetto all&#8217;insieme di Mandelbrot cambia la successione ricorsiva ed è stata introdotta una costante complessa K.</p>
<p>Analogamente a Mandelbrot i punti appartenenti all&#8217;insieme di Julia sono quelli per cui il modulo della successione ricorsiva non diverge.</p>
<img src='http://www.lucaamore.com/wp-content/latex/452/4522a7cb6025534b7ac4c0917bbc6d3c-ffffff-000000-0.png' alt='  J=\left\{c\in \mathbb{C} : \exists s \in \mathbb{R}, \forall n \in \mathbb{N},|Q_n^K(c)| \leq s \right\}  ' title='  J=\left\{c\in \mathbb{C} : \exists s \in \mathbb{R}, \forall n \in \mathbb{N},|Q_n^K(c)| \leq s \right\}  ' class='latex' />
<p>&nbsp;</p>
<p>Alcuni valori di K che si consiglia di esplorare:</p>
<ul>
<li>K = 0.353+0.288i</li>
<li>K = -0.70176-0.3842i</li>
<li>K = -0.835-0.2321i</li>
<li>K= -0.45+0.1428i</li>
</ul>
<p>Dopo aver adeguato lo script perl, ho rappresentato questi insiemi di Julia:</p>
<div id="attachment_438" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/04/julia1.png"><img class="size-medium wp-image-438 " title="julia1" src="http://www.lucaamore.com/wp-content/uploads/2011/04/julia1-300x270.png" alt="" width="300" height="270" /></a><p class="wp-caption-text">Insieme di Julia (K=0.353+0.288i)</p></div>
<ul></ul>
<div id="attachment_439" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/04/julia2.png"><img class="size-medium wp-image-439" title="julia2" src="http://www.lucaamore.com/wp-content/uploads/2011/04/julia2-300x166.png" alt="" width="300" height="166" /></a><p class="wp-caption-text">Insieme di Julia (K=-0.835-0.2321i)</p></div>
<p><strong>Riferimenti</strong></p>
<p><span style="color: #000000;"><a title="Mandelbrot Set Wikipedia" href="http://en.wikipedia.org/wiki/Mandelbrot_set">Mandelbrot Set &#8211; Wikipedia</a><a title="Mu-Ency - The Encyclopedia of the Mandelbrot Set" href="http://www.mrob.com/pub/muency.html"><br />
Mu-Ency &#8211; The Encyclopedia of the Mandelbrot Set<br />
</a><a title="The Mandelbrot Set (algoritmo tracciamento)" href="http://warp.povusers.org/Mandelbrot/">The Mandelbrot Set (algoritmo tracciamento)<br />
</a><a title="Julia Set Wikipedia" href="http://en.wikipedia.org/wiki/Julia_set">Julia Set &#8211; Wikipedia</a><br />
<strong><br />
Esplorazione</strong></span></p>
<p><a title="Visual Guide To Patterns In The Mandelbrot Set" href="http://www.miqel.com/fractals_math_patterns/mandelbrot_fractal_guide.html">Visual Guide To Patterns In The Mandelbrot Set<br />
</a><a title="Mandelbrot: World Map and Popular Tourist Areas" href="http://66.39.71.195/Derbyshire/manguide.html">Mandelbrot: World Map and Popular Tourist Areas<br />
</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucaamore.com/?feed=rss2&#038;p=331</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>AI: sviluppo di un giocatore artificiale di Reversi</title>
		<link>http://www.lucaamore.com/?p=161</link>
		<comments>http://www.lucaamore.com/?p=161#comments</comments>
		<pubDate>Mon, 07 Mar 2011 02:15:23 +0000</pubDate>
		<dc:creator>luca</dc:creator>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[alfabeta]]></category>
		<category><![CDATA[FreeSoftware]]></category>
		<category><![CDATA[giochi]]></category>
		<category><![CDATA[pygame]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Reversi]]></category>
		<category><![CDATA[Reversi42]]></category>
		<category><![CDATA[sdl]]></category>
		<category><![CDATA[strategia]]></category>

		<guid isPermaLink="false">http://www.lucaamore.com/?p=161</guid>
		<description><![CDATA[Nei giochi di strategia a turni, ho sempre ammirato le grandi sfide tra uomo e calcolatore; epiche battaglie tra pensiero strategico umano e forza tattica del calcolatore; equilibrio precario tra sinapsi e silicio, agilità contro forza, tensione tra grande visione &#8230; <a href="http://www.lucaamore.com/?p=161">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.lucaamore.com/wp-content/uploads/2011/03/Tuerkischer_schachspieler_racknitz3_sm-e1299020285953.jpg"><img class="alignleft size-medium wp-image-189" title="Tuerkischer_schachspieler_racknitz3_sm" src="http://www.lucaamore.com/wp-content/uploads/2011/03/Tuerkischer_schachspieler_racknitz3_sm-300x270.jpg" alt="Il Turco" width="300" height="270" /></a>Nei giochi di strategia a turni, ho sempre ammirato le grandi sfide tra uomo e calcolatore; epiche battaglie tra pensiero strategico umano e forza tattica del calcolatore; equilibrio precario tra sinapsi e silicio, agilità contro forza, tensione tra grande visione d&#8217;insieme ed imponente valutazione di ogni dettaglio<em>. </em>L&#8217;epilogo può essere violento: il pensiero strategico umano si prende gioco della miopia del calcolatore e lo annichilisce; la forza bruta del calcolatore devasta il giocatore umano conducendolo verso una combinazione di cui ha previsto ogni minima variante.</p>
<p>Sfide dove a vincere è sempre l&#8217;uomo: il grande maestro oppure la squadra di progettisti che ha concepito un giocatore artificiale in grado di competere contro la finezza del pensiero umano.</p>
<p>In <a title="Il computer e gli scacchi" href="http://www.parodos.it/storia/argomenti/il_computer_e_gli_scacchi.htm">questo articolo</a>, ho trovato una citazione degli autori del programma scacchistico <a title="Deep Thought" href="http://en.wikipedia.org/wiki/Deep_Thought_(chess_computer)">Deep Throught</a> (precursore di <a title="Deep Blue" href="http://it.wikipedia.org/wiki/Deep_Blue">Deep Blue</a>) sullo stile di gioco del calcolatore:</p>
<blockquote><p>&#8220;&#8230; il computer non        imita il pensiero umano &#8211; raggiunge gli stessi obiettivi per vie diverse.        Vede lontano, ma osserva poco; ricorda tutto, ma non impara niente. Non fa        sbagli clamorosi, ma non si innalza mai al disopra della sua normale        abilità. Eppure talvolta produce intuizioni che sfuggono anche a grandi        maestri.&#8221;</p></blockquote>
<p style="text-align: left;">(<a title="Feng-hsiung_Hsu" href="http://it.wikipedia.org/wiki/Feng-hsiung_Hsu">Hsu</a>, F., Anantharaman, T.,        Campbell, M., Nowatzyk, A. &#8211; &#8220;<em>A Grandmaster Chess Machine</em>&#8220;,        Scientific American, Ottobre 1990)<em> </em></p>
<p><strong>realizzazione di Reversi42 in Python</strong></p>
<div id="attachment_248" class="wp-caption alignleft" style="width: 310px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/03/Reversi42.1.png"><img class="size-medium wp-image-248" title="Reversi42.1" src="http://www.lucaamore.com/wp-content/uploads/2011/03/Reversi42.1-300x240.png" alt="Reversi42 screenshot" width="300" height="240" /></a><p class="wp-caption-text">Reversi42 screenshot</p></div>
<p>In questi giorni ho provato a realizzare un prototipo di giocatore automatico di Reversi in Python (sto approfondendo ancora la conoscenza di questo linguaggio) che ho battezzato Reversi42 (in onore di Douglas Adams e della famosa domanda<em>: &#8220;</em><a title="The Ultimate Question of Life, the Universe and Everything" href="http://www.google.com/search?q=The+Ultimate+Question+of+Life%2C+the+Universe+and+Everything"><em>The Ultimate Question of Life, the Universe and Everything</em></a><em>&#8220;)</em>.</p>
<p>Non finirò mai di ringraziare Donato Barnaba, maestro della FNGO (<a title="FNGO" href="http://www.fngo.it">Federazione Nazionale Gioco Othello</a>), per il suo prezioso aiuto, la sua disponibilità e grande competenza (anche dal punto di vista dei giocatori automatici); senza di lui lo sviluppo di Reversi42 non sarebbe stato così stimolante e divertente! Reversi42, allo stato attuale, è solo un prototipo; eventuali imprecisioni sono da attribuire solo a me!</p>
<p>Reversi42, come altre mie realizzazioni, è un <a title="software libero" href="http://www.gnu.org/philosophy/free-sw.it.html">software libero</a> rilasciato sotto la licenza <a title="licenza GNU/GPL" href="http://www.gnu.org/licenses/gpl.html">GNU/GPL</a>; siete incoraggiati a studiarne il sorgente, migliorarlo e farci tutto ciò che desiderate; ogni commento o contributo sarà gradito.</p>
<p>Di <a title="Othello/Reversi" href="http://it.wikipedia.org/wiki/Othello">Reversi</a> esiste un libro di Brian Rose che lo presenta così: <em>&#8220;un minuto per imparare&#8230; una vita per diventare maestri&#8221;</em>; le regole del gioco sono facili da apprendere (e quindi da codificare) ma il gioco può essere estremamente complesso dal punto di vista strategico e tattico (ottima sfida per la realizzazione di un giocatore automatico).</p>
<div id="attachment_249" class="wp-caption alignright" style="width: 310px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/03/Reversi42.2.png"><img class="size-medium wp-image-249" title="Reversi42.2" src="http://www.lucaamore.com/wp-content/uploads/2011/03/Reversi42.2-300x240.png" alt="Reversi42 screenshot" width="300" height="240" /></a><p class="wp-caption-text">Reversi42 screenshot</p></div>
<p>Nella progettazione del motore AI di gioco, ho deciso di adottare l&#8217;approccio classico che viene adottato in tutti i giochi di strategia ad informazione perfetta per due giocatori: si esplora in profondità l&#8217;albero delle possibili mosse valutando la bontà di ogni posizione ottenuta; si assume, inoltre, che l&#8217;avversario risponda sempre con la migliore mossa disponibile.</p>
<p>Trattandosi di un prototipo, sviluppato principalmente nei ritagli di tempo, ho voluto concentrare la mia attenzione solo sugli algoritmi e non sull&#8217;ottimizzazione delle singole procedure.</p>
<p>Citando <a title="Donald E. Knuth" href="http://it.wikipedia.org/wiki/Donald_Knuth">Donald E. Knuth</a>:</p>
<blockquote><p>“We should forget about small efficiencies, say about 97% of the  time: <strong>premature optimization is the root of all evil</strong>. Yet we should not  pass up our opportunities in that critical 3%. A good programmer will not  be lulled into complacency by such reasoning, he will be wise to look  carefully at the critical code; but only after that code has been  identified”.</p></blockquote>
<div id="attachment_251" class="wp-caption alignleft" style="width: 310px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/03/GRhino_vs_Reversi42.2.png"><img class="size-medium wp-image-251" title="GRhino_vs_Reversi42" src="http://www.lucaamore.com/wp-content/uploads/2011/03/GRhino_vs_Reversi42.2-300x175.png" alt="GRhino vs Reversi42" width="300" height="175" /></a><p class="wp-caption-text">screenshot sfida tra GRhino e Reversi42 (test)</p></div>
<p>Ho comunque introdotto alcune metriche (certamente migliorabili) per valutare efficienza e sensitività (rispetto a modifiche) dei punti critici dell&#8217;algoritmo.</p>
<p>La guida di riferimento che ho adottato è: <a title="Strategy Game Programming" href="http://www.fierz.ch/strategy.htm">&#8220;Stategy Game Programming&#8221;</a> di Martin Fierz che propone un graduale ed avvincente percorso tra le principali tecniche adottate per la costruzione di un buon giocatore automatico per giochi strategici (es. scacchi, dama, Reversi, forza quattro).</p>
<p>Le problematiche affrontate nella realizzazione del prototipo sono:</p>
<ul>
<li>ricerca nell&#8217;albero delle posizioni della mossa più efficace</li>
<li>realizzazione di una buona valutazione della posizione</li>
<li>sintesi delle regole del gioco Reversi</li>
</ul>
<p><strong>Ricerca nell&#8217;albero delle posizioni della mossa più efficace</strong></p>
<p>Lo scopo di questo problema (indipendente dal tipo di gioco) è quello di costruire l&#8217;albero di tutte le mosse possibili e percorrerlo in profondità ricercando la mossa migliore; si assume che l&#8217;avversario giochi sempre le mosse migliori.</p>
<p>All&#8217;aumentare della profondità di analisi (D), che condiziona la forza del giocatore, il numero di mosse da valutare (M) cresce esponenzialmente in funzione del fattore Branch Factor medio (B) tipico di ogni gioco.<strong><br />
</strong></p>
<img src='http://www.lucaamore.com/wp-content/latex/b08/b08c82215f1ff2c48b318fa7f3717c41-ffffff-000000-0.png' alt='M=B^{D}' title='M=B^{D}' class='latex' />
<p>Valori tipici del Branch Factor medio (B):</p>

<table id="wp-table-reloaded-id-1-no-1" class="wp-table-reloaded wp-table-reloaded-id-1">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Gioco</th><th class="column-2">Branch Factor (B)</th>
	</tr>
</thead>
<tbody>
	<tr class="row-2 even">
		<td class="column-1">Reversi</td><td class="column-2">7</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">Forza quattro</td><td class="column-2">7</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">Dama</td><td class="column-2">10</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">Scacchi</td><td class="column-2">40</td>
	</tr>
	<tr class="row-6 even">
		<td class="column-1">Go</td><td class="column-2">300 (!!!)</td>
	</tr>
</tbody>
</table>

<div id="attachment_191" class="wp-caption alignnone" style="width: 512px"><a href="http://www.lucaamore.com/wp-content/uploads/2011/03/df_over_bf.png"><img class="size-full wp-image-191   " title="df_over_bf" src="http://www.lucaamore.com/wp-content/uploads/2011/03/df_over_bf.png" alt="M=BF^DF" width="502" height="300" /></a><p class="wp-caption-text">andamento del numero di mosse da analizzare al variare del gioco e profondità (in scala semilogaritmica)</p></div>
<p>Il mio obiettivo era quello di raggiungere una profondità di gioco (D) di 5-8 al fine di realizzare un giocatore automatico discreto; sul mio netbook riesco a giocare, a profondità (D) pari a 6, con tempi di attesa sempre ragionevoli (inferiori al minuto).</p>
<p>L&#8217;algoritmo di ricerca adottato è quello della <a title="Potatura Alfa Beta" href="http://it.wikipedia.org/wiki/Potatura_alfa-beta">potatura alfa-beta</a> (in forma negamax), estremamente più efficace del <a title="Minimax" href="http://it.wikipedia.org/wiki/Minimax">minimax</a> poichè è in grado di escludere dalla ricerca (pruning) interi rami dell&#8217;albero che condurrebbero a mosse non convenienti rispetto ad altre già individuate.</p>
<p>Per massimizzare il numero di rami da potare è opportuno introdurre un criterio euristico per ordinare in sequenza le mosse da valutare; le migliori mosse dovrebbero esser analizzate per prime. Rispetto all&#8217;algoritmo minimax, che richiede l&#8217;analisi di tutto l&#8217;albero delle possibili mosse (<img src='http://www.lucaamore.com/wp-content/latex/b08/b08c82215f1ff2c48b318fa7f3717c41-ffffff-000000-0.png' alt='M=B^{D}' title='M=B^{D}' class='latex' />), nel caso migliore della potatura alfa beta, ovvero nel caso ideale di ordinamento perfetto (le mosse più forti vengono valutate per prime), le posizioni da analizzare si abbattono a <img src='http://www.lucaamore.com/wp-content/latex/c31/c31ee63018e93922290d15f7aba046a1-ffffff-000000-0.png' alt='M=\sqrt{B^D}=B^{\frac{D}{2}}' title='M=\sqrt{B^D}=B^{\frac{D}{2}}' class='latex' />; siamo in grado di raddoppiare la profondità di analisi a parità di risorse di calcolo impiegate!</p>
<p>Il criterio euristico, con il quale vengono ordinate le mosse prima dell&#8217;alfa-beta su Reversi42, è quello di assegnare una priorità statica a tutte le mosse della scacchiera; le celle che hanno un valore più basso hanno maggiore priorità e vengono esplorate per prime (es. gli angoli).</p>

<table id="wp-table-reloaded-id-2-no-1" class="wp-table-reloaded wp-table-reloaded-id-2">
<tbody>
	<tr class="row-1">
		<td class="column-1">1</td><td class="column-2">8</td><td class="column-3">7</td><td class="column-4">6</td><td class="column-5">6</td><td class="column-6">7</td><td class="column-7">8</td><td class="column-8">1</td>
	</tr>
	<tr class="row-2">
		<td class="column-1">8</td><td class="column-2">9</td><td class="column-3">7</td><td class="column-4">4</td><td class="column-5">4</td><td class="column-6">7</td><td class="column-7">9</td><td class="column-8">8</td>
	</tr>
	<tr class="row-3">
		<td class="column-1">7</td><td class="column-2">5</td><td class="column-3">3</td><td class="column-4">2</td><td class="column-5">2</td><td class="column-6">3</td><td class="column-7">5</td><td class="column-8">7</td>
	</tr>
	<tr class="row-4">
		<td class="column-1">6</td><td class="column-2">4</td><td class="column-3">2</td><td class="column-4"></td><td class="column-5"></td><td class="column-6">2</td><td class="column-7">4</td><td class="column-8">6</td>
	</tr>
	<tr class="row-5">
		<td class="column-1">6</td><td class="column-2">4</td><td class="column-3">2</td><td class="column-4"></td><td class="column-5"></td><td class="column-6">2</td><td class="column-7">4</td><td class="column-8">6</td>
	</tr>
	<tr class="row-6">
		<td class="column-1">7</td><td class="column-2">5</td><td class="column-3">3</td><td class="column-4">2</td><td class="column-5">2</td><td class="column-6">3</td><td class="column-7">5</td><td class="column-8">7</td>
	</tr>
	<tr class="row-7">
		<td class="column-1">8</td><td class="column-2">9</td><td class="column-3">7</td><td class="column-4">4</td><td class="column-5">4</td><td class="column-6">7</td><td class="column-7">9</td><td class="column-8">8</td>
	</tr>
	<tr class="row-8">
		<td class="column-1">1</td><td class="column-2">8</td><td class="column-3">7</td><td class="column-4">6</td><td class="column-5">6</td><td class="column-6">7</td><td class="column-7">8</td><td class="column-8">1</td>
	</tr>
</tbody>
</table>

<p>Da quando è stato adottato questo ordinamento, le prestazioni della ricerca sono aumentate notevolmente; molto spesso la mossa migliore ricade tra le prime analizzate.</p>
<p><strong>Valutazione della posizione</strong></p>
<p>La valutazione della posizione è un elemento cruciale di un giocatore artificiale in quanto  ne condiziona: strategia, tattica ed efficienza. Occorre ponderare due parametri contrastanti: l&#8217;accuratezza dell&#8217;analisi e l&#8217;efficienza computazionale. Riuscire a trovare un compromesso ottimale tra queste due caratteristiche è un arte che si affina con l&#8217;esperienza! Un algoritmo di valutazione troppo accurato potrebbe rallentare la ricerca e quindi penalizzare eccessivamente la profondità di analisi; un algoritmo rapido ma poco accurato potrebbe perdere grandi opportunità.</p>
<p>In questo prototipo ho impostato la partita su due momenti distinti:</p>
<ul>
<li><strong>apertura e mediogioco:</strong> meno del 70% delle pedine non sono state giocate</li>
<li><strong>finale:</strong> almeno il 70% delle pedine sono state giocate</li>
</ul>
<p>In <strong>apertura e mediogioco</strong> ho cercato di massimizzare la mobilità, ovvero il numero di mosse disponibili che potranno essere utilizzate per dominare il finale; ho anche assegnato dei pesi ad alcune case strategiche che concorrono alla conquista degli angoli (caselle stabili).</p>

<table id="wp-table-reloaded-id-3-no-1" class="wp-table-reloaded wp-table-reloaded-id-3">
<tbody>
	<tr class="row-1">
		<td class="column-1">10</td><td class="column-2">-3</td><td class="column-3">0</td><td class="column-4">0</td><td class="column-5">0</td><td class="column-6">0</td><td class="column-7">-3</td><td class="column-8">10</td>
	</tr>
	<tr class="row-2">
		<td class="column-1">-3</td><td class="column-2">-7</td><td class="column-3">0</td><td class="column-4">0</td><td class="column-5">0</td><td class="column-6">0</td><td class="column-7">-7</td><td class="column-8">-3</td>
	</tr>
	<tr class="row-3">
		<td class="column-1">0</td><td class="column-2">0</td><td class="column-3">0</td><td class="column-4">0</td><td class="column-5">0</td><td class="column-6">0</td><td class="column-7">0</td><td class="column-8">0</td>
	</tr>
	<tr class="row-4">
		<td class="column-1">0</td><td class="column-2">0</td><td class="column-3">0</td><td class="column-4">0</td><td class="column-5">0</td><td class="column-6">0</td><td class="column-7">0</td><td class="column-8">0</td>
	</tr>
	<tr class="row-5">
		<td class="column-1">0</td><td class="column-2">0</td><td class="column-3">0</td><td class="column-4">0</td><td class="column-5">0</td><td class="column-6">0</td><td class="column-7">0</td><td class="column-8">0</td>
	</tr>
	<tr class="row-6">
		<td class="column-1">0</td><td class="column-2">0</td><td class="column-3">0</td><td class="column-4">0</td><td class="column-5">0</td><td class="column-6">0</td><td class="column-7">0</td><td class="column-8">0</td>
	</tr>
	<tr class="row-7">
		<td class="column-1">-3</td><td class="column-2">-7</td><td class="column-3">0</td><td class="column-4">0</td><td class="column-5">0</td><td class="column-6">0</td><td class="column-7">-7</td><td class="column-8">-3</td>
	</tr>
	<tr class="row-8">
		<td class="column-1">10</td><td class="column-2">-3</td><td class="column-3">0</td><td class="column-4">0</td><td class="column-5">0</td><td class="column-6">0</td><td class="column-7">-3</td><td class="column-8">10</td>
	</tr>
</tbody>
</table>

<p>Vengono assegnati punti di bonus se si occupano angoli mentre, se si conquistano delle case adiacenti agli angoli, vengono assegnate delle penalità poiché sarà più difficile difendere l&#8217;angolo dalla conquista avversaria. Le case adiacenti all&#8217;angolo perdono la loro penalità quando l&#8217;angolo è conquistato.</p>
<p>Nel <strong>finale</strong> si ricerca la vincita della partita oppure, grazie alla mobilità ottenuta in apertura e nel mediogioco, si inizia a massimizzare il numero di pedine possedute rispetto a quelle dell&#8217;avversario. L&#8217;errore fatale, tipico di giocatori mediocri di Reversi, è proprio quello di perseguire intuitivamente tale obiettivo sin dalla prima mossa.</p>
<p><strong>Sorgenti</strong></p>
<p><a title="browse or download sources of Reversi42" href="https://github.com/lookee/Reversi42"></a><a title="Reversi42" href="https://github.com/lookee/Reversi42">Visualizza o scarica i sorgenti dal repository su github</a></p>
<p>richiede:<br />
<a title="pygame" href="http://www.pygame.org">python-pygame</a> &#8211; SLD bindings for games development in Python</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucaamore.com/?feed=rss2&#038;p=161</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>John Conway&#8217;s Game of Life in Python</title>
		<link>http://www.lucaamore.com/?p=113</link>
		<comments>http://www.lucaamore.com/?p=113#comments</comments>
		<pubDate>Mon, 14 Feb 2011 02:12:30 +0000</pubDate>
		<dc:creator>luca</dc:creator>
				<category><![CDATA[Automi Cellulari]]></category>
		<category><![CDATA[Conway's Life]]></category>
		<category><![CDATA[FreeSoftware]]></category>
		<category><![CDATA[pygame]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[sdl]]></category>

		<guid isPermaLink="false">http://blog.lookee.it/?p=113</guid>
		<description><![CDATA[Come primo progetto in Python, ho deciso di realizzare una semplice versione del famosissimo automa cellulare di Conway: &#8220;Game of Life&#8221;. Quick start Per maggiori informazioni su Life vi rimando alla pagina di Wikipedia in italiano oppure in inglese ed &#8230; <a href="http://www.lucaamore.com/?p=113">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Come primo progetto in Python, ho deciso di realizzare una semplice versione del famosissimo automa cellulare di Conway: &#8220;Game of Life&#8221;.</p>
<div id="attachment_135" class="wp-caption alignleft" style="width: 282px"><a href="http://blog.lookee.it/wp-content/uploads/2011/02/jaGOF1.png"><img class="size-full wp-image-135 " title="jaGOF" src="http://www.lucaamore.com/wp-content/uploads/2011/02/jaGOF1.png" alt="jaGOF - just another Game of Life screenshoot" width="272" height="242" /></a><p class="wp-caption-text">screenshot di jaGOF</p></div>
<p><strong>Quick start</strong></p>
<p>Per maggiori informazioni su Life vi rimando alla pagina di Wikipedia in <a title="Gioco della vita" href="http://it.wikipedia.org/wiki/Gioco_della_vita">italiano</a> oppure in <a title="Game of Life" href="http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">inglese</a> ed ai vari riferimenti ed approfondimenti che citerò al termine di questo articolo.</p>
<p>Se utilizzate un browser che supporta l&#8217;HTML5 potete provare velocemente <a title="Game of Life HTML5" href="http://sixfoottallrabbit.co.uk/gameoflife/">Life in HTML5</a>.</p>
<p><strong>The Game of Life</strong></p>
<p>The Game of Life, concepito al termine degli anni 60 dal matematico britannico John Horton Conway, è un automa cellulare che simula l&#8217;evoluzione di una popolazione tramite regole che stabiliscono vita, nascita, morte di ogni singolo<em> </em>individuo<em>.<br />
</em></p>
<p>La magia di questo gioco sta nella sua semplicità contrapposta alla profondità e complessità dell&#8217;esplorazione dei risultati; piccole variazioni di un solo individuo nella distribuzione della popolazione iniziale possono condurre ad evoluzioni totalmente diverse.</p>
<p>Ogni cella di una popolazione, transitando dallo stato di vita o morte, condiziona l&#8217;evoluzione delle celle confinanti; queste interazioni provocano evoluzioni estremamente complesse ed interessanti anche a partire da configurazioni apparentemente banali.</p>
<p>In molti si sono cimentati nella ricerca di configurazioni iniziali con determinate proprietà o nella classificazione sistematica dei possibili schemi o pattern ricorrenti.</p>
<p><strong>Descrizione formale dell&#8217;algoritmo di evoluzione<br />
</strong></p>
<p>Il mondo è costituito da una griglia rettangolare di N x M celle le quali possono essere in due possibili stati: vive o morte.</p>
<p>Due celle si definiscono confinanti se sono connesse in una delle 8 direzioni possibili (anche in diagonale); i confini del mondo sono tra loro connessi come in un pianeta perfettamente sferico.</p>
<p>Definita una configurazione iniziale di celle, l&#8217;automa simula l&#8217;evoluzione della vita. In intervalli di tempo discreti tutte le cellule del mondo vengono aggiornate simultaneamente (ogni aggiornamento è definito generazione o epoca) seguendo queste regole:</p>
<ul>
<li>una cella viva rimane in vita se esistono 2 o 3 celle vive confinanti (<em>sopravvivenza</em>)</li>
<li>una cella viva muore se confina con meno di due celle vive (<em>isolamento</em>)</li>
<li>una cella viva muore se esistono piu&#8217; di 3 celle confinanti (<em>sovraffollamento</em>)</li>
<li>una cella morta con esattamente 3 celle vive confinanti nasce e diventa viva (<em>riproduzione</em>)</li>
</ul>
<p><strong>Evoluzione e classificazione di alcuni schemi</strong></p>
<p>L&#8217;evoluzione della popolazione può giungere verso l&#8217;estinzione totale della specie oppure verso varie tipologie di configurazioni ricorrenti che possono essere di:</p>
<ul>
<li>tipo statico (<em>blocco, barca</em>)</li>
<li>oscillante (<em>lampeggiatore, rospo</em>)</li>
<li>in movimento o navicelle spaziali (<em>aliante, astronave leggera LWSS</em>)</li>
</ul>
<p>Altri schemi estremamente interessanti sono:</p>
<ul>
<li><em>fucili</em>: stazionari che sparano alianti o navicelle spaziali</li>
<li><em>fumatori</em>: si muovono lasciando in coda frammenti di vita</li>
<li><em>rastrelli</em>: si muovono ed emettono navicelle</li>
<li><em>reattore</em>: lascia una coda di fucili (tasso di crescita quadratico)</li>
</ul>
<p>Su Wikipedia sono disponibili le configurazioni di questi schemi base oppure su <a title="Conway Life iki" href="http://www.conwaylife.com/wiki">ConwayLife Wiki</a> o su  <a title="Life Wiki" href="http://www.conwaylife.com/wiki">Life Lexicon</a> è possibile trovare una classificazione ancora più accurata ed estesa.</p>
<p><strong>jaGof: just another Game of Life (la mia realizzazione)<br />
</strong></p>
<p>Per realizzare Life in Python ho utilizzato la libreria Pygame (python-pygame) che si basa su SDL. Potete scaricare i sorgenti di jaGof, rilasciati sotto licenza GNU/GPL v.3, e siete incoraggiati a farne quello che desiderate.</p>
<p>Nella directory seeds sono stati inclusi più di 400 pattern iniziali in formato .cell scaricati da Life Lexicon.</p>
<p>Ricordo che si tratta del mio primo progetto in Python.</p>
<p><a title="jaGOF" href="https://github.com/lookee/jaGOF">Visualizza o scarica i sorgenti dal repository su github</a></p>
<p><strong>Futuri sviluppi</strong></p>
<p>Mi piacerebbe sviluppare un algoritmo automatico per la ricerca di qualche configurazione con determinate proprietà.</p>
<p><strong>Riferimenti</strong></p>
<p><a title="Game of Life HTML5" href="http://sixfoottallrabbit.co.uk/gameoflife/">The Game of Life (HTML5)<br />
Wikipedia (eng): &#8220;Conway&#8217;s Game of Life&#8221;<br />
</a><a title="Life Wiki" href="http://www.conwaylife.com/wiki">Wikipedia(it): &#8220;Gioco della vita&#8221;<br />
LifeWiki<br />
Life Lexicon Home Page</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucaamore.com/?feed=rss2&#038;p=113</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Tuning</title>
		<link>http://www.lucaamore.com/?p=31</link>
		<comments>http://www.lucaamore.com/?p=31#comments</comments>
		<pubDate>Mon, 03 Jan 2011 15:04:50 +0000</pubDate>
		<dc:creator>luca</dc:creator>
				<category><![CDATA[database]]></category>
		<category><![CDATA[libri]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://blog.lookee.it/?p=31</guid>
		<description><![CDATA[Dan Tow, SQL Tuning, O&#8217;Reilly Media Anche se non si tratta di una pubblicazione recentissima, consiglio questo libro a tutti coloro che intendono consolidare la propria comprensione sulle basi del funzionamento interno dei principali DB. Solo dopo aver esposto questi &#8230; <a href="http://www.lucaamore.com/?p=31">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/SQL-Tuning-Dan-Tow/dp/0596005733/">Dan Tow, SQL Tuning, O&#8217;Reilly Media</a></p>
<p><a href="http://www.lucaamore.com/wp-content/uploads/2011/01/sqltuning.gif"><img class="alignleft size-full wp-image-34" title="SQL Tuning" src="http://www.lucaamore.com/wp-content/uploads/2011/01/sqltuning.gif" alt="" width="180" height="236" /></a></p>
<p>Anche se non si tratta di una pubblicazione recentissima, consiglio questo libro a tutti coloro che intendono consolidare la propria comprensione sulle basi del funzionamento interno dei principali DB.</p>
<p>Solo dopo aver esposto questi meccanismi, il libro guida il lettore verso l&#8217;analisi dei vari piani di esecuzione e del loro condizionamento al fine di migliorarne efficienza e robustezza.</p>
<p>Gli esempi fanno riferimento a vecchie versioni di Oracle, DB2, SQL Server; tuttavia i concetti base illustrati, poichè quasi sempre non legati alle varie implementazioni, possono essere estesi facilmente a tutti i possibili DB relazionali.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucaamore.com/?feed=rss2&#038;p=31</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hello world!</title>
		<link>http://www.lucaamore.com/?p=1</link>
		<comments>http://www.lucaamore.com/?p=1#comments</comments>
		<pubDate>Sun, 05 Dec 2010 02:00:43 +0000</pubDate>
		<dc:creator>luca</dc:creator>
				<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://blog.lookee.it/?p=1</guid>
		<description><![CDATA[Mancano pochi minuti alle 2:00 di una notte di dicembre, fuori la temperatura è poco sotto lo zero, mi trovo disteso nel letto al caldo ed ho appena completato la configurazione della macchina che ospiterà il mio nuovo blog. Era &#8230; <a href="http://www.lucaamore.com/?p=1">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.lucaamore.com/wp-content/uploads/2010/12/debian-openlogo-100.png"><img class="alignleft size-full wp-image-58" title="Debian" src="http://www.lucaamore.com/wp-content/uploads/2010/12/debian-openlogo-100.png" alt="" width="100" height="123" /></a>Mancano pochi minuti alle 2:00 di una notte di dicembre, fuori la temperatura è poco sotto lo zero, mi trovo disteso nel letto al caldo ed ho appena completato la configurazione della macchina che ospiterà il mio nuovo blog.</p>
<p>Era da tanto che desideravo farlo.</p>
<p>Mia figlia e mia moglie dormono profondamente mentre io mi diverto a capire come funziona  <a href="http://wordpress.org/">WordPress</a> e m’interrogo sulle tipologie di contenuti che intendo pubblicare.</p>
<p>Ancora non ho trovato un tema definitivo ma ho già avuto modo di costatare quanto sia potente e configurabile WordPress; certamente non sarà il massimo in termini di sicurezza ma è veramente molto usabile.</p>
<p>Il blog è ospitato da una macchina GNU/Linux con <a title="Debian" href="http://www.debian.org/">Debian</a> e risorse estremamente limitate ma spremute fino all&#8217;ultimo MB; sarà più divertente mantenere tutto funzionante.</p>
<p>La mia espressione è simile a quella di mia figlia quando scopre un nuovo gioco; del resto, per quanto riguarda curiosità e la voglia di esplorare, sono rimasto ancora neonato.</p>
<p>Vado solo a vedere alla finestra se sta nevicando e poi mi addormenterò.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lucaamore.com/?feed=rss2&#038;p=1</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

