7.0

Week 9 Set a

home work!

Programming Language ISL+

Due Date Monday 10/29 at 9:00pm (Week 9)

Purpose To design the multiplayer version of the project

Finger Exercises

Exercise 1 From HTDP, 318 319

Graded Exercises

You’ve shared the single player version of Minicraft with some early testers, and they all think it’ll be a hit. But they’ve also convinced you that for it to be a true success, players should be able to interact with one another. Indeed, they think that there should be one large world, with many different 20x20 tiles that players can move between. One of the testers, helpfully, offered to implement the server, so all that you and your partner have to do is extend your game to be a suitable multiplayer client.

You and your partner have gone back to your design studio and, in consultation with your anonymous benefactor (i.e., implementer of the server), came up with the following plan:

The multiplayer version of the game is a generalization of the single-player version, where much remains the same. We begin by imagining we have many independent players on their own single-player versions. We then want to have them all exist in the same Minicraft world. To do that, we need to communicate actions between the single-player games (i.e., that I move left, that I place material, etc.), where those actions will then be replayed by the other players. In this setting, the server is relatively "dumb" – it acts primarily as a communication medium between games. All of the logic is still played out by the individual games.

All of the players will exist in a larger world that is made up of many tiles. Each tile is a grid like your single-player game had. The multiplayer game world is a 10x10 grid of tiles, and each tile is a 20x20 grid of cells, so there should be plenty or room for everyone!

The server manages everything about the tiles: you will only be responsible for reporting whenever you move to the server, and if the server detects that you are moving off of one tile and onto another, it will send a new tile to you to load. Loading a tile is also what will happen when you first connect to the server (when it will randomly place you on a tile). The server will also send you the coordinate of which tile you are on, which you should display in your interface.

There are two critical data types that will be used for the multiplayer game:

IDs are small numeric unique identifiers used to identify different players. They will remain the same while a player is connected to the server, but are not guaranteed to be the same if you reconnect. They will be how you are told that other players are doing things.

Your interface should show the IDs on the players, so you can distinguish different players moving around the map!

SExps: The client and server communicate via s-expressions. This means that you’ll have to convert between your data representations and the representations specified in the protocol below. Most likely, you will want to define helper functions to convert common data types like Posn to the representation used (a list with two numbers in it), and also between the representations of things like cells (which in s-expression format are quite error prone) and the representation that you have in your own game.

Further, the server will specify and require coordinates where the origin (0,0) is at the top left. If you, for whatever reason, decided to represent coordinates in some other way, it is your responsibility for converting to these coordinates when you send messages to the server, and converting back when you receive messages from the server.

Finally, scores for gold accumulation are maintained locally – nothing needs to be communicated to the server, and you do not need to maintain the scores of other players.

The server author presented the following protocol to you. These are the messages that the clients should send to the server, and correspondingly the messages that the server will send to the client. Eventually, your game will have to send/understand all of these:

; - MESSAGE PROTOCOL: CLIENT -> SERVER
 
; A CtoS-Message is one of:
 
;  (list 'move 'left)
;  (list 'move 'right)
;  (list 'move 'up)
;  (list 'move 'down)
 
    ; Interpretation: (list 'move dir) means player is (attempting to)
    ; move in the specified direction. This should be sent even if the
    ; move would hit the edge of the screen, as they may then be moved
    ; to the next tile by the server.
 
;  (list 'smash)
 
    ; Interpretation: (list 'smash) means the player is smashing what
    ; is in front of them. This should be sent even if there is no
    ; material in front of them.
 
;  (list 'place 'grass)
;  (list 'place 'rock)
;  (list 'place 'wood)
;  (list 'place 'water)
;  (list 'place 'tnt)
 
    ; Interpretation: (list 'place material) means the player is
    ; (attempting to) place material in front of them, regardless of
    ; whether this will succeed (i.e., (list 'place 'grass) should be
    ; sent even if standing in front of rock).
 
;  (list 'burygold Nat Nat)
 
    ; Interpretation: (list 'burygold x y) means that the client has
    ; generated gold at the specified coordinates. x and y should both
    ; be < 20
 
 
; - MESSAGE PROTOCOL: SERVER -> CLIENT -
 
; A StoC-Message is one of:
 
;  (list 'map ID Posn Cells)
 
    ; Interpretation: (list 'map selfid posn cells) means that we
    ; have moved into a new map tile (which will happen when we first
    ; connect or when we move off of the edge of the screen). selfid
    ; is our unique identifier, so we can find ourself in the map;
    ; posn is the tile position in the larger world (represented as a
    ; list with two Nats in it), which we will display in the UI; and
    ; cells is an s-expression-encoded version of the map.  It is a
    ; list where each item is a list with three items in it:
    ; (1) a position (represented as a list with two items: x and y)
    ; (2) a list of materials ordered from top to bottom, which are all
    ; symbols except TNT, which is represented as (list 'tnt Nat)
    ; (3) and a list of players, which are represented as lists with
    ; two elements: ID and direction ('left, 'right, 'up, or 'down)
 
;  (list 'join (list ID 'left) Nat Nat)
;  (list 'join (list ID 'right) Nat Nat)
;  (list 'join (list ID 'up) Nat Nat)
;  (list 'join (list ID 'down) Nat Nat)
 
    ; Interpretation: (list 'join player x y) means that player (encoded as an
    ; ID & dir pair, like with 'map) just joined (either the game, or moved onto
    ; your tile) at position x y.
 
;  (list 'move ID 'left)
;  (list 'move ID 'right)
;  (list 'move ID 'up)
;  (list 'move ID 'down)
 
    ; Interpretation: (list 'move id dir) means that player with
    ; unique identifier id is trying to move in direction dir.
 
;  (list 'smash ID)
 
    ; Interpretation: (list 'smash id) means that player with unique
    ; identifier id is smashing whatever is in front of them.
 
;  (list 'place ID 'grass)
;  (list 'place ID 'rock)
;  (list 'place ID 'wood)
;  (list 'place ID 'water)
;  (list 'place ID 'tnt)
 
    ; Interpretation: (list 'place id material) means player with
    ; unique identifier id is placing material in front of them.
 
; (list 'burygold Nat Nat)
 
    ; Interpretation: (list 'burygold x y) means that gold should be
    ; placed at the bottom of the stack of materials at position x y.
 
; (list 'left ID)
 
    ; Interpretation: (list 'left id) means that player with unique
    ; identifier id is leaving the tile. They could either be leaving
    ; the game or moving to another tile.

Exercise 2 Change your WorldState data definition (and all relevant other data definitions) to be able to support multiplayer. Carefully think through what will be different and what can remain the same. Your choices now will hopefully allow you to mostly re-use the single-player functionality you have already implemented when you actually implement all the multiplayer functionality.

Exercise 3 Design a function to convert between the s-expression cells representation and your representation of the grid (you might call this sexp->cells or similar). Note that since not all s-expressions will be valid, this function should report appropriate errors if given invalid input. This will be a core part of the handler for the 'map message, though you don’t need to implement the handler yet. Note that you do not need to implement the reverse, as you will not be sending your map to the server!

Some example inputs your function should handle are:

sexp->cells('(((0 0) (grass (tnt 22)) ())
              ((1 0) () ((0 left)))
              ((0 1) (rock gold) ((1 up)))
              ((1 1) (water) ())))
sexp->cells('(((0 0)
               ()
               ((0 down) (1 right)))))
sexp->cells('(((0 0) () ())
              ((1 0) () ())
              ((0 1) () ())
              ((1 1) () ())))

Exercise 4 Write a signature, purpose statement, and stub for the function that will be your on-receive handler, and describe in several sentences (no more than 4) how you anticipate that this function will work, in particular, paying attention to how you will re-use (or not) your existing code.