Software Engineering 2B03: Software Design II
Revised 2003 February 28

Semiformal Specification of the Interface between the
Main Control Program
and the
Student Teams' Player Modules

1. Project Overview

The goal of this project is to design, document, implement, test and run game playing software for the game "Sevens". The software system is divided into two parts: the main control program (MCP) and the student teams' player modules (PM). The player module written by each student team simulates one player playing the game against other teams' player modules. The player modules compete against one another to win the game.

The main control program will be written by a TA and will perform the following functions: shuffling and dealing the cards; deciding which player should play next; determining whether or not a player has played illegally, reported an incorrect result or failed to move; determining which player finally wins and the ranking of the players; keeping track of the state of the game (i.e. the cards in the various locations, whose turn it is, etc.); creating logs of games played; etc.

Each team's player module will contain access routines to perform the following functions:

1. Start a game: receive the various parameters of the game and initialize the player's own record of the state of the game.

2. Receive a card dealt to the player.

3. Receive information about a card dealt to the table.

4. Play a card onto the table in accordance with the rules of the game and report certain data about the play to the main control program.

5. Receive information about another player's move.

The New Game Development Department has certain extensions and modifications of the game in mind and requires that the software to be developed in this project make some provision for future changes. For this reason, some of the ranges of data to be passed between the main control program and the player modules are specified below to be greater than needed for the game of Sevens as it will be played in the 2B03 tournament. Similarly, the player modules should not depend upon certain restrictions in the procedure for playing the game. For example, in Sevens the cards are first dealt to all players and then the players play cards onto the table; no additional cards are dealt after playing begins. In some of the variations the New Game Development Department has in mind, additional cards can be dealt after play begins, the permitted score values of any card symbol(s) and/or the reward or punishment points can be changed during the game. This will not be done in the 2B03 tournament, but the player modules should be designed so that such a sequence of play will be handled correctly, even though the strategy may be poor for such a variation of the game.

Important Note: This document and the rules for the game Sevens constitute the main statement of the requirements for the design project in 2B03. These documents are formulated comparatively precisely and unambiguously, but they are written almost entirely in non-mathematical, non-technical, natural language. You must, therefore, assume that these requirements documents contain either ambiguous or incomplete information, almost certainly both. It is the responsibility of the teams designing the software in question to

before proceeding with the design and development work. It is important to identify such gaps as early as possible in the project. The later ambiguities, incompleteness, etc. are discovered, the greater the consequences will be. The excuses shortly before -- or after -- the submission deadline "but you didn't tell us", "we interpreted the text differently", "how should we have known?", etc. will not be accepted. It is the designers', i.e. the leagues' and teams', responsibility to identify any problems with the requirements that affect the design and its correctness and suitability for purpose and ensure that they are resolved in good time. In this connection, be extremely careful of assuming anything; ask for explicit clarification of any points that could conceivably be interpreted in different ways (almost all natural language text can be interpreted in different ways). In this respect, the design project in 2B03 mirrors actual software development practice; you will almost never get really unambiguous, complete and correct statements of requirements from clients. A multiphase dialog is always needed to achieve a satisfactory specification for the actual design and implementation work. Probably the best way to achieve a workable statement of requirements is to read everything carefully, critically, repeatedly and skeptically and when in doubt, question what you read. Superficial reading will surely get you into trouble. For every phrase you read, ask yourself how many different ways it could possibly be interpreted. If you can think of only one interpretation, you are almost certainly overlooking others.

2. Data crossing the MCP-PM Interface

The types of data passed between the main control program and each player module fall into the following categories. The ranges for the various data items given below allow for future extensions and modifications of the game (see above).

2.1. The number of players in the current game (an integer, 2 to 25 inclusive)

2.2. Player identifier (an integer between 1 and the number of players inclusive)

2.3. Card symbol (a single character from the set of letters, digits and some special characters). Each card symbol will be represented by a unique character, i.e. no two different symbols will be represented by the same character.

2.4. Card suit (a single character from the set of letters, digits and some special characters). Each card suit will be represented by a unique character, i.e. no two different suits will be represented by the same character.

2.5. Card color (a single character from the set of letters, digits and some special characters). Each card color will be represented by a unique character, i.e. no two different colors will be represented by the same character.

2.6. Score value of a card (an integer between -20 and +20 inclusive)

2.7. Reward points parameter (an integer between -50 and +50 inclusive)

2.8. Total score value of the cards on the table (an integer between -6000 and +6000 inclusive)

3. Constants defined in the main control program and available to the player modules

The constants listed below are defined in the main control program, which exports them for use by the player modules. The player modules must use these constants if these data are needed; neither they nor related values may be embedded numerically in the module's program code.

The values in parentheses correspond to the latest information from the New Game Development Department and are subject to further change at any time, including after submission of your player module. In the 2B03 tournament in which player (team) performance is measured, a standard deck of cards will be used, i.e. with 13 symbols, 4 suits and 2 colors, although the values of the constants listed below may be greater. Your program must also run correctly with other types of card decks within the limits of the following constants. Playing an illegal card or failing to play a card with such decks will disqualify a player module from the regular tournament, but performance will not be measured or counted in such trial or qualification games.

MaxNumPlayers (19), the maximum number of players in any Sevens tournament
MaxNumSymbols (16), the maximum number of card symbols in any deck of cards
MaxNumSuits (6), the maximum number of card suits in any deck of cards
MaxNumColors (4), the maximum number of card colors in any deck of cards
The following parameters are numerical constants mentioned in the rules of the game "Sevens". If the total score value of the cards on the table is divisible by 7 or if the decimal (radix 10) representation of the total score value contains a 7, corresponding reward or punishment points are earned. Because the New Game Development Department may, at some time in the future, decide to create variations of the game based on other numbers, the numerical constants 7 and 10 should not appear in the player modules. Instead, use the following constants:
GameSpecialNum (7), the "Sevens" number for reward and punishment points
GameNumRepBase (10), the radix of the number system for representing total score values
These constants are defined in the module named MCPParam.

4. Sequence of calls to the player modules' access routines

To begin a new game, the main control program will call each player's access routine to initialize the game.

Afterward, the main control program will deal the cards, calling the receiving player's access routines to receive a card and to note cards dealt to the table. Each of these routines will be called for each card dealt. The main control program will also call player modules' access routines to pass the game parameters to the players' modules during this part of the initialization phase.

When the above initialization phase is complete, the main control program will call a player's access routine to place a card onto the table. Afterward, the main control program will inform the other players of the one player's move by calling their access routines to receive information about the player's move. This step will be repeated until the game ends.

It has been left undecided whether or not the main control program will call a player's access routine to receive information about the player's own move. The player module should function correctly either way.

5. Player module and access routines to be supplied by each student team and league

The teams' modules are to be named T11, T12, ... T35. The leagues' modules will be named L01, L02 and L03. The numbers are the team and league numbers respectively.

The program to play the card game Sevens in course 2B03 this year will be written in the programming language Oberon-2, with which you are familiar from course 2A04.

The interfaces to the access routines to be supplied by each student team are defined in sections 5.1 through 5.7 below. Values passed to an access routine, if any, are passed by value ("value parameter"). Result values, if any, are returned by name ("variable parameter"). Parameters passed between the main control program and the player modules are either of type INTEGER or type CHAR as appropriate for the data item in question (see section 2 above). The values of all parameters will be in the ranges stated in section 2 above and limited by the constants defined in section 3 above.

All access routines specified below are "proper procedures", not "function procedures".

For further information about the various parameters passed between the main control program and the players' modules, see the rules for the game Sevens.

5.1 Initialize a game

InitGame(NumberOfPlayers, PlayerID)

Notes:

1. Both parameters are passed to the player module's access routine.
2. No results are returned by the player module to the caller.
Interpretation:

A new game is being started in which NumberOfPlayers players are participating. The called player module is identified in this game by the number PlayerID.

5.2 Initialize Score Values

InitScoreValues(CardSymbol, ScoreValue1, ScoreValue2)

Notes:

1. All parameters are passed to the player module's access routine.
2. No results are returned by the player module to the caller.
3. This access routine will be called for each CardSymbol in the deck.
Interpretation:

The values of the parameters ScoreValue1 and ScoreValue2 are permitted score values for cards bearing the symbol CardSymbol. If no choice is permitted, the values of ScoreValue1 and ScoreValue2 will be equal.

5.3 Initialize Colors

InitSuitColor(CardSuit, CardColor)

Notes:

1. All parameters are passed to the player module's access routine.
2. No results are returned by the player module to the caller.
3. This access routine will be called for each CardSuit in the deck.
Interpretation:

A card of the suit CardSuit is of the color CardColor.

5.4 Initialize Reward Points

InitRewardPoints(RewardPoints1, RewardPoints2, RewardPoints3)

Notes:

1. Both parameters are passed to the player module's access routine.
2. No results are returned by the player module to the caller.
Interpretation:

RewardPoints1 reward points are earned by a player when the new total score value of all the cards on the table is divisible by seven. RewardPoints2 reward points are earned by a player when the decimal representation of the new total score value of all the cards on the table contains a seven. RewardPoints3 reward points are earned by a player when both of the two conditions above apply, i.e. when the new total score value of all the cards on the table is divisible by seven and its decimal representation contains a seven.

5.5 Dealing a card to a player

DealToPlayer(CardSymbol, CardSuit)

Notes:

1. Both parameters are passed to the player module's access routine.
2. No results are returned by the player module to the caller.
Interpretation:

The dealer is dealing the specified card to the player whose access routine is being called.

5.6 Dealing a card to the table

DealToTable(CardSymbol, CardSuit, ScoreValue)

Notes:

1. All parameters are passed to the player module's access routine.
2. No results are returned by the player module to the caller.
Interpretation:

The dealer has dealt the card (CardSymbol, CardSuit) to the table and has chosen to count ScoreValue for this card. Each player's access routine will be called in order to pass this information to all players.

5.7 Play a card

PlayCard(CardSymbol, CardSuit, ScoreValue, TableScore, Reward)

Notes:

1. No parameters are being passed to the player module.
2. All parameters are results being returned by the player module to the caller. TableScore is the score value of all cards on the table, including the card currently being played. The value of the parameter Reward is the number of reward or punishment points earned by this play. If no reward or punishment is earned, the parameter Reward must have the value 0.
Interpretation:

The main control program calls this access routine to request the player module to play a card onto the table. The player plays the card (CardSymbol, CardSuit) and has chosen to count ScoreValue for this card, bringing the total score value of all the cards on the table to TableScore and earning the reward or punishment Reward.

5.8 Receive information about a card played by another player

InformPlay(PlayerID, CardSymbol, CardSuit, ScoreValue)

Notes:

1. All parameters are passed to the player module's access routine. Cf. section 5.7 above.
2. No results are returned by the player module to the caller.
Interpretation:

Player PlayerID has just played the card (CardSymbol, CardSuit) onto the table and has chosen to count ScoreValue for it. Cf. section 5.7 above.

6. Importing and exporting identifiers

The student teams' player modules must export the identifiers (names) of the access routines, i.e. InitGame, InitScoreValues, InitSuitColor, InitRewardPoints, DealToPlayer, DealToTable, PlayCard and InformPlay. The player modules are not permitted to export any other identifier except possibly from submodules as provided for in section 7 below.

The student teams' player modules may import the identifiers (names) of the constants specified in section 3 above. The player modules are not permitted to import any other identifier except possibly from submodules as provided for in section 7 below.

7. Source code for the player modules

The player modules must be written in the Oberon-2 programming language as defined and described in the reference manual The Programming Language Oberon-2 by H. Mössenböck and N. Wirth at http://www-vs.informatik.uni-ulm.de/projekte/Oberon-2.Report. (See also the file Oberon.html.) Any deviations from the statements, constructs, etc. specified in that reference manual will be grounds for disqualifying a team's submission from the tournament (with the attendant loss of performance points). In addition, the player module must compile and execute under the system

installed in the computer laboratories in rooms ITB/235 and ITB/236. Failure to compile or execute on this system, regardless of the reason, will be grounds for disqualifying a team's submission from the tournament (with the attendant loss of performance points). Note that "but it runs correctly on my Oberon-2 system at home" or a similar statement will not be accepted as an excuse or a justification for permission to resubmit a player module. Your player module must both (1) conform to the language specification in the specific reference manual cited above and (2) compile and execute on the specific system mentioned above.

8. Submission instructions

Each team and each league should submit the source code of its module(s) as an attachment to an email to SE2B04@CAS.McMaster.CA. (Note the "2B04" in the address, not "2B03". This account has been carried over from previous years.) Indicate in the subject of your email whether this is your optional or final submission and the league or team number, depending on whether you are submitting your team's module(s) or your league's module(s).

If your team or your league has subsidiary modules (see below), submit each module in a separate file. The name of each file must be the name of the module it contains with a file name extension ".m". Attach all files to one email for your league or for your team.

In the source code for the league modules, indicate with comments which parts are from which teams.

The deadlines for submission of your modules are given in the Course Outline.

9. Submodules

9.1 Subcomponents of the player module implemented as (sub)modules

You may, if you wish, organize subcomponents of your player module as Oberon modules. If you do, the name of each module must begin with "T11", "T12", etc. or, in the case of the leagues, "L01", etc. To facilitate interchanging the various submodules of your player module when putting the league module together, you may want to make use of the module renaming mechanism. This is an option in the import list as described in the early part of section 11 (Modules) of The Programming Language Oberon-2. The same synonyms should be used in all your league and team modules, so that no names of the subsidiary modules need to be changed within the various procedures in the player module.

9.2 Placing access routines of the player module into submodules of the player module

In section 5 above, the access routines of the player module are specified. Some teams may, however, wish to define some or all of these access routines in subsidiary modules, not the main player module. One way of doing this is to

and then, in the player module, The assignment statement should be in the module's initialization block which is executed on loading the module. This type of assignment statement will usually constitute the only contents of the module's initialization block.

The following example shows how to do this for the access routine InitGame. In this example, team 99's player module is named T99 and its submodule T99SUB1 actually contains the access routine InitGame.

MODULE T99;
...
IMPORT T99SUB1;
...
VAR InitGame-: PROCEDURE (a, b: INTEGER);
...
BEGIN
InitGame:=T99SUB1.InitGame;
...
END T99.
This will cause any call to T99.InitGame (e.g. by the main control program) to invoke the procedure T99SUB1.InitGame.

Note that the parameter list in the VAR statement above must match the formal parameter list in the declaration of InitGame in module T99SUB1. See the manual The Programming Language Oberon-2 for further information, especially for the definition of "match" at the end of Appendix A.

Thanks go to Jianliang Lin for pointing out this possibility to us.

10. Changes to this document

Changes, if any, to this document will be announced in class and in the announcements file on the 2B03 web site. In addition, this interface specification will be replaced on the web site by the revised version.