A battleships tournament server.
Latest commit 693bf68 Jan 25, 2012 Neill Alexander Merge pull request #2 from rrees/master
Leiningen plugin to create the policy file
Failed to load latest commit information.
docs Moved server state into separate namespace Nov 26, 2011
games Simplified the context, and added a replay namespace which has a func… Nov 23, 2011
leiningen Created a lein plugin to hopefully create the required policy file ou… Jan 24, 2012
src/battleships Moved server state into separate namespace Nov 26, 2011
test/battleships Moved server state into separate namespace Nov 26, 2011
.classpath Added Eclipse project files to git Nov 14, 2011
.gitignore Added test to check that can't place ships on top of each other Nov 20, 2011
project.clj Updated docs Nov 16, 2011



This project consists of 2 parts:

  1. A server, using Ring and Compojure, which hosts games of battleships.
  2. A client, which is used to submit players to the server.

I had an idea that we could use something like this in the regular Clojure programming dojo I attend. I wanted something that would enable people to get started coding quickly, and that would provide feedback, and hence motivation, to continue writing code. Quite often I find at the dojo, there is only enough time to get something started and write a little bit of code. I thought this might help by providing a starting point.

The idea is that teams will take the demo.clj code and modify that to play a game of battleships. To do so there are 2 functions that need to be implemented:

(defn place-ship [ship])

(defn next-shot [context opponent-context])

See demo.clj for more information.

Game Rules

There are different variations of the game. The rules for this variation are:

  1. A player keeps firing shells until it misses.
  2. The player is notified that it has sunk a ship.


Clojail Requirement

Because the project uses Clojail, you need to create a file called in your home directory called .java.policy (note the dot at the beginning). This should contain:

grant { permission java.security.AllPermission; };

This basically allows Clojail to set up a sandbox for evaluating the code. There is a helper function available in the battleships.client namespace which will create this file for you:


This isn’t done automatically because, hey, it’s your computer, and it’s not up to me to create files willy nilly on your computer!

Starting the Server

lein ring server

Testing a Player

Write your player and then, from the battleships.client namespace do:

=> (test-player "src/battleships/demo.clj")
cpu E1 = :patrol-boat, ships sunk = [:aircraft-carrier :submarine :destroyer :battleship :patrol-boat]
cpu won in 98 shots!
Test Player lost!

Submitting a Player

Once you are happy with your player, submit as follows:

=> (submit-player "src/battleships/demo.clj" "My Awesome Player" "http://localhost:3000")
Submitting to http://localhost:3000/create
{:status 200, :headers {"date" "Thu, 17 Nov 2011 20:26:45 GMT", "content-type" "text/html; charset=utf-8", "connection" "close", "server" "Jetty(6.1.25)"}, :body "player780"}

The body contains the namespace that was created for the player on the server. Now, if you browse to the server, you will see your player listed, and the score from having played against the computer.

Updating a Player

If you want to update a player, do this – note that you need the namespace that was returned when you created the first player:

=> (update-player "src/battleships/demo.clj" "My Awesome Player" "player809" "http://localhost:3000")
Submitting to http://localhost:3000/update
{:status 200, :headers {"date" "Thu, 17 Nov 2011 20:29:42 GMT", "content-type" "text/html; charset=utf-8", "connection" "close", "server" "Jetty(6.1.25)"}, :body "player809"}

There is probably no point in updating a player, since none of the matches will be replayed. From the point of view of a competition, creating a new player each time is probably a better strategy.


Copyright © 2011 Neill Alexander

Distributed under the Eclipse Public License, the same as Clojure.