Universität Ulm,
Fakultät für Mathematik und Wirtschaftswissenschaften,
SAI
Lösung zu Blatt 4 --- Allgemeine Informatik II (WS 1999)
5. Just a Soccer Game
MODULE Soccer;
IMPORT Read, Streams, UnixFiles, Write;
CONST filename = "cards.txt";
TYPE Card = RECORD
colour: ARRAY 4 OF INTEGER; (* 0: yellow, 1: red, 2: blue, 3; black *)
top: ARRAY 4 OF INTEGER; (* 0 = Body, 1 = Legs *)
orientation: INTEGER; (* 0 NORTH, 1 EAST, 2 SOUTH, 3 WEST *)
position: INTEGER; (* -1: not places, 0: NW ... 8: SE *)
(* position is not needed - just for output *)
END;
VAR
cards: ARRAY 9 OF Card; (* nine cards should be placed on 9 spots *)
board: ARRAY 9 OF INTEGER; (* on the board *)
PROCEDURE PrintBoard(); (* I tried to keep it readable - there are *)
VAR i, j, k: INTEGER;(* shorter ways to do this *)
BEGIN
j := 0;
WHILE j < 3 DO
i := 0;
WHILE i < 3 DO
Write.String(" ");
k := i + 3 * j;
Write.Int(cards[board[k]].colour[cards[board[k]].orientation], 1);
Write.Int(cards[board[k]].top[cards[board[k]].orientation], 1);
Write.String(" ");
INC(i);
END;
Write.Ln;
i := 0;
WHILE i < 3 DO
k := i + 3 * j;
Write.Int(cards[board[k]].colour[(cards[board[k]].orientation + 3)
MOD 4], 1);
Write.Int(cards[board[k]].top[(cards[board[k]].orientation + 3)
MOD 4], 1);
Write.String(" ");
Write.Int(cards[board[k]].colour[(cards[board[k]].orientation + 1)
MOD 4], 1);
Write.Int(cards[board[k]].top[(cards[board[k]].orientation + 1)
MOD 4], 1);
INC(i);
END;
Write.Ln;
i := 0;
WHILE i < 3 DO
k := i + 3 * j;
Write.String(" ");
Write.Int(cards[board[k]].colour[(cards[board[k]].orientation + 2)
MOD 4], 1);
Write.Int(cards[board[k]].top[(cards[board[k]].orientation + 2)
MOD 4], 1);
Write.String(" ");
INC(i);
END;
Write.Ln;
INC(j);
END;
END PrintBoard;
PROCEDURE Valid(n: INTEGER): BOOLEAN; (* n in -1 .. 8 *)
BEGIN
IF n < 1 THEN RETURN TRUE END; (* One or less cards *)
(* Second and thrid row -> there is a card to the north *)
(* IF n > 2 & (wrong colour OR wrong body parts) THEN ... *)
IF (n > 2) & ((cards[board[n]].colour[cards[board[n]].orientation] #
cards[board[n - 3]].colour[(cards[board[n - 3]].orientation + 2)
MOD 4])
OR (cards[board[n]].top[cards[board[n]].orientation] =
cards[board[n - 3]].top[(cards[board[n - 3]].orientation + 2) MOD 4]))
THEN
RETURN FALSE
END;
(* And here we will find a card to the left *)
IF (n MOD 3 # 0) &
((cards[board[n]].colour[(3 + cards[board[n]].orientation) MOD 4] #
cards[board[n - 1]].colour[(cards[board[n - 1]].orientation + 1)
MOD 4])
OR (cards[board[n]].top[(3 + cards[board[n]].orientation) MOD 4] =
cards[board[n - 1]].top[(cards[board[n - 1]].orientation + 1) MOD 4]))
THEN
RETURN FALSE
END;
RETURN TRUE;
END Valid;
PROCEDURE PlaceCard(n: INTEGER); (* n Cards to be placed *)
VAR i, j: INTEGER;
BEGIN
IF ~Valid(8 - n) THEN RETURN END; (* Check situation *)
IF n = 0 THEN PrintBoard(); Write.Ln; RETURN END; (* I am done *)
i := 0;
WHILE i < 9 DO (* Try to place all nice cards *)
IF cards[i].position = -1 THEN (* Card not used *)
j := 0;
WHILE j < 4 DO (* Test the four orientations *)
cards[i].position := 9 - n;
cards[i].orientation := j;
board[9 - n] := i;
PlaceCard(n - 1); (* Recursion *)
INC(j);
END;
cards[i].position := -1; (* Remove Card again *)
board[9 - n] := -1;
END;
INC(i);
END;
END PlaceCard;
PROCEDURE InitCards(): BOOLEAN; (* Read card information *)
VAR s: Streams.Stream;
line: ARRAY 80 OF CHAR;
char: CHAR;
ok: BOOLEAN;
i, j: INTEGER;
BEGIN
IF ~UnixFiles.Open(s, filename, UnixFiles.read, Streams.onebuf, NIL) THEN
RETURN FALSE
END;
ok := TRUE;
i := 0;
WHILE i < 9 DO (* Read the nine cards *)
j := 0;
WHILE j < 4 DO (* read the players' colours *)
Read.IntS(s, cards[i].colour[j]);
ok := ok & (s.count = 1);
Read.CharS(s, char);
ok := ok & (char = ",");
INC(j);
END;
j := 0;
WHILE j < 4 DO (* legs or no legs ... *)
Read.IntS(s, cards[i].top[j]);
ok := ok & (s.count = 1);
IF j < 3 THEN
Read.CharS(s, char);
ok := ok & (char = ",");
END;
INC(j);
END;
cards[i].orientation := 0;
cards[i].position := -1; (* cards are not placed on the board *)
INC(i);
Read.LnS(s);
END;
Streams.Release(s);
RETURN ok;
END InitCards;
BEGIN
IF ~InitCards() THEN Write.String("Could not read file"); Write.Ln; END;
PlaceCard(9);
END Soccer.
And the cards....
0,1,0,2,0,0,1,1
2,0,1,3,0,0,1,1
2,0,3,0,0,1,1,0
2,1,2,3,0,1,1,0
3,0,2,1,0,0,1,1
3,1,2,0,0,0,1,1
2,0,3,1,0,1,1,0
2,3,0,1,0,0,1,1
2,1,0,3,0,0,1,1
Ingo Melzer, 20. Mai 1999