Universität Ulm,
Fakultät für Mathematik und Wirtschaftswissenschaften,
SAI
SS 99 || Ferienprojekt zu Allgemeine Informatik II || Puzzle Library
MODULE PuzzleIO
MODULE PuzzleIO;
IMPORT ASCII, Graphics := TermLineGraphics, Puzzle, Read, Streams,
Strings, Terminals, Write;
PROCEDURE ReadMove(s: Streams.Stream; VAR move: Puzzle.Move) : BOOLEAN;
CONST
rowSY = 0; colSY = 1; dashSY = 2; errorSY = 3; eofSY = 4;
TYPE
Symbol = SHORTINT; (* rowSY .. eofSY *)
VAR
line: ARRAY 512 OF CHAR;
input: Streams.Stream;
ch: CHAR;
sy: Symbol; val: SHORTINT;
PROCEDURE NextCh;
BEGIN
IF input.eof OR ~Streams.ReadByte(input, ch) THEN
ch := 0X;
END;
END NextCh;
PROCEDURE GetSy;
BEGIN
WHILE (ch = " ") OR (ch = ASCII.tab) DO
NextCh;
END;
IF (ch >= "a") & (ch <= "z") THEN
ch := CAP(ch);
END;
IF ch = 0X THEN
sy := eofSY;
ELSIF (ch >= "A") & (ch <= CHR(Puzzle.boardsize + ORD("A"))) THEN
sy := rowSY; val := SHORT(ORD(ch) - ORD("A")); NextCh;
ELSIF (ch >= "0") & (ch <= "9") THEN
sy := colSY;
val := SHORT(ORD(ch) - ORD("0")); NextCh;
WHILE (ch >= "0") & (ch <= "9") DO
val := val * 10 + SHORT(ORD(ch) - ORD("0")); NextCh;
END;
IF val >= 1 THEN
DEC(val);
ELSE
sy := errorSY;
END;
ELSIF ch = "-" THEN
sy := dashSY; NextCh;
ELSE
sy := errorSY;
END;
END GetSy;
PROCEDURE ParsePosition(VAR x, y: SHORTINT) : BOOLEAN;
BEGIN
IF sy = rowSY THEN
y := val; GetSy;
IF sy # colSY THEN RETURN FALSE END;
x := val; GetSy;
ELSIF sy = colSY THEN
x := val; GetSy;
IF sy # rowSY THEN RETURN FALSE END;
y := val; GetSy;
ELSE
RETURN FALSE
END;
RETURN TRUE
END ParsePosition;
PROCEDURE ParseMove(VAR move: Puzzle.Move) : BOOLEAN;
VAR
fromx, fromy, tox, toy: SHORTINT;
BEGIN
IF ~ParsePosition(fromx, fromy) THEN RETURN FALSE END;
IF sy # dashSY THEN RETURN FALSE END; GetSy;
IF ~ParsePosition(tox, toy) THEN RETURN FALSE END;
Puzzle.CreateMove(move, fromx, fromy, tox, toy);
RETURN TRUE
END ParseMove;
BEGIN (* ReadMove *)
Read.LineS(s, line);
IF s.count = 0 THEN RETURN FALSE END;
Strings.Open(input, line); NextCh; GetSy;
RETURN ParseMove(move) & (sy = eofSY)
END ReadMove;
PROCEDURE PrintMove(s: Streams.Stream; move: Puzzle.Move);
BEGIN
Write.CharS(s, CHR(move.fromy + ORD("a")));
Write.IntS(s, move.fromx + 1, 1);
Write.CharS(s, "-");
Write.CharS(s, CHR(move.toy + ORD("a")));
Write.IntS(s, move.tox + 1, 1);
END PrintMove;
PROCEDURE PrintSituation(s: Streams.Stream; situation: Puzzle.Situation);
VAR
board: Puzzle.Board;
row, col: INTEGER;
PROCEDURE DrawHorizontalLine(tee: SHORTINT);
VAR
i: INTEGER;
BEGIN
i := 0;
WHILE i < Puzzle.boardsize * 2 - 1 DO
IF ODD(i) THEN
Graphics.Draw(s, tee);
ELSE
Graphics.Draw(s, Graphics.horizontalLine);
END;
INC(i);
END;
END DrawHorizontalLine;
BEGIN (* PrintSituation *)
Puzzle.GetBoard(situation, board);
Graphics.Draw(s, Graphics.upperLeftCorner);
DrawHorizontalLine(Graphics.topTee);
Graphics.Draw(s, Graphics.upperRightCorner);
Write.LnS(s);
row := 0;
WHILE row < Puzzle.boardsize DO
col := 0;
Graphics.Draw(s, Graphics.verticalLine);
WHILE col < Puzzle.boardsize DO
CASE board[row, col] OF
| Puzzle.empty: Write.CharS(s, " ");
| Puzzle.player1: Write.CharS(s, "x");
| Puzzle.player2: Write.CharS(s, "o");
END;
INC(col);
Graphics.Draw(s, Graphics.verticalLine);
END;
Write.IntS(s, row + 1, 1);
Write.LnS(s);
INC(row);
IF row < Puzzle.boardsize THEN
Graphics.Draw(s, Graphics.leftTee);
DrawHorizontalLine(Graphics.cross);
Graphics.Draw(s, Graphics.rightTee);
Write.LnS(s);
END;
END;
Graphics.Draw(s, Graphics.lowerLeftCorner);
DrawHorizontalLine(Graphics.bottomTee);
Graphics.Draw(s, Graphics.lowerRightCorner);
Write.LnS(s);
Write.CharS(s, " ");
col := 0;
WHILE col < Puzzle.boardsize DO
Write.CharS(s, CHR(ORD("a") + col));
Write.CharS(s, " ");
INC(col);
END;
Write.LnS(s);
END PrintSituation;
END PuzzleIO.
SS 99 || Ferienprojekt zu Allgemeine Informatik II || Puzzle Library
Andreas Borchert, 26. Juli 1999