{$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 visible[x,y]
and (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
gueltig: Boolean;
eingabeX, eingabeY, eingabeZ: Char;
field : TFIELD;
visible : TVISIBLE;
begin
eingabeX := upcase(eingabeX);
gueltig := FALSE;
cancel := FALSE;
readInput := gueltig
or cancel;
writeln('
Bitte eine Spalte von 1 bis 7 eingeben oder ''
X''
für Abbruch: ');
readln(eingabeX);
case eingabeX
of
'
X': cancel := TRUE;
'
1'..'
7':
begin
gueltig := TRUE;
x := StrToInt(eingabeX);
end;
else readInput := FALSE;
end;
if gueltig
then
begin
writeln('
Bitte eine Zeile von 1 bis 7 eingeben oder ''
X''
für Abbruch: ');
readln(eingabeY);
case eingabeY
of
'
X': cancel := TRUE;
'
1' .. '
7':
begin
gueltig := TRUE;
y := StrToInt(eingabeY);
end
else readInput := FALSE;
end;
end;
if isValidCoord(x,y)
then
begin
writeln('
Bitte ein ''
B''
eingeben, wenn dort eine Bombe markiert werden '+
'
soll, leer lassen zum Aufdecken oder ''
X''
für Abbruch: ');
readln(eingabeZ);
case eingabeZ
of
'
B' : field[x,y] := Bombe;
'
X' : cancel := TRUE;
else readInput := FALSE;
end;
visible[x,y] := TRUE;
end;
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;
eingabe: char;
eingabeX: integer;
eingabeY: integer;
begin
initField(field, visible);
printField(field, visible);
while readInput(x,y,cancel, bomb)
do
begin
writeln('
haha');
printField(field,visible);
end;
readln;
end.