Last updated: 2016-06-27 ยท 29 commits

Hello Battleships!

Hello Battleships is a collaborative educational experience making networked multiplayer turn based games.

Battleships was the first implemented game, Memory the second.

Since it is primaryly an educational experience we focus on doing interesting things, like coding the server in Clojure, and writing clients in also interesting ways.

If you want to join in, we would be extatic.

license

http://www.gnu.org/licenses/agpl-3.0.html

So, basically it would be nice if you would contribute back code to the project if you feel like using it.

Discussion about game structures

What should the game structure look like? We would like to be able to support several different game types.

game example in this case eacsh player has separate boards for different aspects, ships, shots, etc

{
 :p1 {:name "joakim"
      :board [[0 0 0 (:ship 2 d)]
              [0 0 0 0]
              [0 0 0 0]
              [0 0 0 0]]}
 :p2 {:name "mattias"
      :board [[0 0 1 0]
              [0 0 0 0]
              [0 0 0 0]
              [0 0 0 0]]}
 }

clojure

another game example in this case the grid is shared for both(or more) players

{
  {:name "joakim" :id :p1}
  {:name "mattias" :id :p2}

 :board [[0 0 :p2 :p1]
         [0 0 0 0]
         [0 0 {:p1 {:ship :l 2 :d d} :p2} 0]
         [0 0 0 0]]


 }

clojure

a layer approach

{
  {:name "joakim" :id :p1}
  {:name "mattias" :id :p2}

  ;;ships
  :entities {
             :p1 [[0 0 (:s 2 d) 0]
                  [0 0 0 0]
                  [0 0 0 0]
                  [0 0 0 0]]
             :p2 [[0 0 (:s 2 d) 0]
                  [0 0 0 0]
                  [0 0 0 0]
                 [0 0 0 0]]}

  ;; shots that were fired
    :shots {
             :p1 [[0 0 1 0]
                  [0 0 0 0]
                  [0 0 0 0]
                  [0 0 0 0]]
             :p2 [[0 0 1 0]
                  [0 0 0 0]
                  [0 0 0 0]
                 [0 0 0 0]]}


 }

clojure

again a shared grid example here im thinking that it feels like its nicer with a shared world and views of the world, that might have fog of war and stuff

{
 :players {{:name "joakim" :id :p1}
           {:name "mattias" :id :p2}}

  ;; 0 should be nil
  :board [[0 0 {:type :shot :owner :p2 }  {:type :ship :owner :p1 :l 2 :dir 'd}   0 0 0 0]
          [0 0 0 0   0 0 0 0]
          [0 0 0 0   0 0 0 0]
          [0 0 0 0   0 0 0 0]

         ]


 }

clojure

so, is this useful for other games? heres Go , seems ok. :type and :owner are generic enough to be usable across games

{
 :players {{:name "joakim" :id :p1}
           {:name "mattias" :id :p2}}

  ;; 0 should be nil
 :board [[{:type 'stone :owner :p1} 0 0] 0 
         [0 0 0 0 ]
         [0 0 0 0 ]
         [0 0 0 {:type 'stone :owner :p2} ]
         ]


 }

clojure currently the structure looks like this:

{:board [[{:view #{mv}} {:view #{mv}} {:entities ({:type ship, :owner mv}), :view #{mv}} {:view #{mv}}]
         [{:view #{mv}} {:view #{mv}} {:view #{mv}} {:view #{mv}}]
         [{:view #{mv}} {:entities ({:type ship, :owner mv}), :view #{mv}} {:view #{mv}} {:view #{mv}}]
         [{:entities ({:type ship, :owner mv}), :view #{mv}} {:view #{mv}} {:view #{mv}} {:entities ({:type ship, :owner mv}), :view #{mv}}]
         [{:view #{jv}} {:view #{jv}} {:entities ({:type ship, :owner jv}), :view #{jv}} {:view #{jv}}]
         [{:view #{jv}} {:view #{jv}} {:view #{jv}} {:entities ({:type ship, :owner jv}), :view #{jv}}]
         [{:view #{jv}} {:entities ({:type ship, :owner jv}), :view #{jv}} {:view #{jv}} {:view #{jv}}]
         [{:entities ({:type ship, :owner jv}), :view #{jv}} {:view #{jv}} {:view #{jv}} {:view #{jv}}]],
 :players #{jv mv},
 :turn 0,
 :last-player nil}

clojure

:view determines if a player can see the cell or not. :entities is a list of things in a cell.

General technology discussion

The server uses http-kit, because its lightweight, simple to work with, and supports websockets nicely.

As of now theres no security implemented, but the friend library seems nice.

There are some beginnings of a json interface, and it just uses plain Clojure and json lib. If we want to do anything more advanced, we are eyeing fnhouse.

Buildinng and running the server

lein run

the web port is atm 7890.

making a self contained jar: lein uberjar

Clients

The idea is to write fat clients using a json rest interface.

There is also a primitive inbuilt html client to test game logic.

Also there is a client done with reagent.

working with clojurescript

Do this in a separate shell, and the cljs files will be compiled to js files automatically. then they will be served from the static dir by httpkit.

lein cljsbuild auto

we use austin as the brepl backend.

cljx for sharing code between clj and cljs.

games

in progress

should be pretty easy

other games

were looking for similar games, with perhaps some simple extra facilities, so we wind up with a toolbox.