Due: Wednesday, March 3, 11:59pm
Submission: Create a release on GitHub tagged p4
. Add a p4-exec.zip
to the release containing:
testLevel
executable for the testing tasktests/
Here is a sketch of the p4-exec.zip
layout:
|-- testLevel
|-- tests
| |-- 1-in.json
| |-- 1-out.json
| ...
...
Submit a ZIP with the following on Handins:
Snarl/tests/Level
with all of your testing suite for the testing tasktestLevel
depends ongame-manager.md
and player.md
in Snarl/Planning/
for the design taskHere is a sketch of the Handins ZIP layout:
Snarl
|-- Planning
| |-- game-manager.md
| `-- player.md
|-- tests
| `-- Level
| |-- testLevel.<ext>
| |-- 1-in.json
| ...
`-- src
...
Note: to avoid conflicts in your repository, you might want to rename tests/Level
from Milestone 3 to tests/Room
which now seems a better fitting name for that test harness.
Many of you have noticed that your instructors can’t seem to get their doo-doo together and seem to disagree on basic details about the game. Does an adversary have to move on every turn? Does a level end if all players reach the exit or is one of them sufficient? You correctly caught us making contradictory statements. However, while it is fair to ask these questions, the actual answers to many of them do not (and should not) matter for your design and code.1 Many of them will change and change again, and then change some more. At some point, “final” choices will be made and the finished product will embody those choices.
The bottom line is, weather, moods, requirements, design, software all change. You should strive to design and program for change. Whether an adversary has to move on every turn – that shouldn’t take long to change. Do we require 1 to 4 or 2 to 6 players? Heck, there should be a constant for that somewhere! Does a level end when any or all players reach the exit? Better make that logic easy to find, comprehend, and, ultimately, modify, so when your instructors finally make up their minds, you’re not caught by surprise.
Design the interfaces for the Game Manager and Player components.
For now, the main task of the Game Manager is to accept players to the game and start a game with a single level, which will be provided. Players should provide a unique name when registering.
A Player component represents the interests of the human behind the keyboard in the game. A Player needs to receive updates from the Game Manager at appropriate moments. When it’s the Player’s turn, it needs to communicate the chosen action to the Game Manager.
Include definitions of any auxiliary data you might need to specify these interfaces. Consider any kind of information that is necessary for the Player or the Game Manager in their interaction.
Assume the following for now (also refer to the digression above):
A player can see at most 2 grid units away in any cardinal or diagonal direction. That is, a player (marked X
) can, at any moment, see all the dots in the sketch below.
.....
.....
..X..
.....
.....
A player may choose to stay put.
Players only interact with items on the tile they’ve chosen as their destination.
A player knows its location in relation to the level’s origin.
The order of interaction for a player is: interact with the enemy, interact with the key, and, finally, interact with the exit.
Scope: The purpose of this task is looking at how the Game Manager and Players should interact to start and run a single level. We are looking for data definitions, signatures and purpose statements à la Fundies, or definitions and interface specifications approximating your chosen language (if it has such constructs). Feel free to use examples and diagrams.
We tend to use the term “player” in at least two meanings in discussions about Snarl:
Create a test harness executable testLevel
, which, given a level and a point in the level will output information about that point:
The input JSON is of the following format
[(level), (point)]
where the following data definitions apply.
A (level)
is a JSON object with the following shape:
{
"type": "level",
"rooms": (room-list),
"hallways": (hall-list),
"objects": [ { "type": "key", "position": (point) },
{ "type": "exit", "position": (point) } ]
}
A (room-list)
is a JSON array of (room)
as defined in Milestone 3
A (hall-list)
is a JSON array of (hall)
A (hall)
is a JSON object with the following shape:
{
"type": "hallway",
"from": (point),
"to": (point),
"waypoints": (point-list)
}
A (point)
and (point-list)
are as defined in Milestone 3.
The "from"
and "to"
points specify door tiles on the boundaries of the respective rooms and so are considered a part of the room.
For this task, assume that the given level is valid and that it always contains exactly one key and one exit object.
As output, the testLevel
harness should output the following JSON object to standard output:
{
"traversable": (boolean),
"object": (maybe-object-type),
"type": (room-or-hallway-or-void),
"reachable": (point-list)
}
The data definitions below apply. The order of the fields in the outputted object does not matter.
A (boolean)
is one of
true
false
A (maybe-object-type)
is one of
"key"
"exit"
null
A (room-or-hallway-or-void)
is one of
"room"
"hallway"
"void"
The interpretation for the fields is as follows.
true
if the tile is traversable (door or “floor”, i.e., type 1
or 2
in Milestone 3’s testing task or a hallway), false
otherwise.
Type of the object if the tile contains a key or an exit. Otherwise null
.
The type of the current level segment. "void"
is a grid position which is neither in a room, nor in a hallway.
An array of room origins that are immediately reachable from the current room or hallway (if the given point is in one or the other). For a hallway, these are the rooms which it connects. For a room, these are the rooms which are immediate neighbors of the room, i.e., reachable by crossing exactly one hallway. If the point is not in a hallway or a room, the array should be empty. The order of the points in the array does not matter.
Note: we consider a hallway to be one tile wide. That means, even if you represent a hallway with a wall on either side somewhere, that wall is considered "void"
for the purposes of this assignment.
Create a test suite for testLevel
with at least 3 test file pairs. Your test files must be in pairs, <n>-in.json
and <n>-out.json
, where <n>
is an integer greater than 0. <n>-in.json
should only consist of the input and <n>-out.json
should only consist of the output, both specified above.
Scope: Your executable must run on the Khoury Linux VMs and your tests must be correct. We will be running our own tests and your team’s tests through your testing harness. Ideally, you should not need to modify your code from the previous milestones.
In the example inputs, %LEVEL%
is a placeholder that is to be replaced with the following JSON before feeding to testLevel
.
{ "type": "level",
"rooms": [ { "type": "room",
"origin": [ 3, 1 ],
"bounds": { "rows": 4, "columns": 4 },
"layout": [ [ 0, 0, 2, 0 ],
[ 0, 1, 1, 0 ],
[ 0, 1, 1, 0 ],
[ 0, 2, 0, 0 ] ] },
{ "type": "room",
"origin": [ 10, 5 ],
"bounds": { "rows": 5, "columns": 5 },
"layout": [ [ 0, 0, 0, 0, 0 ],
[ 0, 1, 1, 1, 0 ],
[ 2, 1, 1, 1, 0 ],
[ 0, 1, 1, 1, 0 ],
[ 0, 0, 0, 0, 0 ] ] },
{ "type": "room",
"origin": [ 4, 14 ],
"bounds": { "rows": 5, "columns": 5 },
"layout": [ [ 0, 0, 2, 0, 0 ],
[ 0, 1, 1, 1, 0 ],
[ 0, 1, 1, 1, 0 ],
[ 0, 1, 1, 1, 0 ],
[ 0, 0, 0, 0, 0 ] ] } ],
"objects": [ { "type": "key", "position": [ 4, 2 ] },
{ "type": "exit", "position": [ 7, 17 ] } ],
"hallways": [ { "type": "hallway",
"from": [ 3, 3 ],
"to": [ 4, 16 ],
"waypoints": [ [ 1, 3 ], [ 1, 16 ] ] },
{ "type": "hallway",
"from": [ 6, 2 ],
"to": [ 12, 5 ],
"waypoints": [ [ 12, 2 ] ] } ]
}
Input:
[ %LEVEL%, [6, 10] ]
Expected output:
{
"traversable": false,
"object": null,
"type": "void",
"reachable": []
}
Input:
[ %LEVEL%, [7, 17] ]
Expected output:
{
"traversable": true,
"object": "exit",
"type": "room",
"reachable": [[3, 1]]
}
Input:
[ %LEVEL%, [12, 4] ]
Expected output:
{
"traversable": true,
"object": null,
"type": "hallway",
"reachable": [[3, 1], [10, 5]]
}
02/28/21 |
|
03/01/21 |
|
They do matter if we evaluate your code and claim it’s not doing something we actually told you it shouldn’t be doing. That’s on us and a reason for a regrade.↩︎