Assignment 4. CS330 Programming Languages, Spring 2004
PLEASE READ CAREFULLY
MISSING DETAILS MAY COST YOU
Details
A random 25% of students will be orally interviewed by me in person
regarding their submission. Make sure you have written everything you
submit. For any function you are trying to write, you can request
what is the desired output for a particular input by email.
Late assignment policy: If the assignment is submitted
within three days from when it was due, you will get half the grade you
would get if you had submitted on time. You will not be able
to submit after three days. (exceptions to this rule only
if you have a VERY important reason).
You will be working in groups of two for this assignment. I understand
that in some cases one student will do more work than their partner.
If that's the case make sure both partners understand well all the code
written. Either of you might be orally interviewed and failure to
understand the code will
result in lower grade for both of you. Learning to work with other
programmers
of various skill leves is essential and it can be unfair but that's
life. Try
to make this a learning experience for both of you. For this assignment
you can choose your partner. Please email me ASAP your choice
of partner.
IMPORTANT: The careful design
and documentation (i.e comments) of
your code will be important factors in your grade. If there is a bug
it's better to report it than hide it. Be honest, precise and clear and
you shall be rewarded. NEVER (at least in this class) sacrifice
clarity for efficiency of execution.
(10% of final grade - 10 points)
A multi-user game engine (mugEngine)
In this assignment you will be
building a game engine that can
be used to create simple multiplayer text adventure games. The basic
goal is to learn how object oriented programming and C++ can
help you in managing global and local state. Inheritance and container
classes from the STL (Standard Template Libaries) will assist you
in this process.
You will be given code for the server/client communication which you
will need to extend to handle the game management. The type of games
you can create using this engine have the typical structure of
adventure games. There are multiple players (one for each client)
that can move around in a world consisting of rooms/locations.
Various items can be found in each mapsite and players can
pick/drop/examine these items. Each item has an attached value.
You can also talk with other players in the game.
For this assignment you are only required to support movement
between map sites and picking/dropping of items. Various minor details
:-)
such as monsters/magic spells/AI controlled players/trading/fighting,
graphics 2d or 3d
and a purpose/goal for the game can be added for fun but are not
required.
On the other hand, an interesting aspect of the game engine is
that you can create new mapsites, new connections between them
and new items while the game is running (only one player called
Builder is allowed to do so).
Here is a sample possible interaction of a client with the game:
> player George
Welcome to the reception hall...
You can see:
Builder
George
A basketball
Available exits:
north
up
Your name is George
> pick basketball
Welcome to the reception hall...
You can see:
Builder
George
Available exits:
north
up
Picked basketball
> examine George
Welcome to the reception hall...
You can see:
Builder
George
Available exits:
north
up
Player George is carrying:
A basketball : 20
> north
NorthRoom
You can see:
George
Available exits:
west
> drop basketball
NorthRoom
You can see:
George
A basketball
Available exits:
west
Dropped basketball
> examine basketball
NorthRoom
You can see:
George
A basketball
Available exits:
west
Leather basketball: 20
You will also be provided with an executable version of my
implementation of the mugEngine
which you can use for reference. As usual there might be
errors/problems here and there
with my implementation as I wrote it quickly during this weekend. I am
sure you will
find them and let me know :-).
Supported Commands
Words in italics are specified by the user. For example playerName can be George or
Tiffany.
- player playerName:
create a new player (each client can control one and only
player)
- exitName: goto to the
room connected by exitName. ValidexitNames depend on the particular
room. Examples could be north, south, teleport, up, down.
- pick itemName:
the player picks the specified item
- drop itemName:
the player drops the specified item
- examine objectName: returns
a longer description of the specified objectNamewhich
can be either a player or an item. For items it is their
description/value for player it is all the items they are carrying
After any player command is executed the current map site is described
together with all the players/items in it as
well as the response for the particular command.
The special player named Builder has the additional ability to create
new rooms/items using the following commands:
- room roomName :
creates a new room - an integer roomId is returned
- connect exitName roomId1 roomId2 : creates an exit in the
room corresponding to roomId1 connecting
it with the room corresponding to roomId2 . Exits are one way
so for for "normal" moves you would have to do
for example : connect north 0 1 and then connect south 1 0.
- item itemName
: creates a new item - an integer itemId is returned
- describe itemId value
description : provides a value and description for a particular
item. For example: describe 1 10 shiny crystal ball will associate the
description "shiny crystal ball" to the item corresponding to 1 and
make it's value equal to 10.
Here are simple commands to add four neighbors to room 0:
room NorthRoom (returns 1)
connect north 0 1
connect south 1 0
room SouthRoom (returns 2)
connect south 0 2
connect north 2 0
etc ...
Suggestions
You are absolutely free to structure the program any way you want.
Here are some suggestions
you might find helpful. Create a base class GameObject from which
Items/Players inherit
common functionality and use dynamic binding (virtual functions) for
the functions
that are specific to each type. Use map<string, GameObject *,
less<string> > to
create "dictionaries" of items/players/posistions. Create a class
MapSite that
contains a dictionary of neighbors (pointer to MapSites) and a
dictionary of
GameObjects. For objects such as MapSites and Items that can not be
removed
from a game you can also use the vector or list containers of the
Standard Template
Library. Use a map<int, string, less<int> > as a dictionary
to associates clients with particular players.
For parsing/printing you will find helpful to use the sstream library
for using string like streams.
To include use include<sstream> using namespace std; and use as
follows:
ostringstream oss;
oss << "Hello" << x << endl;
string res = oss.str();
and
istringstream iss;
iss.str("Hello 5");
string s;
int v;
iss >> s >> v;
Loading/Saving games
By default the server loads the game stored in file init.txt
and writes the current game to file game.txt. You can
change these names by supplying command line arguments
to the server. For exampel:
mugServer initGame.txt saveGame.txt
That you can create interesting
mazes etc and store them as
text files. Notice that the files store the sequence of commands
used to generate the game rather than the game data in some format.
Supporting code
You are going to be provided with skeleton code for a a server, client
program written in C++. The following files will be provided:
Server.cpp
Server.h
Client.cpp
Client.h
Game.h
Game.cpp
Makefile
init.txt (a simple saved game you can use
for starters)
mugServerReference (a working executable version used a a reference
implementation)
The reference code has been compiled for Solaris and runs fine
on the machines in B215. If you want to use windows you will have
to write your own socket code and your submission must compile
in a B215 machine.
mugEngine.tar.gz
init.txt contains a small initial game setup and you need to
type make to compile the skeleton implementation. To understand how
the program works start the reference server by:
./mugServerRefence
and in another shell window start a client and play with :
./mugClient
then start
./mugServer which is the skeleton code you compiled and
only prints the messages. You will need to extend the code
so that mugServer behaves as mugServerReference.
Deliverables
A game engine that supports the basic commands player and builder
commands mentioned above.
The executable implementation can serve as a guide. Please follow the
conventions strictly as
I might be doing automatic testing on this assignment. IMPORTANT: THE ONLY SIZE ASSUMPTION
YOU CAN MAKE IS THAT EACH LINE SENT/RECEIVED BY THE CLIENT/SERVER HAS
MAXIMUM SIZE OF 2048 characters. THE NUMBER OF ROOMS/PLAYERS/ITEMS
SHOULD NOT
BE FIXED AND CAN BE CHANGED WHILE THE GAME IS RUNING. Any program that
makes any such assumption will loose 2 points.
Grading method:
movement commands : 3 points
pick/drop/examine objects : 3 points
builder commands : 3
points
comments/documentation : 1 point
Extra credit
(2pt)
In the late 70s early 80s a group of MIT students created a company
called Infocom
and made some really cool text adventure games. The games were written
in an interpreted language called Z-code. There are a number of Z-code
interpreter
available on the web. Write code for taking an existing z-code game and
creating a multi-user game out of it using your mugEngine. At minimum
you have to be able to support the same-sites and movement between them
as the z-code game and you also might need to extend the functionality
of mugEngine
to support other features.
(3pt)
This extra credit is open ended. Any group who wants to participate
will implement a full game based on extending the mugEngine.
The two best games will win the 3 extra points. Best will be defined
by voting between all participating groups (voting your own group
is not allowed). If only two groups participate they get 3pts for free.