{$APPTYPE CONSOLE}
{$R+,Q+,X-}
uses
System.SysUtils,
Windows;
const
FIELDSIZE: Byte = 7;
type
TSize = 1 .. 7;
TSTATE = (leer, Bombe);
TDIR = (Nord, NordOst, Ost, SüdOst, Süd, SüdWest, West, NordWest);
TFIELD =
array [TSize, TSize]
of TSTATE;
TVISIBLE =
array [TSize, TSize]
of Boolean;
const
OFFSET_X:
array [TDIR]
of integer = (0, 1, 1, 1, 0, -1, -1, -1);
OFFSET_Y:
array [TDIR]
of integer = (1, 1, 0, -1, -1, -1, 0, 1);
// Setzt die Ausgabeposition der Konsole auf die angegebene Koordinate.
// @param
// x,y - zu setzende Position in der Konsole an 0/0 = oben links
procedure setConsolePosition(x, y: Byte);
var
coord: _COORD;
begin
coord.x := x;
coord.y := y;
if SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord)
then;
end;
// Setzt die Textfarbe der Konsole
// @param
// color - zu setzender Farbwert
procedure setTextColor(color: word);
begin
if SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color)
then
end;
// Initialisiert das Feld leer und das Sichbarkeitsfeld mit 'false'
// Setzt in gerundet 10% aller Zellen eine Bombe
// @param
// field - Feld, welches initialisiert wird
// visible - zu setzendes Sichtbarkeitsfeld
procedure initField(
var field: TFIELD;
var visible: TVISIBLE);
var
x, y, r, s: integer;
begin
for x := 1
to FIELDSIZE
do
begin
for y := 1
to FIELDSIZE
do
begin
visible[x, y] := FALSE;
field[x, y] := leer;
end;
end;
r := (FIELDSIZE * FIELDSIZE)
div 10;
s := (FIELDSIZE * FIELDSIZE)
mod 10;
if s >= 5
then
inc(r);
// Bomben platzieren
randomize;
while r > 0
do
begin
x := Random(FIELDSIZE) + 1;
// Random liefert einen Wert 0..(FIELDSIZE - 1)
y := Random(FIELDSIZE) + 1;
if field[x, y] = leer
then
begin
field[x, y] := Bombe;
Dec(r);
end;
end;
end;
// Prüft, ob eine Koordinate gültig ist
// @param
// x,y - zu überprüfende Koordinatenwerte
// @out
// Überprüfung ob Koordinate im Bereich des Spielfeldes liegt
// @return
// true, wenn Koordinaten gültig sind
function isValidCoord(x, y: integer): Boolean;
begin
if ((x <= FIELDSIZE)
and (x >= 1))
then
if ((y <= FIELDSIZE)
and (y >= 1))
then
isValidCoord := TRUE
else
isValidCoord := FALSE;
end;
// Zeigt an, wie viele Bomben sich auf den Nachbarzellen, der übergebenen
// Koordinate befinden
// @param
// field - Spielfeld, welches geprüft wird
// x,y - Koordinaten
// @out
// Bestimmung der Nachbarzellen
// @return
// byte-Wert, wie viele Bomben in den Nachbarzellen existieren
function countBombs(field: TFIELD; x, y: TSize): Byte;
var
dir: TDIR;
xNachbar, yNachbar: integer;
n: Byte;
begin
n := 0;
for dir := low(TDIR)
to high(TDIR)
do
begin
xNachbar := x + OFFSET_X[dir];
yNachbar := y + OFFSET_Y[dir];
if field[x, y] = Bombe
then
inc(n);
end;
countBombs := n;
end;
// Textausgabe des Spielfeldes in der Konsole
// @param
// field - Spielfeld, welches ausgegeben werden soll
// visible - augedeckte Zellen
procedure printField(field: TFIELD; visible: TVISIBLE);
var
x, y: Byte;
s:
string;
n: integer;
begin
for x := 1
to FIELDSIZE
do
begin
for y := 1
to FIELDSIZE
do
begin
if not visible[x, y]
then
s := '
▓'
else if field[x, y] = Bombe
then
s := '
ð'
else
begin
n := countBombs(field, x, y);
if n = 0
then
s := '
'
else
s := IntToStr(n);
end;
write(s, '
');
end;
writeln;
end;
end;
// liest vom Benutzer Spalte und Zeile ein und prüft diese. Außerdem wird der
// Benutzer gefragt ob die gewählte Zelle aufgedeckt oder als Bombe markiert
// oder das Programm mit der Eingabe von x beendet werden soll
// @param
// x,y - x- und y-Koordinate des Spielfeldes
// cancel - soll das Spiel verlassen werden?
// bomb - soll eine Bombe markiert werden?
// @out
//
// @return
function readInput(
var x, y: TSize;
var cancel, bomb: Boolean): Boolean;
var
eingabe: char;
gueltig: Boolean;
begin
eingabe := upcase(eingabe);
gueltig := FALSE;
case eingabe
of
'
X':
cancel := TRUE;
'
1' .. '
7':
gueltig := TRUE;
end;
case eingabe
of
'
X':
cancel := TRUE;
'
B':
bomb := TRUE;
end;
readInput := gueltig
or cancel;
end;
// Prüft, ob das gesamte Spielfeld mit Ausnahme der Bomben aufgedeckt ist
// @param
// field - Spielfeld, in dem geprüft werden soll
// visible -Sichtbarkeit der Zellen
// @out
//
// @return
// true, wenn alle Zellen außer die Bomben aufgedeckt sind
(* function isFieldSolved(field : TFIELD; visible :TVISIBLE) : boolean;
begin
while visible or (field = Bombe) do
end; *)
var
field: TFIELD;
visible: TVISIBLE;
cancel, bomb: Boolean;
x, y: TSize;
begin
initField(field, visible);
printField(field, visible);
writeln('
Bitte eine Spalte von 1 bis 7 eingeben oder ''
X''
für Abbruch: ');
readln(x);
if readInput(x, y, cancel, bomb)
then
begin
writeln('
Bitte eine Zeile von 1 bis 7 eingeben oder ''
X''
für Abbruch: ');
readln(y);
if readInput(x, y, cancel, bomb)
then
begin
writeln('
Bitte ein ''
B''
eingeben, wenn dort eine Bombe markiert werden soll, '
+ '
leer lassen zum aufdecken oder ''
X''
für Abbruch: ');
end;
end;
readln;
end.