Monday, April 18, 2011

Pirates 0.2: fixes and a chat interface

I released a little update to my Pirates Yesod/Canvas game. Nothing too dramatic, but the new version, still at http://pirates.dyndns-free.com boasts:

  • Fixes in the collision detection code
  • A chat interface, so you can talk to the other ship you're fighting with. Stock up on pirates insults!
  • Fixes in handling of games when a ship leaves the game before it's finished
As I said, nothing too fancy, but I find that polishing off bugs and adding unplanned features is often a good exercise, especially for personal projects where the temptation is great to just move to something else when it kinda works. The chat interface was interesting: the server side code was done in a few minutes, using the same event system as the rest, but I struggled longer with the HTML to get the right positions for everything, as usual... Now it's on the right hand side, outside of the canvas area, which makes the full game area much bigger than the original 800x600, but I don't think I get a lot of mobile users anyways (-;.

I could probably make the game more appealing long term by having a bigger area where more than 2 ships could battle, and have more of a RPG feel to it (maybe be able to log in and out so you keep your ship, be able to repair it in harbours, etc...). I'll see what I have time to do. Any suggestions welcome!

Friday, April 08, 2011

Pirates!! A multi-player browser game with Yesod and Canvas

I can finally open to the public a little game I've made! You can now go to http://pirates.dyndns-free.com and play!
The game is simple: you're sailing a pirate ship, and you have to sink your opponent. You can use cannons, ram the other ship, board it with your blood-thirsty crew. Your speed depends of course on the direction and strength of the wind. You can play alone versus a very dumb AI (mainly to get the hang of the controls), against a friend in a private game, or against any dog on the internet. 
The technology stack is as follows:

  • Hosting is on a free Amazon EC2 instance. Performance is probably not going to be great, but should be sufficient I hope for the traffic I'll be getting!
  • Server side is Yesod 0.7. Coming from the Java/JSP/Struts world it was such a pleasure to work in Haskell, with type safe templates. I have no web server, just warp, since there are very few static files (a few sprites and the tile image).
  • Client side uses Canvas with a sprinkling of JQuery.

As you can see, no database. Information about current games is purely in memory, and I don't keep any long term information about players. I suppose that allowing players to log in with their Google or Facebook id, and keep statistics on their battles would be good, but I'm not sure this little game will get enough traction to warrant it, really... 
The AI also is not great shake, there are only two bots: The Sitting Duck turns to face the wind and stays there. The Drunken Sailor just goes randomly through all possible actions. But hey, it's a multi-player game!
I'm not too sure if I chose the best route for concurrency. I use MVars and modifyMVar.
In fact the more difficult bit was to design the control. I didn't want to a do a full 3D environment, and opted for a top view, but the velocity of the ships was essential, and so providing just direction keys as in more static games wouldn't have worked. Hopefully the way the control works, being disposed on a copy of the boat icon at the top of screen, that turns when you boat turns, will work well. The icons are probably a bit small, it's fine for a mouse but I don't think it could work on a touch screen, unless you have tiny fingers.


A little bit of personal info: inspiration from this game comes from the French magazine "Jeux et Stratégies", that my dad used to get when I was young, and that got me into games. We have still kept all the issues, and issue 22 from August 1983 describes a simple ship battle game, rules written by Michel Brassinne (French warning!). Thanks!


Still it was fun to do!! Hope you enjoy playing it a little!

Friday, April 01, 2011

Install GHC7 and Yesod on Amazon Linux

I've been working lately on a multi-player web game, to actually get to know HTML Canvas (on the client) and Yesod (on the server) properly. I have a first fully functional version of the game, so now is the time to think about hosting. Michael initiated a discussion about it, and in the meantime I decided to investigate Amazon since they offer free instances now on EC2.
The free AMIs (images) come with a version of Linux specific to Amazon, but apparently binary compatible with CentOS, on which GHC and the Haskell Platform have been reported to successfully build.
These are the steps I followed to get everything working, hopefully they can be useful to somebody else. So as per the Amazon Getting Started guide, you connect to your instance with the ec2-user.
First we install through the package manager some useful packages:

sudo yum install make
sudo yum install gcc
sudo yum install zlib-devel
sudo yum install glut
sudo yum install glut-devel

I didn't find gmp, so I downloaded and installed in the default location:

curl -O ftp://ftp.gnu.org/gnu/gmp/gmp-4.3.2.tar.bz2
tar -xjvf gmp-4.3.2.tar.bz2
cd gmp-4.3.2
./configure
make
sudo make install

But afterwards I had issues building some Haskell packages because it didn't like the default install folder of /usr/local/lib, it preferred /usr/lib, so I did:
sudo cp /usr/local/lib/libgmp.* /usr/lib/
But I suppose ./configure --prefix=/usr/lib/ would be the preferred way to do that.

Libbsd is also required otherwise unix-compat fails:

curl -O http://libbsd.freedesktop.org/releases/libbsd-0.2.0.tar.gz
tar -xzvf libbsd-0.2.0.tar.gz
cd libbsd-0.2.0
sudo make install

Then for GHC, I just downloaded the generic binary and installed that. I decided to install Haskell under my home folder.

curl -O http://haskell.org/ghc/dist/7.0.2/ghc-7.0.2-i386-unknown-linux.tar.bz2
tar -xjvf ghc-7.0.2-i386-unknown-linux.tar.bz2
cd ghc-7.0.2
./configure --prefix=/home/ec2-user/haskell
make install

Make sure we know how to find it:
export PATH=$PATH:/home/ec2-user/haskell/bin

Then get the Haskell Platform source and build that, since there is no binary (yet) for our platform:

curl -O http://lambda.galois.com/hp-tmp/2011.2.0.0/haskell-platform-2011.2.0.0.tar.gz
tar -xzvf haskell-platform-2011.2.0.0.tar.gz
cd haskell-platform-2011.2.0.0
./configure --prefix=/home/ec2-user/haskell
make
make install

Once you're there, it's back to familiar ground:

cabal update
cabal install yesod

And there we are!! My deployment platform is ready!

Monday, March 21, 2011

EclipseFP 2.0.4 released: supports GHC 7!

Hello, the demand was HUGE (well, everything is relative :-)) for a version of EclipseFP that could build and run on GHC7. Since the 2.0.3 release there is now a Haskell Platform release that contains GHC7, so we had no excuse... And there it is! Thanks have to go mainly to Alejandro Serrano, for getting Scion to compile with GHC7 and to Thomas Schilling and Matti Niemenmaa, who upgraded their libraries for GHC7.


So what we have is a scion backend that should build both with 6.12 and 7.0, and hopefully work the same on both. We now support test-suite sections in Cabal files, with limited support for running test suites (running just cabal test with no options).


On my To Do list are full support for test-suites (having full launch configurations for Cabal defined tests) and HLint integration. But I'd also like to work on my own project, so don't expect that a release every two weeks is going to be our normal cruising speed.


As usual, just install from the Eclipse update site: http://eclipsefp.sf.net/updates, and bug reports or feature requests should go to the SourceForge forum or the development mailing list.


Happy Haskell Hacking!

Monday, March 07, 2011

EclipseFP 2.0.3 released

It's my pleasure to release EclipseFP version 2.0.3. EclipseFP is a set of Eclipse plugins for Haskell development. Scooter and I have tried to add a few features and hopefully to fix the bugs that were reported by users.

Main things in this version are code completion templates, which enables you to code even quicker!! We also enhanced the Cabal support (you can now set Cabal flags from the project properties, run Cabal install on the project) and simplified the installation (more settings are auto detected).

EclipseFP is alive and well (I use it for all my Haskell work) so please send us all your feedback, bug reports, feature requests!

Use the standard Eclipse Updates Site  or download files. Enjoy!

Friday, January 21, 2011

Evolving a computer with TECS and Genprog

I've started reading The Elements of Computer Systems since it was recommended on Reddit and it's a great read. After the section on boolean gates I decided to have a quick go at build the gates in Haskell. Just implement Nand with pattern matching, and implement all the other gates just in term of functions calls to previously defined gates. The book mentioned "think positive" about implementing Not, so I just T as the second parameter, did't think more about it, even though I wasn't sure having a constant value was OK.



Then I moved on to the other gates. It was interesting to think about boolean logic without Or, for example, after years of only reasoning in terms of And Or and Not. But at some stage I thought "why am I doing this by hand?". I remembered a thread about a new genetic programming library on an Haskell group. Surely generating the gates would be simple enough?
So I got genprog from hackage, and adapted the example for my needs. I started with a very simple system to determine the implementation of Not:



And of course, the result came quickly enough: not a=nand(a,a). No need for a Const at all! Evolution has beaten me! (OK, I'm only a not-so-intelligent designer, I suppose...)
Now, I'm going to see if this approach can take me all the way to the arithmetic unit...

Wednesday, December 01, 2010

EclipseFP 2.0.2 released

I am pleased to announce another release of EclipseFP. Version 2.0.2 should make installation of Scion easier, improve stability and performance of the parsing and building operations, and provide a few new functionalities. You can now configure where the "Open Definition" action will look for definitions (these can be in Haskell source code or Haddock pages): by default it will look in the dependent projects, in your GHC install doc folder, and on Hackage, but you can add more locations in the preferences. You can also generate source distribution via a project export command (that calls cabal sdist).


The release notes are here. To install or upgrade, just point your Eclipse to http://eclipsefp.sf.net/updates. Be sure to configure both the GHC path and the Cabal path in the preferences.


Happy Haskell hacking!

Thursday, November 25, 2010

A simple game in Haskell + SDL

I wanted to play a bit with SDL, and it's always good to step away from actually working on EclipseFP to use it for a "real" project. So I wrote a very primitive game using SDL and SDL_TTF. It's a typing speed game (hence the, ahem, clever pun on the name: TypeClass): you see letters scrolling down the screen and you need to type them, and of course they go faster and faster. Maybe my children will learn to type with it. Maybe not.


I had SDL installed earlier, but of course SDL_TTF proved challenging on my windows machine, but I think it's was all my fault, I probably didn't read the instructions properly or something. Anyway, I only forgotten to set the LIBS variable. When I ran export LIBS=/usr/local/lib/libSDL_ttf.dll.a in my MSYS environment then configure worked fine!


Afterwards it was all plain sailing, really. Just remember to add enableUnicode True in your initialization code so you can get the actual Unicode character typed (I'm on a French keyboard, so typing M gives me the SDL key ;). And of course you need a font file, so I include a GNU FreeFont file with the package. It needs to be in the same folder as the executable.


For some reason, after seeing code that was blocking for SDL events in a loop, I started building the game with two threads, one blocking for events and one looping and drawing, and a MVar in the middle. It worked, but rewriting it in a single normal game loop: process event, update game state, draw made things a lot easier.


This brilliant piece of software that has already made its mark in video game history can be found on Hackage here!


As usual, all feedback is welcome. Possible enhancements are a high score screen, difficulty levels, choosing letters by frequency in English, using Markov chains so that the flow of letters look more natural... The list is infinite!

Thursday, September 30, 2010

EclipseFP 2.0.0 released!

Hello all,

I'm proud to announce version 2.0.0 of EclipseFP, the Eclipse plugin for Haskell coding. The change in the major version number shows that some big changes have been made, even if under the hood:
- the Antlr parsing has been removed
- the JFace based syntax highlighter has been removed
We now rely solely on Scion and the GHC API to provide lexer tokens! This fixes some long standing syntax highlighting bugs while giving us more options for coloring.
Also, we now communicate to the Scion library via standard streams instead of network calls, which should solve some headaches.

There are also loads of bug fixes and small enhancements peppered a bit everywhere, either things that people asked or things that I did for myself, since EclipseFP is (of course) my IDE of choice for my Haskell coding. The release notes can be found here.

Another good news is that I'm not alone in hacking at EclipseFP, scooter has helped a lot with Helios, Cabal 1.6, GHC 6.10 and Mac OS X support, and has a few new features coming up soon!

Just point your Eclipse to the EclipseFP update site, and happy Haskell hacking!!

Friday, September 24, 2010

Haskell Neural Network: plugging a space leak


First, the good news: last week when I posted about my little digit recognition program I had made a mistake in my test code: when I give a rounded eight to my network, it does recognize it, even though it's been trained only with a square eight! Yoohoo!


Also, a few people pointed to online database of handwritten digits so that I could get more data to train my network. I dully downloaded and started working with some files. Soon I knew I had a problem. Not only was the learning slow, but the memory usage of the program showed exponential growth, like using 400MB after a few iterations. Ha ha, I thought, so it's me against lazy evaluation again!


Well, I was right. A couple of strictness annotation in the neuron output calculation function helped performance, nearly making the code twice as fast, but didn't help the memory consumption. Going mad with ! (BangPatterns is your friend) didn't help any more. WTF?


Then I started to read a bit more about seq and Weak Head Normal Form. So when I put a BangPattern in front of a tuple, it evaluates the tuple but not what's inside it. And, lo and behold, if at each learning iteration I traced the network to the standard output, memory usage stayed constant! So I needed to tell Haskell to fully evaluate the network each time, so as not to keep thunks full of arithmetic operations hanging round. A distant memory of a package called deepseq provided me the final help I needed. I didn't use the package itself because I wanted to understand really what's going on, so I just roll out a few lines of my own:



And by calling deepSeq on my network in each iteration, my program runs in constant space! And I looked at the flat line of memory usage in my task manager, and I was pleased. Now, I can try to improve the speed of the dang thing, but that's another set of problems...

Friday, September 17, 2010

Digit recognition with a neural network. First attempt!

I bought myself "On Intelligence", and I thought as the first step on the long road to building an intelligent machine I would go back to neural networks. I have my own little library that seems to work (kind of), so I decided I was going to try to write a little number recognition program. I was inspired of course by ai-junkie, but it was a bit short on details...
So here is the problem: I have a 5x5 grid of LEDs that can be on or off, and I want to recognize the digit that they show. 
The input will be a list of 25 numbers, either 0 (off) or 1 (on)
The output will be a list of 10 numbers, either 0 or 1. The first position of a 1 indicates the result (so if the first element is a 1, it's number 0, etc).
I arbitrarily decide to set the number of hidden neurons to 50, twice the input neurons. So my topology is 25-50-10. 
I train the network with only one version of each digit. For example 3 would be:
*****
    *
 ****
    *
*****
Wrote a few lines of Haskell code to read the training sets (moving from the representation with *, spaces and new lines to the list of 1 and 0, so that 3 becomes: [1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0]).
Then I train the network. It learns after 200 iterations, and successfully recognizes the training sets (ok, so things are working as they should be).
Then the real test: can my network recognize small variants of the training set?
Lets's try with:
****
    *
 ***
    *
****
(a slightly rounded 3): the network answers 3!!
Works also for a slightly rounded 6. But then:
 ***
*   *
 ***
*   *
 ***
(rounded 8) gives me 6. Oh dear... I could probably add more cases in the training sets and hopefully resolve the ambiguities, but there are bigger issues (I know I know, I'm very candid, but it's one thing being told something in a book, and another to build something to actually show it to you). For example:
***
* *
***
Is a small zero that doesn't take the full 5 LED width. My network recognizes 0 when it fills the full square, not when it's smaller (tells me it's a 5).
And of course, 1 is a disaster. The training "1" is a vertical row of LEDs on the left. A vertical row of LEDs on the right gives me 9, usually (and I suppose, 9 has all the LEDs on the right on).
So not only is basic training not sufficient to detect simple variations, but also the fact that we deal with absolute positioning of leds mean than scaling and simple side translations are not supported. So I suppose the next step is to not work with absolute positions, but relative positions of "on" LEDs. Another day's work...

Monday, September 06, 2010

EclipseFP development: using the GHC Lexer

The new version of EclipseFP is slowly coming along. Slowly, because of some holidays, because of a lot of bug fixes, and mainly because of some big changes.
There were a few bugs revolving around syntax highlighting. The original code was using some lexing rules from the JFace packages in Eclipse, but it didn't cover some common enough cases of Haskell syntax, and of course was fairly hopeless at more complex stuff (things like Template Haskell). So I could either trod on and fix the lexing rules for everything, or I could use a different approach. So I decided to use Scion again, and to add support for lexing. Now Scion exposes a method that calls the GHC Lexer on an arbitrary Haskell source. We use the result to color highlight properly the Haskell source code. Of course I have to handle things like CPP preprocessing directives and literal source files myself, but that was ok. The two main issues I had to tackle were performance, and advanced lexing options.
Performance was poor at start, and there are two reasons: the underlying Scion code deals with JSON Strings while the socket code uses ByteStrings, and, I think, the Eclipse console. For the first issue, I'm using now AttoJson, so that Json marshalling is done with ByteStrings and try to use ByteString as much as possible in the code. The Eclipse console is a different matter. I think when too much data is written to it it struggles to update the console control, blocks the UI thread and the whole UI becomes unresponsive. For the moment, I have disabled server output in the console for commands (since now getting the tokens from the source code is quite a big response). Since lexing is also done in the UI thread, we've probably lost a bit in that area, but I feel the advantages (less Haskell knowledge in the Java code, more reliance on the GHC code, which I suspect knows about Haskell pretty well) outweigh the costs.
One funny thing with the Lexer I found: for example when you have TemplateHaskell code in your source file, and you have the TemplateHaskell pragma, the Lexer doesn't automatically set the TemplateHaskell flag. So I decided that I was going to enable all the lexer flags, since performance didn't seem to suffer. Be liberal in what you parse...


Anyway, I'm not going to release the next version right now, a bit of testing is still needed, and there are a few little things that I want to fix. The testing is easy, in a way: I use the development version of EclipseFP to hack the Scion code, so by eating my own dog food I hope that I can release something of value to Haskell programmers.
So don't worry, EclipseFP is coming soon!

Wednesday, June 02, 2010

EclipseFP 1.111 released

I have just released version 1.111 of EclipseFP. You can get it from sourceforge or via the Eclipse update site (http://eclipsefp.sourceforge.net/updates/).
This is mostly a bug-fixing release to ensure compatibility with GHC 6.12.1 (Haskell Platform 2010) and IPv6. It also bundles a version of the Scion source code that it builds under the covers to save people from downloading the source code from github and building it themselves.


There aren't too many feature enhancements because I didn't get any requests for it. I'm not too sure a lot of people are using EclipseFP and are interested in seeing it improved. I suppose now with a Cabalized gtk2hs Leksah becomes more attractive. Anyway, if you have requests for EclipseFP let me know!

Friday, May 28, 2010

Gtk2hs and Leksah on Windows, check!

Things have moved since I posted about the difficulty of being a Haskell programmer on Windows. Now, Gtk2hs has been cabalized and put on Hackage. I went into my MSYS prompt, and it installed like a charm! I've downloaded the latest version of Leksah, and it installed and started properly! As I write this I've seen the initial Leksah screen, and it's now busy referencing my packages (I wonder if giving it the location where Cabal stores the packages it downloads was a good idea, it seem to be taking a while...). 
So I think now all the things I was struggling to get working are now installed and doing fine on my Windows 7 machine! There is hope!

Wednesday, May 05, 2010

Haskell SDL on Windows, check! (hacking required)

Things looked grim. Even though Timothy could get it to work, the SDL Haskell library wouldn't build for me. libSDL itself installed ok and the samples compiled and ran. But I couldn't compile the hsc files because of a linker error: gcc couldn't find SDLMain or whatever. In desperation, I posted to Haskell-cafe. I didn't get a single answer or hint. I was truly alone.
OK, it was time to either give up or take drastic action. And I never give up.

By then I had narrowed the problem. The order of arguments to gcc were wrong for linking, according to the gcc manual: the .o file should be referenced before the SDL libraries on the command line. It would work like that for other people, but for me, on my system, in my corner of the universe, the order was wrong, and that was it. If I tried the same order of arguments on the SDL samples, they would fail to link. If I reverted the arguments, they would succeed.
So I was left with the straight and narrow: I managed to get the source code for hsc2hs from darcs. I fiddled for a while with the include-dirs and extra-lib options so I could get it to compile and produce the same error than I had with the Haskell Platform version, and not some stupid errors about hsFFI.h not found or so.

Then I opened up, hands trembling and sweat pouring from my forehead, Main.hs in an editor. Found the offending lines:
    rawSystemL ("linking " ++ oProgName) beVerbose linker
( [f | LinkFlag f <- flags]
++ [oProgName]
++ ["-o", progName]
)

Changed them to:

      rawSystemL ("linking " ++ oProgName) beVerbose linker
( [oProgName]
++ [f | LinkFlag f <- flags]
++ ["-o", progName]
)
So that the name of the o file would be before the libraries.
Recompiled, copied the exe in the Haskell Platform bin folder...
Relaunched the SDL build...
And watched SDL build and install properly!
Gaped at the first sample of Timothy opening up a blank window that would close when I press a key! (OK, the last print fails, but by now little errors are not going to disturb my feeling of invulnerability).
Danced around my desk!
Had a beer!

Friday, April 30, 2010

Happstack on Window, check! (in a long, round-about, fear-inducing way)

The other day I noted that I couldn't install the darcs version of Happstack on my windows machine. There was a build failure that was reported on the mailing list. So I waited a few days, and tried again. But then, before I started building Happstack, something happened. I don't exactly remember what, I think I was a bit to eager with cabal upgrade, and I upgraded some base packages that I shouldn't have. I remember directory-1.0.1.1 failing to build and having to go through MSYS to get it to build. Then more and more things needed to be upgraded and ghc-pkg check was reporting more and more weird things. When I thought I had upgraded everything, I tried happstack. happstack-util built, but then happstack-data reported that happstack-util couldn't be built because it required both time-1.1.4 and time-2-something. Oh oh. I screwed around for a while. Then I saw some posts on the web talking about removing package.conf.d. In my random experiments with cabal upgrade I had managed to install everything in my user profile and not inside my Haskell Platform directory, so there was hope!
I deleted package.conf.d. ghc-pkg list reported a saner list of packages. I tried building happstack again. Then something "funny" happened: every cabal build I was trying to do first tried to reinstall process-1.0.1.2, and failed every time!! And of course process-1.0.1.2 appeared in the ouput of ghc-pkg list... WTF? Ah, ok, directory-1.0.1.1 is still installed, let's kill the beast! And then everything worked! Happstack built, happstack "hello world" server even runs, life is happy again!
I didn't try to investigate why Cabal or directory-1.0.1.1 were insisting on reinstalling something that I have already. I've seen enough weird things and spent enough time this week away from the nice world of pure lazy functional programming and in dirty low-level configuration and build issues to not care too much anymore...

Wednesday, April 28, 2010

WXWidgets and WxHaskell on Windows, check!

Despite my earlier problems, I finally managed to install WXWidgets and WxHaskell on my Windows machine. Pfiu! I started again from scratch, and things went much better when I installed, as recommended, MinGW and MSYS in different folders. When I need to compile stuff, I only put MinGW in my path, and when I need Unixy tools like make I add MSYS. Of course MinGW has its own version of make, mingw32-make, that works when MSYS make doesn't...

So I installed MinGW in c:\dev\MinGW and:
set PATH=c:\dev\MinGW\bin;c:\dev\MinGW\libexec\gcc\mingw32\3.4.5;%PATH%

Then I modified the WxWidgets config.gcc file to set SHARED=1 UNICODE=1 MONOLITHIC=1.
And then:
mingw32-make -f makefile.gcc BUILD=debug
worked!

Setting new environment variables (wxWidgets is installed in c:\ui):
set WXWIN=c:\ui\wxWidgets-2.8.10
set WXCFG=gcc_dll\mswud

Then I could install then wxdirect, wxcore and wx packages using a few more flags than what a default cabal install would do, for example:
runhaskell Setup configure --extra-lib-dirs=c:\dev\MinGW\lib --extra-include-dirs=c:\dev\MinGW\include --extra-include-dirs=c:\dev\MinGW\include\c++\3.4.5\mingw32 --extra-include-dirs=c:\ui\wxWidgets-2.8.10\include --extra-include-dirs=c:\dev\MinGW\include\c++\3.4.5

And it install, and works!

Thursday, April 22, 2010

The sorry plight of a Windows programmer (aka me)

Having secured fame and fortune with MazesOfMonad, my console based RPG, and having some ideas for some games that would look even better with a graphical front end, I decided it was time to take the bulls by the horn and go seriously into Haskell GUI programming. Well, the bull won and I feel truly gored...
So what's wrong? Well, after fooling around on my Windows 7 computer for a few nights I've achieved nothing. I now have three different copies of MinGW installed in different places. I have tried to installed SDL, GTK2HS, WXWidgets and Happstack and I have failed at all of them. I know WXWidgets is manageable because I've done it before, I only seem to have some include paths issues. libSDL itself installed but not the Haskell bindings. I found somebody with the same problem on the web, that then told me he had given up. I even managed to get Darcs errors with Gtk2Hs. In despair I thought I could develop a web based game but even the darcs version of happstack failed to compile, I remembered then some bug mentioned on the mailing list, so I should probably just download the latest stable version instead of the development branch.
Some problems are down to some silly things I did. For example installing the Haskell Platform in a directory with spaces is not a great idea (I don't remember if it was the default), because then a lot of paths referencing its MinGW install are wrong in the MSYS shell...
But most are due to the Unixy nature of a lot of the GUI components. Now I see a configure script and my blood freezes. I run "cabal install foo" and I get the dreaded message "this package has a configure script, you need to dive into Unix hell". Can you tell me why I have three versions of GCC, and two make a configure script crash with "c compiler cannot create executables" and the third one works? Where can I download one single file that will allow me to have a full MSYS/MinGW setup with most of what I need? I'm sure there are solutions to a lot of the problems I have, and maybe I need to spend more time reading the INSTALL files and such, and download everything from the MinGW files page. But why can't it Just Work? I mean, I work with Java at work, we do GUI work in SWT now and before that in Swing, we use a lot of libraries, and we never run into any installation problem. Maybe once or twice over the past couple of years we had a cross-platform compatibility issue or a library conflict. I know, I know, apples and oranges, but I'm now thinking that writing my own lazy, purely functional language with monads on top of the JVM with Java integration is going to be easier than getting a GUI library with Haskell bindings to work.
I like to write applications, not spend my free time trying to get libraries to install.

Friday, April 09, 2010

Found my neural network bug (three years later)

After the university of Waterloo AI Challenge I went back to a bit of AI programming in Haskell. Three years ago I had written some code to implement a neural network, and it didn't seem to learn as fast as the book said it should. I had not worked on that any more, but I decided to look at it again. And I found a bug!! I mixed up the deltas to pass on from one run to the next. Changing two lines of code makes my network learning much faster.
So now onto something a bit more meaty than exclusive or: very simple character recognition. I want to be able to recognize numbers written as a digital alarm clock would display them (at least mine): you have 7 lights, four vertical and three horizontal, and various patterns make the numbers. If all lights are on, it's 8, if only the middle horizontal light is off we have zero, etc...
I just test things with a network that has 7 input neurons (one for each light), 10 output neurons (one for each number) and 8 hidden neurons (the average between input and output)

g<-getStdGen
n<-network 7 8 10
let trainingSet=[
([1,1,1,-1,1,1,1],[1,0,0,0,0,0,0,0,0,0]), -- 0
([-1,-1,1,-1,-1,1,-1],[0,1,0,0,0,0,0,0,0,0]), -- 1
([1,-1,1,1,1,-1,1],[0,0,1,0,0,0,0,0,0,0]), -- 2
([1,-1,1,1,-1,1,1],[0,0,0,1,0,0,0,0,0,0]), -- 3
([-1,1,1,1,-1,1,-1],[0,0,0,0,1,0,0,0,0,0]), -- 4
([1,1,-1,1,-1,1,1],[0,0,0,0,0,1,0,0,0,0]), -- 5
([1,1,-1,1,1,1,1],[0,0,0,0,0,0,1,0,0,0]), -- 6
([1,1,1,-1,-1,1,-1],[0,0,0,0,0,0,0,1,0,0]), -- 7
([1,1,1,1,1,1,1],[0,0,0,0,0,0,0,0,1,0]), -- 8
([1,1,1,1,-1,1,1],[0,0,0,0,0,0,0,0,0,1]) -- 9
]
let (LNS(n',err,ds),e) = run (initialState n) defaultLearningRate trainingSet (1,1000)

And after something like 150 iterations I get a network that has a low error rate. A little helper method to massage the results:

runNumber n inputs=do
let
(_, output)=exec n inputs
normalized=map (\v->if (1-v)>0.5 then 0 else 1) output
return $ elemIndex 1 normalized

Et voila!

Main> runNumber nn [1,-1,1,1,-1,1,1]
Just 3

Now, things are starting to get interesting! Hopefully I won't wait another three years before trying maybe more complex character recognition.

Thursday, February 11, 2010

Waterloo Contest and Human Intelligence

I've entered the Waterloo university Google AI Challenge, hiding under a cunning nickname, since I saw that you could develop in Haskell, and a few others Haskellers are on it too! At the moment, I'm cruising at around the 110th position, which is not too bad given that I only worked a few hours at night on it (I have a day job, you know...) and that I implemented everything myself since the starter pack wasn't ready when I started working. I've played a bit with the standard strategies, implemented some flood fill, reuse some A* implementation I have.
All of this is interesting, of course, but there is no AI as such. The only intelligence in my code is the one I put in, and the strategies I devised. So I'm thinking of playing around with genetic programming and evolution techniques to try to get my code to find the right strategies at the right time. I have the feeling the trick will be to design something that is not too restricted and is truly able to evolve into some more advanced and complex than what I've designed myself. But hey, I'll learn, even if my program doesn't (-: