Universität Ulm,
Fakultät für Mathematik und Wirtschaftswissenschaften,
SAI
SS 99 || Ferienprojekt zu Allgemeine Informatik II || Puzzle Library
MODULE ChessClocks
MODULE ChessClocks;
IMPORT Clocks, Objects, Op := Operations, Scales, Services, Shards, Times;
TYPE
Interface = POINTER TO InterfaceRec;
ChessClock = POINTER TO ChessClockRec;
ChessClockRec =
RECORD
(Services.ObjectRec)
if: Interface;
numberOfPlayers: SHORTINT;
timelimit: Times.Time; (* relative *)
abstimelimit: Times.Time; (* absolute *)
END;
Player = SHORTINT; (* player number, starting from 0 *)
TYPE
StartProc = PROCEDURE (chessclock: ChessClock;
auth: Shards.Lid) : BOOLEAN;
StopProc = PROCEDURE (chessclock: ChessClock;
auth: Shards.Lid) : BOOLEAN;
SwitchProc = PROCEDURE (chessclock: ChessClock;
auth: Shards.Lid; player: Player) : BOOLEAN;
RunningProc = PROCEDURE (chessclock: ChessClock) : BOOLEAN;
CurrentPlayerProc = PROCEDURE (chessclock: ChessClock) : Player;
GetClockProc = PROCEDURE (chessclock: ChessClock; player: Player;
VAR clock: Clocks.Clock);
InterfaceRec =
RECORD
(Objects.ObjectRec)
start: StartProc;
stop: StopProc;
switch: SwitchProc;
running: RunningProc;
currentPlayer: CurrentPlayerProc;
getClock: GetClockProc;
END;
(* === private procedures ============================================= *)
PROCEDURE InitModule;
VAR
type: Services.Type;
BEGIN
Services.CreateType(type, "ChessClocks.ChessClock", "");
END InitModule;
PROCEDURE MakeAbsolute(time: Times.Time; VAR abstime: Times.Time);
VAR
timeval: Times.TimeValueRec;
BEGIN
Times.GetValue(time, timeval);
Times.CreateAndSet(abstime, Scales.absolute,
timeval.epoch, timeval.second, timeval.usec);
END MakeAbsolute;
(* === exported procedures ============================================ *)
PROCEDURE Init(chessclock: ChessClock; if: Interface;
numberOfPlayers: SHORTINT;
timelimit: Times.Time);
BEGIN
ASSERT((if.start # NIL) & (if.stop # NIL) & (if.switch # NIL) &
(if.running # NIL) & (if.currentPlayer # NIL) & (if.getClock # NIL));
ASSERT(numberOfPlayers > 0);
ASSERT(Scales.IsRelative(timelimit));
chessclock.if := if;
chessclock.numberOfPlayers := numberOfPlayers;
chessclock.timelimit := timelimit;
MakeAbsolute(timelimit, chessclock.abstimelimit);
END Init;
PROCEDURE Start(chessclock: ChessClock; auth: Shards.Lid) : BOOLEAN;
BEGIN
RETURN chessclock.if.start(chessclock, auth)
END Start;
PROCEDURE Stop(chessclock: ChessClock; auth: Shards.Lid) : BOOLEAN;
BEGIN
RETURN chessclock.if.stop(chessclock, auth)
END Stop;
PROCEDURE Switch(chessclock: ChessClock;
auth: Shards.Lid; player: Player) : BOOLEAN;
BEGIN
RETURN chessclock.if.switch(chessclock, auth, player)
END Switch;
PROCEDURE Running(chessclock: ChessClock) : BOOLEAN;
BEGIN
RETURN chessclock.if.running(chessclock)
END Running;
PROCEDURE CurrentPlayer(chessclock: ChessClock) : Player;
BEGIN
RETURN chessclock.if.currentPlayer(chessclock)
END CurrentPlayer;
PROCEDURE GetClock(chessclock: ChessClock; player: Player;
VAR clock: Clocks.Clock);
BEGIN
chessclock.if.getClock(chessclock, player, clock);
END GetClock;
(* === exported procedures that are not propagated to the impl. *)
PROCEDURE NumberOfPlayers(chessclock: ChessClock) : SHORTINT;
BEGIN
RETURN chessclock.numberOfPlayers
END NumberOfPlayers;
PROCEDURE TimeLeft(chessclock: ChessClock; player: Player;
VAR time: Times.Time);
VAR
clock: Clocks.Clock;
currentTime: Times.Time;
BEGIN
GetClock(chessclock, player, clock);
Clocks.GetTime(clock, currentTime);
Op.Sub3(time, chessclock.abstimelimit, currentTime);
END TimeLeft;
PROCEDURE GetTimeLimit(chessclock: ChessClock;
VAR timelimit: Times.Time);
BEGIN
timelimit := chessclock.timelimit;
END GetTimeLimit;
BEGIN
InitModule;
END ChessClocks.
SS 99 || Ferienprojekt zu Allgemeine Informatik II || Puzzle Library
Andreas Borchert, 26. Juli 1999