Donnerstag, Februar 15, 2007

SE: Maven upon Avon

In diesem Post möchte ich kurz auf das Build- und Eierlegendewollmilchsau-Tool Maven eingehen und auch erklären, wie man es dazu bringen kann, mit Eclipse zusammenzuarbeiten. Auf die Idee gekommen bin ich durch den Artikel Building Eclipse Plugins with Maven 2. Denn das Hauptproblem ist nämlich, dass Eclipse nur eine flache Projektstruktur in seinen Workspaces zulässt, Maven mit seinem Submodul-Mechanismus jedoch hierarchisch angelegte Verzeichnisse bevorzugt. Natürlich kann jede Option irgendwie übersteuert werden, aber der Grund Maven einzuführen ist ja, dass man die Rumkonfiguriererei am Build-Prozess loswerden möchte. Und da gilt halt das wichtige Prinzip: Convention over configuration. Richtet man sich nach den vorgegebenen Best Practices, so werden die Konfigurationsdateien, das sogenannte Project Object Model (pom.xml), nämlich sehr übersichtlich kurz. Viele Annahmen werden dann einfach implizit getroffen.

Die wesentliche Erkenntnis des genannten Artikels war nun für mich, dass man die Maven-Projekte eben nicht in den Eclipse-Workspace kopiert, sondern an ihrem Ort belässt und mit Eclipse dorthin zugreift, d.h. im Workspace befinden sich nur noch die eclipsespezifischen Projekt-Metadaten.

Folgende Schritte habe ich nun in einer Shell ausgeführt:


# myproject als Maven-Projekt anlegen
mvn archetype:create -DgroupId=de.steffen-mazanek -DartifactId=myproject

cd myproject/

# in der pom.xml also packaging-Format pom statt jar eintragen (ist nötig
# wegen der Eigenständigkeit der submodules)
sed -i s/jar/pom/g pom.xml

# das src-Verzeichnis wird an dieser Stelle auch nicht benötigt
rm -r src

# Module anlegen, diese werden automatisch als Module in der Ober-POM
# vermerkt und bekommen in ihre POMs direkt myproject als parent eingetragen
# site ist üblicher Bezeichner für die von Maven zu generierende Projektwebseite
mvn archetype:create -DgroupId=de.steffen-mazanek -DartifactId=myproject-p1
mvn archetype:create -DgroupId=de.steffen-mazanek -DartifactId=myproject-p2
mvn archetype:create -DgroupId=de.steffen-mazanek -DartifactId=myproject-p3
mvn archetype:create -DgroupId=de.steffen-mazanek -DartifactId=myproject-site

# jetzt funktioniert schon install (in den mit archetype erzeugten Projekten ist standardmäßig
# eine Datei App.java enthalten, die Hello World ausgibt...)
mvn install

# Eclipse mit dem Maven repository bekannt machen
mvn -Declipse.workspace="D:\workspace" eclipse:add-maven-repo

# Eclipse-Dateien löschen (ist beim ersten Mal eclipse:eclipse ausführen noch nicht
# wichtig, aber später schon)
mvn eclipse:clean

# .project und .classpath Dateien in jedem Submodul (rekursiv absteigend) anlegen
# die Option downloadSources lädt Abhängigkeiten im Quellcode runter, dieser kann
# dann von Eclipse benutzt werden
mvn eclipse:eclipse -DdownloadSources=true


Jetzt kann in Eclipse die Funktion Import -> Existing projects into Workspace (Option kopieren deaktivieren!!) ausgeführt werden und das Ergebnis ist mehr als ansprechend. Koppelt man das ganze nun noch mit einem Versionsmanagementsystem wie subversion, sollten nun nur noch die Eclipse-Dateien .classpath und .project ausgeschlossen werden. Die haben in einem Repository nämlich nichts verloren.

Möchte man nun zum Beispiel p1 weiter aufteilen, zum Beispiel ein Untermodul p11 anlegen, so ist die Vorgehensweise sehr ähnlich. Es muss im p1-Verzeichnis der src-Ordner gelöscht werden und in die POM für packaging der Wert pom eingetragen werden. Dann erstellt man wieder das Projekt mit archetype, an die groupId fügt man dabei zum Beispiel p1 an.
Hinweis: Die Eclipse-Dateien im p1-Ordner müssen ggf. manuell gelöscht werden, eclipse:clean erwischt die nicht mehr und dann könnte Eclipse etwas spinnen.

Auch das "tiefste" Maven-Modul erscheint auf diese Weise in Eclipse als Toplevel-Projekt.
Ab einer bestimmten Tiefe wird das wahrscheinlich affig, aber dann kann ja der ganz normale Java-Subpaketmechanismus (via Unterordner) genutzt werden.

Sehr zu empfehlen ist übrigens das Maven-Buch Better Builds with Maven, hat mir sehr geholfen. Und auch das Buch Konfigurationsmanagement mit Subversion, Ant und Maven ist ganz brauchbar, zumindest das freigegebene Probekapitel :-)

Tags:

Haskell: Chess

I recently implemented Chess in Haskell. I used a standard minmax-Algorithm and a very simple evaluation function for computing moves.

The following problems and oddities occured:

  • easiest evaluation function: difference of material on board (without any positional judgement)

  • value of the King is infinity, winning threshold a little bit less than infinity :-), because the losing player may have a material advantage, so the threshold should be infinity minus the maximal material value of all pieces but the King

  • winning "player" keeps playing instead of just capturing the king, because he can capture in the future as well and tries to maximize benefit by trying to capture other pieces

  • king is captured by naive algorithm -> delete last two moves (King tries to run away of the chessmate, but is captured nevertheless...)

  • the capturing en passant and castling rules are the worst things from a programmers point of view, because they make moves depending on previous moves, thats why I ignored both rules in my implementation

  • a depth of the game tree of 4 is already very, very slow



Have a look at my implementation at hsChess.zip. You may start trying the test functions exampleGame and exampleMateGame.

Tags: