6 — Implementing Common Pieces

Due Monday, October 01, midnight

Delivery Add four additional sub-directories to your Santorini folder:
  • Admin, which is where all the administrator-specific code goes;

  • Player for all the player-specific code codes;

  • Common, which is where you place all code that both administrative components and player components need to access; and

  • Lib, for all library-like code you may need.

For this assignment, you will place all Santorini specific artifacts into Common.

Also create a top-level directory 6. Place the xboard artifact in there and place all system-level tests into 6/board-tests.

Design Task The player and the administrative components must communicate. To this end, they must use a common form of data with a common interpretation.You may encounter the terminology of ontology in software engineering courses in this context.

For this game, the common data consists of two major pieces:
  • the physical game pieces, see below

  • the rules of the game

    Develop a specification of the rule checker’s interface. This interface must allow either of the two (players, administrators) to check the basic rules of the game.

    The rule checker’s implementation will also reside in the Common directory of course.

  • the player interface

    Develop a specification of the player’s interface. This interface must enable an administrative component to take a player component thru all phases of the game.

    Recall that software components go thru start up (initialization), steady state, and shut down phases. We are ignoring configurations for now.

Write up your interface specification as a single source file in your chosen language. A good specification will mix technical terms from your language (e.g. function headers, interfaces) and English (purpose statements or data definitions in untyped languages). Keep in mind that a specification must define all terms. Make sure to start the file with a purpose statement.

Implementation Task Implement a data representation of the physical game pieces (the board, buildings, workers, etc.) and their functional capabilities (e.g., you can move a worker from one cell to another).

Knowledge Remember that going from an implementation requires cycling thru the questions "what does the component ‘know’", "which services does it provide", to "how does it implement these services". The board "knows" the following facts:
  • It is the playing field and consists of 36 squares.

  • The squares may contain a building up to four stories tall.

There are no other constraints. In particular, a board does "not" know the rules of the game.

Services A board implementation must be able to move workers, add floors to buildings, and observe basic facts about squares that a player module considers relative to one of its workers.

Mock-up Context To test such a small system of a number of components, it is common to implement a mock-up environment.

Create a system-level test harness called xtest xboard that can read and interpret sequences of well-formed JSON values. Every sequence must begin with a board specification:
  • A Board is [[Cell, ...], ...].

    A Cell is one of: a Height or a BuildingWorker Worker.

    A Height is one of: 0, 1, 2, 3, 4. It indicates (the height of) a building.

    A BuildingWorker is a String that starts with a single digit followed by a Worker. The first digit represents the Height of the building.

    A Worker is a string of lowercase letters that ends in either 1 or 2. The last digit indicates whether it is the first or the second worker of a player. The lowercase letters make up the Name of the player that owns the worker.

    An incomplete row of a Board is filled with trailing, unoccupied Cells.

    A Board specification is valid if it has at most six rows and each row consists of at most six cells. A "short" Board is supplemented with empty rows. It must also contain exactly four Workers, two per player.

followed by an arbitrary number of the following JSON values in arbitrary order:
  • A Move is ["move", Worker, Direction].

    A Direction is [EastWest, NorthSouth] where EastWest is one of: "EAST" "PUT" "WEST" and NorthSouth is one of: "NORTH" "PUT" "SOUTH".

    A Move is valid if the Worker can step to a physical Cell in the specified Direction.

    The harness moves the specified worker in the given direction and prints the empty JSON array.

  • A Build is ["build", Worker, Direction].

    A Build is valid if the Worker can add a floor to the building in the specified neighboring Cell.

    The harness increases the building on the specified cell in the given direction and prints the empty JSON array.

  • A Neighbor Query is ["neighbors", Worker, Direction].

    The query determines whether there is a cell in the give direction, and the harness prints "yes" or "no".

  • A Occupy Query is ["occupied?", Worker, Direction].

    The query determines whether there is worker on the cell in the give direction, and the harness prints "yes" or "no".

  • A Height Query is ["height", Worker, Direction].

    It yields the Height of the building that the worker is looking at.

You may assume that the JSON values of the test inputs are well-formed and valid. Tests that do not satisfy these conditions will be eliminated.

These JSON values do not represent the interface (function/method call) that a board implementation should use, though the test harness must be able to interpret such requests smoothly with the given interface. It does not at all represent my board's interface.

Testing Task Develop at most five system-level tests to be used with your test harness. A test consists of a pair of files: n-in.json and n-out.json where n is in 1, 2, 3, 4 or 5.