{Notation
    _c       :cardinal
              b: byte
    _s       : string
              c :char (_sc)
    _b      : boolean
    _i      : integer
    _p      : Pointer auf
            bf     : TBooleanFeld
    _a      :
            300bz : array[0..300] of TBewerteterZug
            b     : array[0..6,0..6] of boolean (TBooleanFeld)
            sfq   : array[0..2047] of TSpielFeldQueuePoint
    _x      : Extended
            s      : Tstatus
            ss     : TStrings
            sf     : TSpielFeld
            sfC    : TSpielFeldC, Klasse zum Spielfeld
            p      : TPoint
            pb     : TPaintBox
            bsf    : TBewertetesSpielFeld
            f      : TFigur
            fb     : TFigurenBilder
            bc     : TBrandubhConfig
            bsfr   : TBrandubhSpielfeldRenderer
            lb     : TListBox
            sh     : TShape
            pa     : TPanel
            ll     : TLinkedList
            za     : TZugAnalyse
            o      : TObject
            c      : TControl/Color
            wc     : TWinControl
            ods    : TOwnerDrawState
            mb     : TMouseButton
            bz     : TBewerteterZug
            ccp    : TCCPanel
}
unit spielvar;

interface
uses windows,classes,sysutils,gauges,dialogs,turbo,extctrls,math,stdctrls,AbstractSpielVar,spielgraph,controls,ccpanel;
type
  Tstatus=(sWeisAmZug,sSchwarzAmZug,sWeisGewann,sSchwarzGewann,sUnentschieden); //status_xs über das Spiel
  TZug=record
    start_xp,ziel_xp:TPoint;
  end;
  TSpielFeld=array[0..6,0..6] of TFigur;
  TBooleanFeld=array[0..6,0..6] of boolean;
  PBooleanFeld=^TBooleanFeld;
  TSpielFeldC=class
    felder_xsf:TSpielFeld;
    status_xs:Tstatus;
    procedure Stellungsanalyse(out result_i:integer);
    function Stellungsanalyse_f():integer;
    procedure GetInfos(out WeiseFiguren_i,SchwarzeFiguren_i,VonWeisErreichbareFelder_i,VonSchwarzErreichbareFelder_i:integer;const randFelderWertvoller_b:boolean);
    function CanFigureFahren(const sx_i,sy_i,zx_i,zy_i:integer):boolean;
    procedure BewegeFigur(const sx_i,sy_i,zx_i,zy_i:integer); //Bewegt eine Figur von sx|sy nach zx|zy
    function Clone:TSpielFeldC;
    procedure CloneOther(const feld_xsfC:TspielfeldC);
    procedure CloneOtherFast(const feld_xsfC:TspielfeldC);
    function isEquals(const feld_xsfC:TSpielFeldC):boolean;

    procedure Init;
  end;

  TBewerteterZug=record //Bewerter Zug, wird vom Analysierer ausgegeben
    startfeld_xp:TPoint;
    zielfeld_xp:TPoint;
    spielfeld_xp:TSpielFeld;
    wert_i:integer;
  end;

  TBewertetesSpielfeld=record
    Spielfeld_xsfC:TSpielFeldC;
    wert_i:integer;
//    status_xs:Tstatus;
  end;

  type TZugAnalyser=class //Analysiert alle Züge mit Hilfe eines MiMaBaUms mit AlphaBetaCurtoff
  protected
    KIModus_b:boolean;
    zuege_a300bz:array[0..300] of TBewerteterZug; //Auszugebene Züge
    StartFarbeSchwarz_b:boolean; //Legt die Startfarbe fest
    StartTiefe_i,arrayindex_i:integer; //Starttiefe: Tiefe für den Baum; arrayindex:Position im Zuege array
    procedure Rekursion(const SpielFeld_xsfC:TSpielFeldC;const schwarzAmZug_b:boolean;const tiefe_i:integer;alpha_i,beta_i:integer;var bewertetesSpielFeld_xbsf:TBewertetesSpielfeld);
  public
    erreichbareFelder_ab:TBooleanFeld;
    list_xss:TStrings; //Ausgabe Liste
    fortschritt_xpb:TPaintBox; //Fortschritt anzeige
    RealTimePriority_b:boolean;
    constructor Create(const ausgabe_xss:TStrings);
    procedure StartMiMaBaum(const SpielFeld_xsfC:TSpielFeldC;const tiefe_i:integer;KIModus_b:boolean);
  end;

  TBrandubhConfig=class(tSpielConfig)
  public
    OberflaecheHelligkeit_im:smallint;
    OberflaecheZeigAlleZuege_b,OberflaecheZeigAlleErreichbareFelder_b:boolean;
    RegelnweissgewinntwennschwarzKeineFigurenMehrHat_b:boolean;
    KITiefeBeiAnzeigenDerMoeglichenZuege_i:integer;
    KITiefeBeimComputerSpiel_i:integer;
    KIHighPriority_b:boolean;
    SpielerWhiteHuman_b,SpielerBlackHuman_b:boolean;
    procedure Assign(Source: TSpielConfig);override;
    procedure ActivateStandard;override;
  end;

  TBrandubhSpielfeldRenderer=class
    protected
      pfad_s:string;
    public
      figurenbilder_xfb:TFigurenBilder;
      procedure renderSpielfeldToFeld(spielFeld:TSpielFeldC;ausgabeBox:TPaintBox;SelectedX_i,SelectedY_i,VerschiebungX_i,VerschiebungY_i,FeldSize_i,helligkeit_i:integer;zahlenAusgeben_b,ErreichbareFelderMarkieren_b:boolean;erreichbareFelder_pab:PBooleanFeld;tempFigurX,tempFigurY:integer);
      constructor create(pfad_s:string);
      destructor destroy;override;
  end;

  TZentralSpielVerwaltungBrandubh=class(TZentralSpielVerwaltung)
   protected
//    oldspielFeld:TSpielFeldC;
    SelectedX_i,SelectedY_i:integer;
    tempFigurX_i,tempFigurY_i:integer;
    tempFigurClickPosX_i,tempFigurClickPosY_i:integer;
    pfad_s:string;
    FConfig_xbc:TBrandubhConfig;
    procedure SetConfig(const value_xbc:TBrandubhConfig);
    function GetConfig():TBrandubhConfig;
   public
    BildSize_i,BildVerschiebungX_i,BildVerschiebungY_i,FeldSize_i:integer;

    renderer_xbsfr:TBrandubhSpielfeldRenderer;
    moeglicheZuege_xlb:tlistbox;
    ZugMerker_xlb:TListBox;
    ausgabeFeld_xpb:TPaintBox;
    aktiverSpieler_xsh:TShape;
    StellungsInfos_xpb:TPaintBox;
    meldungsFeld_xccp:TCCPanel;
    Berechnungsstatus_xpb:TPaintBox;
    spielFeld_xsfC:TSpielFeldC;
    spielmerker_xll:TLinkedList;
    analyser_xza:TZugAnalyser;
    constructor create(moeglicheZuege_xo,ZugMerker_xo,ausgabeFeld_xo,aktiverSpieler_xo,StellungsInfo_xo,Berechnungsstatus_xo,meldungsFeld_xo:TObject;pfad_s:string);override;
    procedure Init;override;
//    procedure render(Sender: TObject);
    procedure StellungAnalyseAnzeigen(out Stellungswert_i,WeisseFiguren_i,SchwarzeFiguren_i,Stellungswiederholung_i:integer);
    procedure PaintStellungsAnalyse(sender_xo:TObject);
    procedure UpdateSize(feld_xc:TControl);
    procedure renderTo(ausgabe_xo:TObject);override;
    procedure MoeglicherZugClick(Sender_xo: TObject);
    procedure DrawListItem(Control_xwc: TWinControl; Index_i: Integer;Rect: TRect; State_xods: TOwnerDrawState);
    function BewegeFigur(sx_i,sy_i,zx_i,zy_i:integer):boolean;
    procedure spielfeldMouseDown(Sender_xo: TObject; Button_xmb: TMouseButton;Shift: TShiftState; X_i, Y_i: Integer);
    procedure spielfeldMouseMove(Sender_xo: TObject; Shift: TShiftState; X_i,  Y_i: Integer);
    procedure spielfeldMouseUp(Sender_xo: TObject; Button_xmb: TMouseButton; Shift: TShiftState; X_i, Y_i: Integer);
    procedure SelectOldZug(Sender_xo: TObject);
    destructor destroy;override;

    property Konfiguration:TBrandubhConfig read FConfig_xbc write SetConfig;
  end;
  TSpielFeldQueuePoint=record
    SFQPx_i,SFQPy_i:integer;
    SFQPschwarz_b:boolean;
  end;
  TSpielFeldQueue=array[0..2047] of TSpielFeldQueuePoint;
function KoordinatenBuchstabeToZahl(const buchstabe_sc:char):byte; //Verwandelt eine Zahl in einen Buchstaben
function KoordinatenZahlToBuchstabe(const zahl_cb:byte):char; //Umkehrung von KoordinatenBuchstabeToZahl
function KoordinatenToString(const kx_cb,ky_cb:byte):string; //Verwandelt Arraykoordinaten in einen String
function StringToKoordinaten(const koordinaten_s:string):TPoint; //Gegenstück zu KoordinatenToString
function FigurenTypToString(const typ_xf:TFigur):String; //Verwandelt einen Figurentyp in einen String
function HabenFigurenDieGleicheFarbe(const f1_xf,f2_xf:TFigur):boolean; //Testet ob zwei Figuren die selbe Farbe haben

var
  globalqueue_asfq:TSpielFeldQueue;
implementation
uses graphics,forms;
//==============================================================================
//======================Konvertierungsfunktionen für die UI=====================
//==============================================================================
function IntToStr2(const i:integer):string;
begin
  Result:=Format('%d',[i]);
  if i>0 then
    result:='+'+result;
end;
function KoordinatenZahlToBuchstabe(const zahl_cb:byte):char;
begin
  result:=chr(zahl_cb+65);
end;
function KoordinatenBuchstabeToZahl(const buchstabe_sc:char):byte;
begin
  result:=ord(buchstabe_sc)-65;
end;
function KoordinatenToString(const kx_cb,ky_cb:byte):string;
begin
  result:=KoordinatenZahlToBuchstabe(kx_cb){+'x'}+chr(ky_cb+49);
end;
function StringToKoordinaten(const koordinaten_s:string):TPoint;
begin
  if length(koordinaten_s)<>2 then exit;
  Result.x:=KoordinatenBuchstabeToZahl(koordinaten_s[1]);
  Result.y:=ord(koordinaten_s[2])-49;
end;
function FigurenTypToString(const typ_xf:TFigur):String;
begin
  case typ_xf of
    fLeer:Result:='Keine Figur';
    fBelagerer:Result:='\Be  '; //Die entsprechenden Codes werden durch Bilder ersetzt.
    fGetreuer:Result:='\Ge  ';
    fKoenig,fKoenigThron:Result:='\Kö  ';
    fThron:Result:='Thron';
  end
end;

//==============================================================================
//==========================Spielfeldklasse TSpielFeldC=========================
//==============================================================================


procedure TSPielfeldC.Init;
var i,j:integer;
begin
  status_xs:=sSchwarzAmZug;
  for i:=0 to 6 do
    for j:=0 to 6 do begin //Ersteinmal löschen
      felder_xsf[i,j]:=fLeer;
    end;
  felder_xsf[3,3]:=fKoenig;

  felder_xsf[1,3]:=fGetreuer;
  felder_xsf[2,3]:=fGetreuer;
  felder_xsf[4,3]:=fGetreuer;
  felder_xsf[5,3]:=fGetreuer;
  felder_xsf[3,1]:=fGetreuer;
  felder_xsf[3,2]:=fGetreuer;
  felder_xsf[3,4]:=fGetreuer;
  felder_xsf[3,5]:=fGetreuer;

  //Schwarze Figuren
   //linksoben
    felder_xsf[0,1]:=fBelagerer;
    felder_xsf[0,2]:=fBelagerer;
    felder_xsf[1,0]:=fBelagerer;
    felder_xsf[2,0]:=fBelagerer;
   //rechtsoben
    felder_xsf[6,1]:=fBelagerer;
    felder_xsf[6,2]:=fBelagerer;
    felder_xsf[5,0]:=fBelagerer;
    felder_xsf[4,0]:=fBelagerer;
   //linksunten
    felder_xsf[0,5]:=fBelagerer;
    felder_xsf[0,4]:=fBelagerer;
    felder_xsf[1,6]:=fBelagerer;
    felder_xsf[2,6]:=fBelagerer;
   //rechtsunten
    felder_xsf[6,5]:=fBelagerer;
    felder_xsf[6,4]:=fBelagerer;
    felder_xsf[5,6]:=fBelagerer;
    felder_xsf[4,6]:=fBelagerer;
end;
function TSpielfeldC.Clone:TSpielFeldC;
begin
  result:=tspielfeldC.create;
  result.felder_xsf:=felder_xsf;
  result.status_xs:=status_xs;
end;
procedure TSPielfeldC.CloneOther(const feld_xsfC:TspielfeldC);
begin
  felder_xsf:=feld_xsfC.felder_xsf;
  status_xs:=feld_xsfC.status_xs;
end;
procedure TSPielfeldC.CloneOtherFast(const feld_xsfC:TspielfeldC);
begin
  felder_xsf:=feld_xsfC.felder_xsf;
end;
function HabenFigurenDieGleicheFarbe(const f1_xf,f2_xf:TFigur):boolean;
begin
  Result:=(f2_xf<>fLeer) and //F2 darf nicht leer sein
          ((f1_xf=f2_xf)        //Gleiche Figuren haben die gleiche Farbe
          or ((f1_xf<>fBelagerer) and (f2_xf<>fBelagerer))); //Sind beide weiß?
end;

procedure TSpielFeldC.GetInfos(out WeiseFiguren_i,SchwarzeFiguren_i,VonWeisErreichbarefelder_i,VonSchwarzErreichbarefelder_i:integer;const randfelderWertvoller_b:boolean);
{$BOOLEVAL OFF}
type TFeldTyp=array[0..1] of byte; //(ftWeiss,ftSchwarz,ftErreichbarFuerWeiss,ftErreichbarFuerSchwarz,ftErreichbarFuerBeide,ftLeer);
     TFeld=array[0..6,0..6] of TFeldTyp;
var x,y:integer;
    //point,point2:PFeldpoint;
    point_psfqp:^TSpielFeldQueuePoint;
    ende_i,anfang_i:integer;
    feld_f:TFeld;
begin
ende_i:=0;
anfang_i:=0;
WeiseFiguren_i:=0;
SchwarzeFiguren_i:=0;
VonWeisErreichbarefelder_i:=0;
VonSchwarzErreichbarefelder_i:=0;
for x:=0 to 6 do
  for y:=0 to 6 do  begin
    if felder_xsf[x,y]=fLeer then begin
      feld_f[x,y,0]:=0;
      feld_f[x,y,1]:=0;
      continue;
    end;

    //---Erreichbare felder_xsf---
    //Position in die Queue einfügen.
    with globalqueue_asfq[ende_i] do begin
      SFQPx_i:=x;
      SFQPy_i:=y;
      SFQPschwarz_b:=felder_xsf[x,y]=fBelagerer;
    end;
    inc(ende_i);

    //Position blockieren
    feld_f[x,y,0]:=1;
    feld_f[x,y,1]:=1;
    //Ende ~ Erreichbare felder_xsf ~ Ende

    //Materielle Vorteile
    if felder_xsf[x,y]=fBelagerer then
      SchwarzeFiguren_i:=SchwarzeFiguren_i + 1
     else
      WeiseFiguren_i:=WeiseFiguren_i+1;
  end;
//schwarz:=schwarz/2; //Schwarz wird durch 2 geteilt, weil dessen Aufgabe schwerer ist

  while (anfang_i<>ende_i) do begin
    point_psfqp:=@GlobalQueue_asfq[anfang_i];
    inc(anfang_i);
    if anfang_i>high(globalqueue_asfq) then
      anfang_i:=0;
    if (feld_f[point_psfqp^.SFQPx_i,point_psfqp^.SFQPy_i,integer(point_psfqp^.SFQPschwarz_b)]=2) then
      continue;
    feld_f[point_psfqp^.SFQPx_i,point_psfqp^.SFQPy_i,integer(point_psfqp.SFQPschwarz_b)]:=2;
    if (randfelderWertvoller_b)and((point_psfqp^.SFQPx_i<=1)or(point_psfqp^.SFQPy_i<=1)or(point_psfqp^.SFQPx_i>=5)or(point_psfqp^.SFQPy_i>=5)) then begin
      if point_psfqp^.SFQPschwarz_b then
        VonSchwarzErreichbarefelder_i:=VonSchwarzErreichbarefelder_i+2
       else
        VonWeisErreichbarefelder_i:=VonWeisErreichbarefelder_i+2;
    end else begin
      if point_psfqp^.SFQPschwarz_b then
        VonSchwarzErreichbarefelder_i:=VonSchwarzErreichbarefelder_i+1
       else
        VonWeisErreichbarefelder_i:=VonWeisErreichbarefelder_i+1;
    end;

    if (point_psfqp^.SFQPx_i>0) and  (feld_f[point_psfqp^.SFQPx_i-1,point_psfqp^.SFQPy_i,integer(point_psfqp^.SFQPschwarz_b)]=0) then begin
      with globalqueue_asfq[ende_i] do begin
        SFQPx_i:=point_psfqp^.SFQPx_i-1;
        SFQPy_i:=point_psfqp^.SFQPy_i;
        SFQPschwarz_b:=point_psfqp^.SFQPschwarz_b;
      end;
      inc(ende_i);
      if ende_i>high(globalqueue_asfq) then
        ende_i:=0;
      feld_f[point_psfqp^.SFQPx_i-1,point_psfqp^.SFQPy_i,integer(point_psfqp^.SFQPschwarz_b)]:=1;
    end;
    if (point_psfqp^.SFQPx_i<6) and (feld_f[point_psfqp^.SFQPx_i+1,point_psfqp^.SFQPy_i,integer(point_psfqp^.SFQPschwarz_b)]=0) then begin
      with globalqueue_asfq[ende_i] do begin
        SFQPx_i:=point_psfqp^.SFQPx_i+1;
        SFQPy_i:=point_psfqp^.SFQPy_i;
        SFQPschwarz_b:=point_psfqp^.SFQPschwarz_b;
      end;
      inc(ende_i);
      if ende_i>high(globalqueue_asfq) then
        ende_i:=0;
      feld_f[point_psfqp^.SFQPx_i+1,point_psfqp^.SFQPy_i,integer(point_psfqp^.SFQPschwarz_b)]:=1;
    end;
    if (point_psfqp^.SFQPy_i>0) and (feld_f[point_psfqp^.SFQPx_i,point_psfqp^.SFQPy_i-1,integer(point_psfqp^.SFQPschwarz_b)]=0) then begin
      with globalqueue_asfq[ende_i] do begin
        SFQPx_i:=point_psfqp^.SFQPx_i;
        SFQPy_i:=point_psfqp^.SFQPy_i-1;
        SFQPschwarz_b:=point_psfqp^.SFQPschwarz_b;
      end;
      inc(ende_i);
      if ende_i>high(globalqueue_asfq) then
        ende_i:=0;
      feld_f[point_psfqp^.SFQPx_i,point_psfqp^.SFQPy_i-1,integer(point_psfqp^.SFQPschwarz_b)]:=1;
    end;
    if (point_psfqp^.SFQPy_i <6) and (feld_f[point_psfqp^.SFQPx_i,point_psfqp^.SFQPy_i+1,integer(point_psfqp^.SFQPschwarz_b)]=0) then begin
      with globalqueue_asfq[ende_i] do begin
        SFQPx_i:=point_psfqp^.SFQPx_i;
        SFQPy_i:=point_psfqp^.SFQPy_i+1;
        SFQPschwarz_b:=point_psfqp^.SFQPschwarz_b;
      end;
      inc(ende_i);
      if ende_i>high(globalqueue_asfq) then
        ende_i:=0;
      feld_f[point_psfqp^.SFQPx_i,point_psfqp^.SFQPy_i+1,integer(point_psfqp^.SFQPschwarz_b)]:=1;
    end;
  end;
end;

procedure TSpielFeldC.Stellungsanalyse(out result_i:integer);
var weiseFiguren_i,schwarzeFiguren_i,VonWeisErreichbarefelder_i,VonSchwarzErreichbarefelder_i:integer;
begin
  GetInfos(weiseFiguren_i,schwarzeFiguren_i,VonWeisErreichbarefelder_i,VonSchwarzErreichbarefelder_i,true);
  result_i:=(weiseFiguren_i *3 + VonWeisErreichbarefelder_i) - (schwarzeFiguren_i *3 +VonSchwarzErreichbarefelder_i)+48{+48 zur eichung auf 0};
  case status_xs of
    sWeisGewann: result_i:=result_i + 500;
    sSchwarzGewann: result_i:=result_i - 500;
  end;
end;
function TSpielFeldC.Stellungsanalyse_f():integer;
begin
  Stellungsanalyse(result);
end;
function TSpielFeldC.CanFigureFahren(const sx_i,sy_i,zx_i,zy_i:integer):boolean;
var i:integer;
begin
result:=false;
if (sx_i<0)or(sx_i>6)or(sy_i<0)or(sy_i>6) then
  raise EZugError.create('Startfeld außerhalb des Spielfeldes');
if (zx_i<0)or(zx_i>6)or(zy_i<0)or(zy_i>6) then
  raise EZugError.create('Zielfeld außerhalb des Spielfeldes');

if (felder_xsf[sx_i,sy_i]=fLeer) then
  raise EZugError.create('Startfeld ist leer');
if (felder_xsf[zx_i,zy_i]<>fLeer) then
  raise EZugError.create('Zielfeld ist belegt');

if (sx_i<>zx_i)and(sy_i<>zy_i) then
  raise EZugError.create('Diagonal fahren nicht erlaubt');

if (felder_xsf[sx_i,sy_i]<>fKoenig)and(zx_i=3)and(zy_i=3)  then
  raise EZugError.create('Das Thronfeld kann nur vom König betreten werden');

for i:=min(sx_i,zx_i) to max(sx_i,zx_i) do
  if (felder_xsf[i,sy_i]<>fLeer)and(i<>sx_i) then
    raise EZugError.create('Zielfeld nicht vom Startfeld aus erreichbar');
for i:=min(sy_i,zy_i) to max(sy_i,zy_i) do
  if (felder_xsf[sx_i,i]<>fLeer) and (i<>sy_i) then
    raise EZugError.create('Zielfeld nicht vom Startfeld aus erreichbar');

if (felder_xsf[sx_i,sy_i]=fBelagerer) and (status_xs=sWeisAmZug) then
  raise EZugError.create('Keine weiße Figur');
if (felder_xsf[sx_i,sy_i]<>fBelagerer) and (status_xs=sSchwarzAmZug) then
  raise EZugError.create('Keine schwarze Figur');
if (status_xs in [sWeisGewann,sSchwarzGewann,sUnentschieden]) then
  raise EZugError.create('Spiel ist schon vorbei');
result:=true;
end;
//Bewegt eine Figur von sx|sy zu zx|zy und testet auf Kollision
procedure TSpielFeldC.BewegeFigur(const sx_i,sy_i,zx_i,zy_i:integer);
var KoenigBedroht:TPoint;
    figur:TFigur;
    i:integer;
begin
  //if (status_xs<>sWeisAmZug) and (status_xs<>sSchwarzAmZug) then exit;
  figur:=felder_xsf[sx_i,sy_i];
  felder_xsf[zx_i,zy_i]:=figur;
  felder_xsf[sx_i,sy_i]:=fLeer;
  KoenigBedroht:=point(-1,-1);
  if figur = fkoenig then
    if (zx_i=0)or(zx_i=6)or(zy_i=0)or(zy_i=6) then
      status_xs:=sWeisGewann;
  if (zx_i<5) then begin
     case felder_xsf[zx_i+1,zy_i] of
       fkoenig:
         if figur=fbelagerer then
           KoenigBedroht:=point(zx_i+1,zy_i);// Bedrohten König später betrachten
       fBelagerer,fGetreuer:
         if HabenFigurenDieGleicheFarbe(figur,felder_xsf[zx_i+2,zy_i])
           and not HabenFigurenDieGleicheFarbe(figur,felder_xsf[zx_i+1,zy_i]) then begin
             felder_xsf[zx_i+1,zy_i]:=fLeer;
           end;
     end;
  end;
  if (zx_i>1) then begin
     case felder_xsf[zx_i-1,zy_i] of
       fkoenig:
         if figur=fbelagerer then
           KoenigBedroht:=point(zx_i-1,zy_i);// Bedrohten König später betrachten;
       fBelagerer,fGetreuer:
         if HabenFigurenDieGleicheFarbe(figur,felder_xsf[zx_i-2,zy_i])
           and not HabenFigurenDieGleicheFarbe(figur,felder_xsf[zx_i-1,zy_i]) then begin
             felder_xsf[zx_i-1,zy_i]:=fLeer;
           end;
     end;
  end;
  if (zy_i<5) then begin
     case felder_xsf[zx_i,zy_i+1] of
       fkoenig:
         if figur=fbelagerer then
           KoenigBedroht:=point(zx_i,zy_i+1);// Bedrohten König später betrachten;
       fBelagerer,fGetreuer:
         if HabenFigurenDieGleicheFarbe(figur,felder_xsf[zx_i,zy_i+2])
           and not HabenFigurenDieGleicheFarbe(figur,felder_xsf[zx_i,zy_i+1]) then begin
             felder_xsf[zx_i,zy_i+1]:=fLeer;
           end;
     end;
  end;
  if (zy_i>1) then begin
     case felder_xsf[zx_i,zy_i-1] of
       fkoenig:
         if figur=fbelagerer then
           KoenigBedroht:=point(zx_i,zy_i-1);// Bedrohten König später betrachten;
       fBelagerer,fGetreuer:
         if HabenFigurenDieGleicheFarbe(figur,felder_xsf[zx_i,zy_i-2])
           and not HabenFigurenDieGleicheFarbe(figur,felder_xsf[zx_i,zy_i-1]) then begin
             felder_xsf[zx_i,zy_i-1]:=fLeer;
           end;
     end;
  end;
  if (KoenigBedroht.x<>-1)and(KoenigBedroht.y<>-1) //Wenn eine schwarze Figur neben den König steht und
        then begin //werden die umgebenden Figuren gezählt
          i:=0;
          if (KoenigBedroht.x>0)and(felder_xsf[KoenigBedroht.x-1,KoenigBedroht.y]=fbelagerer) then inc(i);
          if (KoenigBedroht.x<7)and(felder_xsf[KoenigBedroht.x+1,KoenigBedroht.y]=fbelagerer) then inc(i);
          if (KoenigBedroht.y>0)and(felder_xsf[KoenigBedroht.x,KoenigBedroht.y-1]=fbelagerer) then inc(i);
          if (KoenigBedroht.y<7)and(felder_xsf[KoenigBedroht.x,KoenigBedroht.y+1]=fbelagerer) then inc(i);
          if (((KoenigBedroht.x=2)or(KoenigBedroht.x=4))and(KoenigBedroht.y=3)) or (((KoenigBedroht.y=2)or(KoenigBedroht.y=4))and(KoenigBedroht.x=3)) then inc(i);
          if i>=4 then begin //Wenn der König von mindestens 4 Gegnern (der Thron zählt als Gegner) umgeben ist:
            felder_xsf[KoenigBedroht.x,KoenigBedroht.y]:=fLeer;
            status_xs:=sSchwarzGewann;
          end;
        end;

  if status_xs=sSchwarzAmZug then
    status_xs:=sWeisAmZug
   else if status_xs=sWeisAmZug then
    status_xs:=sSchwarzAmZug;
end;

function TSpielFeldC.isEquals(const feld_xsfC:TSpielFeldC):boolean;
var x,y:integer;
begin
  result:=status_xs=feld_xsfC.status_xs;
  for x:=0 to 6 do
    for y:=0 to 6 do
      result:=result and (felder_xsf[x,y]=feld_xsfC.felder_xsf[x,y]);
end;

//==============================================================================
//==========================MiMaBaumKlasse TZugAnalyser=========================
//==============================================================================

constructor TZugAnalyser.Create(const ausgabe_xss:TStrings);
begin
  list_xss:=ausgabe_xss;
  fortschritt_xpb:=nil;
end;

procedure TZugAnalyser.Rekursion(const SpielFeld_xsfC:TSpielFeldC;const schwarzAmZug_b:boolean;const tiefe_i:integer;alpha_i,beta_i:integer;var bewertetesSpielFeld_xbsf:TBewertetesSpielfeld);
var x_i,y_i,x2_i,y2_i:integer;
    tempspielfeld_xsfC:TSpielFeldC;
    temp_xbsf:TBewertetesSpielfeld;
begin
  if GetAsyncKeyState(VK_ESCAPE)<>0 then begin
    if StartTiefe_i=tiefe_i then
      fortschritt_xpb.Refresh;
    exit;
  end;
  if GetAsyncKeyState(VK_LBUTTON)or GetAsyncKeyState(VK_RBUTTON)<>0 then begin
    fortschritt_xpb.canvas.brush.color:=fortschritt_xpb.Parent.Brush.Color;
    fortschritt_xpb.Canvas.TextOut(70+StartTiefe_i*111-333,3,'Um die Berechnung abbzubrechen, ESC drücken und halten');
    fortschritt_xpb.canvas.brush.color:=clBlue;
  end;
  if schwarzAmZug_b then
    bewertetesSpielFeld_xbsf.wert_i:=1000000
  else
    bewertetesSpielFeld_xbsf.wert_i:=-1000000;
  tempspielfeld_xsfC:=TSpielFeldC.create;
  tempspielfeld_xsfC.felder_xsf:=SpielFeld_xsfC.felder_xsf;
  if tiefe_i>3 then begin
    with fortschritt_xpb.Canvas do begin
      brush.color:=clWhite;
      Rectangle(70+(StartTiefe_i-tiefe_i)*111,3,70+98+(StartTiefe_i-tiefe_i)*111,15);
      brush.color:=clBlue;
    end;
  end;

  for x_i:=0 to 6  do
    for y_i:=0 to 6 do begin
      if (SpielFeld_xsfC.felder_xsf[x_i,y_i]=fLeer)or((SpielFeld_xsfC.felder_xsf[x_i,y_i]<>fBelagerer)and(schwarzAmZug_b))or((SpielFeld_xsfC.felder_xsf[x_i,y_i]=fBelagerer)and(not schwarzAmZug_b)) then continue;
      if tiefe_i>3 then
        fortschritt_xpb.Canvas.Rectangle(70+(StartTiefe_i-tiefe_i)*111,3,70+((x_i*7+y_i)) shl 1+(StartTiefe_i-tiefe_i)*111 ,15);
      y2_i:=y_i;
      for x2_i:=x_i+1 to 6 do
        {$include ziehen.pas}
      for x2_i:=x_i-1 downto 0 do
        {$include ziehen.pas}

      x2_i:=x_i;
      for y2_i:=y_i+1 to 6 do
        {$include ziehen.pas}
      for y2_i:=y_i-1 downto 0 do
        {$include ziehen.pas}
    end;
  tempspielfeld_xsfC.Free;
end;

procedure TZugAnalyser.StartMiMaBaum(const SpielFeld_xsfC:TSpielFeldC;const tiefe_i:integer;KIModus_b:boolean);

var 
    i,j,k:integer;
    origWeiseFiguren_i,origSchwarzeFiguren_i,origErreichbarefelderWeis_i,origErreichbarefelderSchwarz_i,WeiseFiguren_i,SchwarzeFiguren_i,ErreichbarefelderWeis_i,ErreichbarefelderSchwarz_i:integer;
    tempzug_xbz:TBewerteterZug;
    tempspielfeld_xsfC:TSpielFeldC;
    ausgabe_s:string;
    tempbewertetesSpielFeld_xbsf:TBewertetesSpielfeld;
begin
  if RealTimePriority_b then begin
    SetPriorityClass(GetCurrentProcess,REALTIME_PRIORITY_CLASS);
    SetThreadPriority(MainThreadID,THREAD_PRIORITY_TIME_CRITICAL);
  end;
  try
    GetAsyncKeyState(VK_ESCAPE);
    GetAsyncKeyState(VK_LBUTTON);
    GetAsyncKeyState(VK_RBUTTON); 
    self.KIModus_b:=KIModus_b; //Kimodus merken
    tempspielfeld_xsfC:=TSpielFeldC.create;
    tempbewertetesSpielFeld_xbsf.Spielfeld_xsfC:=TSpielFeldC.create;
    StartFarbeSchwarz_b:=SpielFeld_xsfC.status_xs=sSchwarzAmZug;
    StartTiefe_i:=tiefe_i;
    list_xss.Clear;
    arrayindex_i:=0;
    for i:=0 to 6 do for j:=0 to 6 do//Markiert die felder_xsf mit einer Figur von der richtigen Farbe
      erreichbarefelder_ab[i,j]:=(SpielFeld_xsfC.felder_xsf[i,j]<>fLeer) and
                                 ((SpielFeld_xsfC.status_xs=sSchwarzAmZug) xor (SpielFeld_xsfC.felder_xsf[i,j]<>fBelagerer));
    if SpielFeld_xsfC.status_xs=sSchwarzAmZug then begin
      tempbewertetesSpielFeld_xbsf.wert_i:=1000000;
      tempbewertetesSpielFeld_xbsf.Spielfeld_xsfC.status_xs:=sSchwarzAmZug
    end else begin
      tempbewertetesSpielFeld_xbsf.wert_i:=-1000000;
      tempbewertetesSpielFeld_xbsf.Spielfeld_xsfC.status_xs:=sWeisAmZug
    end;
    fortschritt_xpb.Canvas.TextOut(5,2,'Bitte warten: ');
    Rekursion(SpielFeld_xsfC,SpielFeld_xsfC.status_xs=sSchwarzAmZug,tiefe_i,-10000000,10000000,tempbewertetesSpielFeld_xbsf);
    if GetAsyncKeyState(VK_ESCAPE)<>0 then begin
      list_xss.clear;
      list_xss.add('Abgebrochen');
      abort; //In die finally-Clauses springen
    end;
    SpielFeld_xsfC.GetInfos(origWeiseFiguren_i,origSchwarzeFiguren_i,origErreichbarefelderWeis_i,origErreichbarefelderSchwarz_i,false);
    for i:=0 to arrayindex_i-1 do begin
      k:=i;
      for j:=i+1 to arrayindex_i-1 do //Sortierung nach Selectionsort
        if ((not (SpielFeld_xsfC.status_xs=sSchwarzAmZug))and(zuege_a300bz[j].wert_i>zuege_a300bz[k].wert_i)) or
              ((SpielFeld_xsfC.status_xs=sSchwarzAmZug)and(zuege_a300bz[j].wert_i<zuege_a300bz[k].wert_i)) then k:=j;
      tempzug_xbz:=zuege_a300bz[k];
      zuege_a300bz[k]:=zuege_a300bz[i];
      zuege_a300bz[i]:=tempzug_xbz;

      ausgabe_s:=KoordinatenToString(zuege_a300bz[i].startfeld_xp.x,zuege_a300bz[i].startfeld_xp.y)+'->'+KoordinatenToString(zuege_a300bz[i].zielfeld_xp.x,zuege_a300bz[i].zielfeld_xp.y); //Zugausgeben

      tempspielfeld_xsfC.CloneOtherFast(SpielFeld_xsfC);
      tempspielfeld_xsfC.bewegefigur(zuege_a300bz[i].startfeld_xp.x,zuege_a300bz[i].startfeld_xp.y,zuege_a300bz[i].zielfeld_xp.x,zuege_a300bz[i].zielfeld_xp.y);
      tempspielfeld_xsfC.GetInfos(WeiseFiguren_i,SchwarzeFiguren_i,ErreichbarefelderWeis_i,ErreichbarefelderSchwarz_i,false);
      ausgabe_s:=ausgabe_s+'('+FloatToStr(tempspielfeld_xsfC.Stellungsanalyse_f())+') ' ; //Zukünftige Bewertung ausgeben


      if (origWeiseFiguren_i>WeiseFiguren_i)or(origSchwarzeFiguren_i>SchwarzeFiguren_i) then begin
        if origWeiseFiguren_i>WeiseFiguren_i then
          ausgabe_s:=ausgabe_s+IntToStr2(WeiseFiguren_i-origWeiseFiguren_i)+' \Ge    ';
        if origSchwarzeFiguren_i>SchwarzeFiguren_i then
          ausgabe_s:=ausgabe_s+IntToStr2(SchwarzeFiguren_i-origSchwarzeFiguren_i)+' \Be    ';
      end;
      if origErreichbarefelderWeis_i>ErreichbarefelderWeis_i then begin
        if origErreichbarefelderWeis_i-ErreichbarefelderWeis_i=1 then
          ausgabe_s:=ausgabe_s+ ' 1 Feld weniger für  \W    erreichbar; '
         else
          ausgabe_s:=ausgabe_s+ ' '+IntToStr2(origErreichbarefelderWeis_i-ErreichbarefelderWeis_i)+' Felder weniger für  \W    erreichbar;'
      end else if origErreichbarefelderWeis_i<ErreichbarefelderWeis_i then begin
        if ErreichbarefelderWeis_i-origErreichbarefelderWeis_i=1 then
          ausgabe_s:=ausgabe_s+ ' 1 Feld mehr für  \W    erreichbar;'
         else
          ausgabe_s:=ausgabe_s+ ' '+IntToStr2(ErreichbarefelderWeis_i-origErreichbarefelderWeis_i)+' Felder mehr für  \W    erreichbar;'
      end;
      if origErreichbarefelderSchwarz_i>ErreichbarefelderSchwarz_i then begin
        if origErreichbarefelderSchwarz_i-ErreichbarefelderSchwarz_i=1 then
          ausgabe_s:=ausgabe_s+ ' 1 Feld weniger für  \S    erreichbar;'
         else
          ausgabe_s:=ausgabe_s+ ' '+IntToStr2(origErreichbarefelderSchwarz_i-ErreichbarefelderSchwarz_i)+' Felder weniger für  \S    erreichbar;'
      end else if origErreichbarefelderSchwarz_i<ErreichbarefelderSchwarz_i then begin
        if ErreichbarefelderSchwarz_i-origErreichbarefelderSchwarz_i=1 then
          ausgabe_s:=ausgabe_s+ ' 1 Feld mehr für  \S    erreichbar;'
         else
          ausgabe_s:=ausgabe_s+ ' '+IntToStr2(ErreichbarefelderSchwarz_i-origErreichbarefelderSchwarz_i)+' Felder mehr für  \S    erreichbar;'
      end;
      tempspielfeld_xsfC.felder_xsf:=zuege_a300bz[i].spielfeld_xp;
      tempspielfeld_xsfC.GetInfos(WeiseFiguren_i,SchwarzeFiguren_i,ErreichbarefelderWeis_i,ErreichbarefelderSchwarz_i,false);
      if origErreichbarefelderWeis_i>ErreichbarefelderWeis_i then begin
        if origErreichbarefelderWeis_i-ErreichbarefelderWeis_i=1 then
          ausgabe_s:=ausgabe_s+ ' 1 Feld weniger für  \W    erreichbar; '
         else
          ausgabe_s:=ausgabe_s+ ' '+IntToStr2(origErreichbarefelderWeis_i-ErreichbarefelderWeis_i)+' Felder weniger für  \W    erreichbar;'
      end else if origErreichbarefelderWeis_i<ErreichbarefelderWeis_i then begin
        if ErreichbarefelderWeis_i-origErreichbarefelderWeis_i=1 then
          ausgabe_s:=ausgabe_s+ ' 1 Feld mehr für  \W    erreichbar;'
         else
          ausgabe_s:=ausgabe_s+ ' '+IntToStr2(ErreichbarefelderWeis_i-origErreichbarefelderWeis_i)+' Felder mehr für  \W    erreichbar;'
      end;
      if origErreichbarefelderSchwarz_i>ErreichbarefelderSchwarz_i then begin
        if origErreichbarefelderSchwarz_i-ErreichbarefelderSchwarz_i=1 then
          ausgabe_s:=ausgabe_s+ ' 1 Feld weniger für  \S    erreichbar;'
         else
          ausgabe_s:=ausgabe_s+ ' '+IntToStr2(origErreichbarefelderSchwarz_i-ErreichbarefelderSchwarz_i)+' Felder weniger für  \S    erreichbar;'
      end else if origErreichbarefelderSchwarz_i<ErreichbarefelderSchwarz_i then begin
        if ErreichbarefelderSchwarz_i-origErreichbarefelderSchwarz_i=1 then
          ausgabe_s:=ausgabe_s+ ' 1 Feld mehr für  \S    erreichbar;'
         else
          ausgabe_s:=ausgabe_s+ ' '+IntToStr2(ErreichbarefelderSchwarz_i-origErreichbarefelderSchwarz_i)+' Felder mehr für  \S    erreichbar;'
      end;
      ausgabe_s:=ausgabe_s+' Später: ('+FloatToStr(zuege_a300bz[i].wert_i)+') ' ; //Zukünftige Bewertung ausgeben
      if zuege_a300bz[i].wert_i>350 then
        ausgabe_s:=ausgabe_s+'Weis gewinnt'
       else if zuege_a300bz[i].wert_i<-350 then
        ausgabe_s:=ausgabe_s+'Schwarz gewinnt';
      if (origWeiseFiguren_i>WeiseFiguren_i)or(origSchwarzeFiguren_i>SchwarzeFiguren_i) then begin
        if origWeiseFiguren_i>WeiseFiguren_i then
          ausgabe_s:=ausgabe_s+IntToStr2(WeiseFiguren_i-origWeiseFiguren_i)+' \Ge    ';
        if origSchwarzeFiguren_i>SchwarzeFiguren_i then
          ausgabe_s:=ausgabe_s+IntToStr2(SchwarzeFiguren_i-origSchwarzeFiguren_i)+' \Be    ';
      end;
      list_xss.Add(ausgabe_s);
    end;

    tempspielfeld_xsfC.free;
    fortschritt_xpb.Refresh;
  finally
    if RealTimePriority_b then begin
      SetPriorityClass(GetCurrentProcess,NORMAL_PRIORITY_CLASS);
      SetThreadPriority(MainThreadID,THREAD_PRIORITY_NORMAL);
    end;
  end;
end;




//==============================================================================
//======================= TBrandubhSpielfeldRenderer ===========================
//==============================================================================
procedure TBrandubhSpielfeldRenderer.renderSpielfeldToFeld(spielFeld:TSpielFeldC;ausgabeBox:TPaintBox;SelectedX_i,SelectedY_i,VerschiebungX_i,VerschiebungY_i,FeldSize_i,helligkeit_i:integer;zahlenAusgeben_b,ErreichbarefelderMarkieren_b:boolean;erreichbarefelder_pab:PBooleanFeld;tempFigurX,tempFigurY:integer);
var x,y:integer;
    FormBgColor_xc,BrettBgColor_xc,ErreichbaresFeld_xc:TColor;
begin
if (ausgabeBox = nil) then exit;
FormBgColor_xc:=SetHelligkeit( $00004080,helligkeit_i-254);
BrettBgColor_xc:=SetHelligkeit( $00054585,helligkeit_i-254);
ErreichbaresFeld_xc:=SetHelligkeit($0000FA00,helligkeit_i-254);
with ausgabeBox.Canvas do begin
  brush.Color:=FormBgColor_xc;
 // Font.Color:=(ausgabeBox.Parent as TWinControl).font.color;
  pen.Width:=1;
  Pen.Style:=psClear;
  Rectangle(0,0,ausgabeBox.Width,VerschiebungY_i+16);
  Rectangle(0,0,VerschiebungX_i+16,ausgabeBox.Height);
  Rectangle(ausgabeBox.Width-VerschiebungX_i-1,0,ausgabeBox.Width+1,ausgabeBox.Height+1);
  Rectangle(0,ausgabeBox.Height-VerschiebungY_i-1,ausgabeBox.Width+1,ausgabeBox.Height+1);
  pen.color:=font.color;
  pen.Style:=psSolid;
end;
for x:=0 to 6 do begin
  //Buchstaben vertikal:unten
  if zahlenAusgeben_b then begin
    ausgabeBox.Canvas.brush.color:=FormBgColor_xc;
    ausgabeBox.Canvas.TextOut(x*FeldSize_i+VerschiebungX_i+FeldSize_i div 2+10,2+VerschiebungY_i, {IntToStr(x+1)}KoordinatenZahlToBuchstabe(x));
  end;
  for y:=0 to 6 do begin
    if (x=0)and (zahlenAusgeben_b) then begin
      ausgabeBox.Canvas.brush.color:=FormBgColor_xc;
      ausgabeBox.Canvas.TextOut(2+VerschiebungX_i,y*FeldSize_i+FeldSize_i div 2+10+VerschiebungY_i,IntToStr(y+1));
    end;
    ausgabeBox.Canvas.brush.Color:=BrettBgColor_xc;
    ausgabeBox.Canvas.Rectangle(x*FeldSize_i+15+VerschiebungX_i,y*FeldSize_i+15+VerschiebungY_i,x*FeldSize_i+FeldSize_i+15+VerschiebungX_i,y*FeldSize_i+FeldSize_i+15+VerschiebungY_i);
    if (ErreichbarefelderMarkieren_b) then
      if (erreichbarefelder_pab^[x,y]) then begin
        ausgabeBox.Canvas.brush.Style:=bsFDiagonal;
        ausgabeBox.Canvas.brush.Color:=ErreichbaresFeld_xc;
        ausgabeBox.Canvas.Rectangle(x*FeldSize_i+15+VerschiebungX_i,y*FeldSize_i+15+VerschiebungY_i,x*FeldSize_i+FeldSize_i+15+VerschiebungX_i,y*FeldSize_i+FeldSize_i+15+VerschiebungY_i);
        ausgabeBox.Canvas.brush.Style:=bsSolid;
      end;
    //Das Thronfeld extra zeichnen
    if (x=3)and(y=3) then begin
      if spielfeld.felder_xsf[x,y]=fkoenig then
        figurenbilder_xfb.DrawToCanvasEx(fKoenigThron,ausgabeBox.canvas,x*FeldSize_i+VerschiebungX_i+15,y*FeldSize_i+VerschiebungY_i+15,FeldSize_i,FeldSize_i,helligkeit_i-254)
       else
        figurenbilder_xfb.DrawToCanvasEx(fThron,ausgabeBox.canvas,x*FeldSize_i+VerschiebungX_i+15,y*FeldSize_i+VerschiebungY_i+15,FeldSize_i,FeldSize_i,helligkeit_i-254);
    end else
      figurenbilder_xfb.DrawToCanvasEx(spielfeld.felder_xsf[x,y],ausgabeBox.canvas,x*FeldSize_i+VerschiebungX_i+15,y*FeldSize_i+VerschiebungY_i+15,FeldSize_i,FeldSize_i,helligkeit_i-254);
  end;
end;
if tempFigurX<>-1 then begin
  figurenbilder_xfb.DrawToCanvasEx(spielfeld.felder_xsf[SelectedX_i,SelectedY_i],ausgabeBox.canvas,tempFigurX,tempFigurY,FeldSize_i,FeldSize_i,helligkeit_i-254);
end;
if SelectedX_i<>-1 then 
  with ausgabeBox.Canvas do begin
    pen.color:=SetHelligkeit(clBlue,helligkeit_i-200);
    pen.Width:=3;
    x:=SelectedX_i*FeldSize_i+15+VerschiebungX_i;
    y:=SelectedY_i*FeldSize_i+15+VerschiebungY_i;
    MoveTo(x+FeldSize_i div 3,y+FeldSize_i div 16);
    LineTo(x+FeldSize_i div 16,y+FeldSize_i div 16);
    LineTo(x+FeldSize_i div 16,y+FeldSize_i-FeldSize_i div 16);
    LineTo(x+FeldSize_i div 3,y+FeldSize_i-FeldSize_i div 16);

    MoveTo(x+FeldSize_i-FeldSize_i div 3,y+FeldSize_i div 16);
    LineTo(x+FeldSize_i-FeldSize_i div 16,y+FeldSize_i div 16);
    LineTo(x+FeldSize_i-FeldSize_i div 16,y+FeldSize_i-FeldSize_i div 16);
    LineTo(x+FeldSize_i-FeldSize_i div 3,y+FeldSize_i-FeldSize_i div 16);
  end;

end;
constructor TBrandubhSpielfeldRenderer.create(pfad_s:string);
begin
  self.pfad_s:=pfad_s;
  figurenbilder_xfb:=TFigurenBilder.create(pfad_s+'images\');
end;
destructor TBrandubhSpielfeldRenderer.destroy;
begin
  figurenbilder_xfb.free;
end;

//==============================================================================
//============================ TBrandubhConfig =================================
//==============================================================================
procedure TBrandubhConfig.Assign(Source: TSpielConfig);
begin
  OberflaecheHelligkeit_im:=(Source as TBrandubhConfig).OberflaecheHelligkeit_im;
  OberflaecheZeigAlleZuege_b:=TBrandubhConfig(Source).OberflaecheZeigAlleZuege_b;
  RegelnweissgewinntwennschwarzKeineFigurenMehrHat_b:=TBrandubhConfig(Source).RegelnweissgewinntwennschwarzKeineFigurenMehrHat_b;
  KITiefeBeiAnzeigenDerMoeglichenZuege_i:=TBrandubhConfig(Source).KITiefeBeiAnzeigenDerMoeglichenZuege_i;
  KITiefeBeimComputerSpiel_i:=TBrandubhConfig(Source).KITiefeBeimComputerSpiel_i;
  KIHighPriority_b:=TBrandubhConfig(Source).KIHighPriority_b;
  SpielerWhiteHuman_b:=TBrandubhConfig(Source).SpielerWhiteHuman_b;
  SpielerBlackHuman_b:=TBrandubhConfig(Source).SpielerBlackHuman_b;
  OberflaecheZeigAlleErreichbarefelder_b:=TBrandubhConfig(Source).OberflaecheZeigAlleErreichbarefelder_b;
end;
procedure TBrandubhConfig.ActivateStandard;
begin
  OberflaecheHelligkeit_im:=277;
  OberflaecheZeigAlleZuege_b:=true;
  RegelnweissgewinntwennschwarzKeineFigurenMehrHat_b:=true;
  KITiefeBeiAnzeigenDerMoeglichenZuege_i:=4;
  KITiefeBeimComputerSpiel_i:=5;
  KIHighPriority_b:=false;
  SpielerWhiteHuman_b:=true;
  SpielerBlackHuman_b:=true;
  OberflaecheZeigAlleErreichbarefelder_b:=false;
end;

//==============================================================================
//========================== TZentralSpielVerwaltungBrandubh ===================
//==============================================================================
procedure TZentralSpielVerwaltungBrandubh.SetConfig(const value_xbc:TBrandubhConfig);
begin
  FConfig_xbc.Assign(value_xbc);
end;
function TZentralSpielVerwaltungBrandubh.GetConfig():TBrandubhConfig;
begin
  Result:=FConfig_xbc;
end;
constructor TZentralSpielVerwaltungBrandubh.create(moeglicheZuege_xo,ZugMerker_xo,ausgabeFeld_xo,aktiverSpieler_xo,StellungsInfo_xo,Berechnungsstatus_xo,meldungsFeld_xo:TObject;pfad_s:string);
begin
  Self.moeglicheZuege_xlb:=moeglicheZuege_xo as TListBox;
  Self.ZugMerker_xlb:=ZugMerker_xo as TListBox;
  Self.ausgabeFeld_xpb:=ausgabeFeld_xo as TPaintBox;
  self.aktiverSpieler_xsh:=aktiverSpieler_xo as TShape;
  self.StellungsInfos_xpb:=StellungsInfo_xo as TPaintBox;
  self.Berechnungsstatus_xpb:=Berechnungsstatus_xo as TPaintBox;
  self.meldungsFeld_xccp:=meldungsFeld_xo as TCCPanel;
  self.pfad_s:=pfad_s;

  tempFigurX_i:=-1;

  self.moeglicheZuege_xlb.OnClick:=MoeglicherZugClick;
  Self.moeglicheZuege_xlb.OnDrawItem:=DrawListItem;
  Self.ZugMerker_xlb.OnDrawItem:=DrawListItem;
  Self.ZugMerker_xlb.OnClick:=SelectOldZug;
  self.ausgabeFeld_xpb.OnPaint:=renderTo;
  self.ausgabeFeld_xpb.OnMouseDown:=spielfeldMouseDown;
  self.ausgabeFeld_xpb.OnMouseMove:=spielfeldMouseMove;
  self.ausgabeFeld_xpb.OnMouseUp:=spielfeldMouseUp;
  self.StellungsInfos_xpb.OnPaint:=PaintStellungsAnalyse;

  renderer_xbsfr:=TBrandubhSpielfeldRenderer.create(pfad_s);
  spielFeld_xsfC:=TSpielFeldC.create;
  FConfig_xbc:=TBrandubhConfig.create;
  spielmerker_xll:=TLinkedList.create;
  analyser_xza:=TZugAnalyser.create(self.moeglicheZuege_xlb.items);
  analyser_xza.fortschritt_xpb:=self.Berechnungsstatus_xpb;

end;
procedure TZentralSpielVerwaltungBrandubh.Init;
var temp:TSpielFeldC;
    llElement:TLLElement;
    start,ziel:TPoint;
begin
  meldungsFeld_xccp.caption:='';
  meldungsFeld_xccp.hint:='';
  aktiverSpieler_xsh.Brush.Color:=SetHelligkeit($00101010{clGray},Konfiguration.OberflaecheHelligkeit_im-254);
  spielFeld_xsfC.init;
  llElement:=spielmerker_xll.start;
  while (llElement<>nil) do begin
    TSpielFeldC(llElement.wert).free;
    llElement:=llElement.next;
  end;
  spielmerker_xll.start:=nil;
  spielmerker_xll.ende:=nil;
  temp:=TSpielFeldC.create;
  temp.CloneOther(spielFeld_xsfC);
  spielmerker_xll.add(temp);
  {$INCLUDE Computerspieler.pas}
end;

procedure TZentralSpielVerwaltungBrandubh.StellungAnalyseAnzeigen(out Stellungswert_i,WeisseFiguren_i,SchwarzeFiguren_i,Stellungswiederholung_i:integer);
var erreichbareFelderWeis_i,erreichbareSchwarz_i:integer;
    linkElement:TLLElement;
begin
  Stellungswert_i:= spielFeld_xsfC.Stellungsanalyse_f;
  StellungsInfos_xpb.Canvas.TextOut(2,30,'Stellungswert: '+IntToStr(Stellungswert_i));
  spielFeld_xsfC.GetInfos(WeisseFiguren_i,SchwarzeFiguren_i,erreichbareFelderWeis_i,erreichbareSchwarz_i,false);
  StellungsInfos_xpb.Canvas.TextOut(2,43,'Erreichbare Felder:');
  StellungsInfos_xpb.Canvas.TextOut(10,56,'Für Schwarz: '+IntToStr(erreichbareFelderWeis_i));
  StellungsInfos_xpb.Canvas.TextOut(10,69,'Für Weiß: '+IntToStr(erreichbareSchwarz_i));

  //Berechnen wie oft eine Stellung schon aufgetreten ist:
  linkElement:=spielmerker_xll.start;
  Stellungswiederholung_i:=0;
  while (linkElement<>nil)and(linkElement.next<>nil) do begin
    if (TSpielFeldC(linkElement.wert).isEquals(spielFeld_xsfC)) then
      inc(Stellungswiederholung_i);
    linkElement:=linkElement.next;
  end;
    StellungsInfos_xpb.canvas.TextOut(2,82,'Diese Stellung ist bisher');
    StellungsInfos_xpb.canvas.TextOut(2,95,IntToStr(Stellungswiederholung_i)+'mal aufgetreten');
end;
procedure TZentralSpielVerwaltungBrandubh.PaintStellungsAnalyse(sender_xo:TObject);
var
  Stellungswert_i,FuerWeissErreichbarefelder_i,FuerSchwarzErreichbarefelder_i,Stellungswiederholung_i:integer;
begin
  StellungAnalyseAnzeigen(Stellungswert_i,FuerWeissErreichbarefelder_i,FuerSchwarzErreichbarefelder_i,Stellungswiederholung_i);
end;
procedure TZentralSpielVerwaltungBrandubh.UpdateSize(feld_xc:TControl);
begin
  if feld_xc.Width>feld_xc.Height then
    BildSize_i:=feld_xc.Height
   else
    BildSize_i:=feld_xc.Width;
  FeldSize_i:=(BildSize_i-15) div 7;
  BildVerschiebungX_i:=(feld_xc.Width-15-FeldSize_i*7)div 2;
  BildVerschiebungY_i:=(feld_xc.Height-15-FeldSize_i*7)div 2;
end;
procedure TZentralSpielVerwaltungBrandubh.renderTo(ausgabe_xo:TObject);
begin
  UpdateSize(ausgabeFeld_xpb as TControl);
  renderer_xbsfr.renderSpielfeldToFeld(spielFeld_xsfC,ausgabeFeld_xpb as TPaintbox,SelectedX_i,SelectedY_i,BildVerschiebungX_i,BildVerschiebungY_i,FeldSize_i,Konfiguration.OberflaecheHelligkeit_im,true,Konfiguration.OberflaecheZeigAlleErreichbarefelder_b,@analyser_xza.erreichbarefelder_ab,tempFigurX_i,tempFigurY_i);
end;

procedure TZentralSpielVerwaltungBrandubh.MoeglicherZugClick(Sender_xo: TObject);
var start,ziel:TPoint;
    PfeilVerschiebung:integer;
    ts:string;
begin
  renderTo(ausgabeFeld_xpb);
  UpdateSize(ausgabeFeld_xpb);
  ts:=(Sender_xo as Tlistbox).items[(Sender_xo as Tlistbox).itemindex];

  start:=StringToKoordinaten(copy(ts,1,2));
  ziel:=StringToKoordinaten(copy(ts,5,2));
  start.x:=start.x*FeldSize_i+FeldSize_i div 2+BildVerschiebungX_i+15;
  start.y:=start.y*FeldSize_i+FeldSize_i div 2+BildVerschiebungY_i+15;
  ziel.x:=ziel.x*FeldSize_i+FeldSize_i div 2+BildVerschiebungX_i+15;
  ziel.y:=ziel.y*FeldSize_i+FeldSize_i div 2+BildVerschiebungY_i+15;
  PfeilVerschiebung:=FeldSize_i div 4;
  with ausgabeFeld_xpb.Canvas do begin
    Pen.Color:=SetHelligkeit($0000DDDD,Konfiguration.OberflaecheHelligkeit_im-255);
    Pen.Width:=2;
    MoveTo(start.x,start.y);
    LineTo(ziel.x,ziel.y);
    if start.x<ziel.x then begin
      ausgabeFeld_xpb.Canvas.LineTo(ziel.x-PfeilVerschiebung,ziel.y-PfeilVerschiebung);
      ausgabeFeld_xpb.Canvas.MoveTo(ziel.x,ziel.y);
      ausgabeFeld_xpb.Canvas.LineTo(ziel.x-PfeilVerschiebung,ziel.y+PfeilVerschiebung);
    end else if ziel.x<start.x then  begin
      ausgabeFeld_xpb.Canvas.LineTo(ziel.x+PfeilVerschiebung,ziel.y-PfeilVerschiebung);
      ausgabeFeld_xpb.Canvas.MoveTo(ziel.x,ziel.y);
      ausgabeFeld_xpb.Canvas.LineTo(ziel.x+PfeilVerschiebung,ziel.y+PfeilVerschiebung);
    end else if start.y<ziel.y then begin
      ausgabeFeld_xpb.Canvas.LineTo(ziel.x-PfeilVerschiebung,ziel.y-PfeilVerschiebung);
      ausgabeFeld_xpb.Canvas.MoveTo(ziel.x,ziel.y);
      ausgabeFeld_xpb.Canvas.LineTo(ziel.x+PfeilVerschiebung,ziel.y-PfeilVerschiebung);
    end else if ziel.y<start.y then  begin
      ausgabeFeld_xpb.Canvas.LineTo(ziel.x-PfeilVerschiebung,ziel.y+PfeilVerschiebung);
      ausgabeFeld_xpb.Canvas.MoveTo(ziel.x,ziel.y);
      ausgabeFeld_xpb.Canvas.LineTo(ziel.x+PfeilVerschiebung,ziel.y+PfeilVerschiebung);
    end;
  end;
end;

procedure  TZentralSpielVerwaltungBrandubh.DrawListItem(Control_xwc: TWinControl; Index_i: Integer;
  Rect: TRect; State_xods: TOwnerDrawState);
var s:string;
    i,bw,xp:integer;
    listbox:TListBox;
begin
listbox:=(control_xwc as TListBox);
ListBox.Canvas.pen.Style:=psClear;
ListBox.Canvas.brush.Style:=bsSolid;
if odSelected in State_xods then begin
  ListBox.Canvas.brush.Color:=clBlue;
end else begin
  ListBox.Canvas.brush.Color:=ListBox.Color;
end;
ListBox.Canvas.Rectangle(rect.Left,rect.Top-1,rect.Right,rect.Bottom+1);
bw:=ListBox.Canvas.TextWidth('AM W') div 4;
s:=listbox.items[index_i];
i:=1;
xp:=Rect.left;
while i<=length(s) do begin
  if s[i]='\' then begin
    if s[i+1]+s[i+2]='Be' then begin
      renderer_xbsfr.figurenbilder_xfb.DrawToCanvasEx(fBelagerer, listbox.canvas,xp,rect.top,bw*3+2,rect.bottom-rect.top+1,Konfiguration.OberflaecheHelligkeit_im-254);
      s[i]:=#32;s[i+1]:=#32;s[i+2]:=#32;
      xp:=xp+listbox.Canvas.TextWidth(#32) *2;
      inc(i,2);
      continue;
    end;
    if s[i+1]+s[i+2]='Ge' then begin
      renderer_xbsfr.figurenbilder_xfb.DrawToCanvasEx(fGetreuer, listbox.canvas,xp,rect.top,bw*3+2,rect.bottom-rect.top+1,Konfiguration.OberflaecheHelligkeit_im-254);
      s[i]:=#32;s[i+1]:=#32;s[i+2]:=#32;
      xp:=xp+listbox.Canvas.TextWidth(#32) *2;
      inc(i,2);
      continue;
    end;
    if s[i+1]+s[i+2]='Kö' then begin
      renderer_xbsfr.figurenbilder_xfb.DrawToCanvasEx(fKoenig, listbox.canvas,xp,rect.top,bw*3+2,rect.bottom-rect.top+1,Konfiguration.OberflaecheHelligkeit_im-254);
      s[i]:=#32;s[i+1]:=#32;s[i+2]:=#32;
      xp:=xp+listbox.Canvas.TextWidth(#32) *2;
      inc(i,2);
      continue;
    end;
    if s[i+1]='X'then begin
      s[i]:=#32;s[i+1]:=#32;
      ListBox.Canvas.brush.Style:=bsClear;
      ListBox.Canvas.font.Style:=[fsBold];
      listbox.Canvas.Font.Color:=SetHelligkeit(clWhite,Konfiguration.OberflaecheHelligkeit_im-254);
      listbox.canvas.TextOut(xp,rect.top,'x');
      ListBox.Canvas.brush.Style:=bsSolid;
      xp:=xp+listbox.Canvas.TextWidth(#32);
      inc(i);
      continue;
    end;
    if s[i+1]='x' then begin
      ListBox.Canvas.font.color:=SetHelligkeit(clBlack,Konfiguration.OberflaecheHelligkeit_im-254);
      ListBox.Canvas.font.Style:=[fsBold];
      s[i]:=#32;s[i+1]:=#32;
      ListBox.Canvas.brush.Style:=bsClear;
      listbox.canvas.TextOut(xp,rect.top,'x');
      ListBox.Canvas.brush.Style:=bsSolid;
      xp:=xp+listbox.Canvas.TextWidth(#32);
      inc(i);
      continue;
    end;
    if s[i+1]='W' then begin
      ListBox.Canvas.pen.Style:=psSolid;
      ListBox.Canvas.pen.color:=SetHelligkeit(clGray,Konfiguration.OberflaecheHelligkeit_im-254);
      ListBox.Canvas.pen.Width:=2;
      ListBox.Canvas.brush.Color:=SetHelligkeit(clWhite,Konfiguration.OberflaecheHelligkeit_im-254);
      ListBox.Canvas.Rectangle(xp+2,rect.top+2,xp+bw*2-1,rect.bottom-1);
      ListBox.Canvas.pen.Style:=psClear;
      s[i]:=#32;s[i+1]:=#32;
      xp:=xp+listbox.Canvas.TextWidth(#32);
      inc(i);
      continue;
    end;
    if s[i+1]='S' then begin
      ListBox.Canvas.pen.Style:=psSolid;
      ListBox.Canvas.pen.color:=SetHelligkeit(clGray,Konfiguration.OberflaecheHelligkeit_im-254);
      ListBox.Canvas.pen.Width:=2;
      ListBox.Canvas.brush.Color:=SetHelligkeit(clBlack,Konfiguration.OberflaecheHelligkeit_im-254);
      ListBox.Canvas.Rectangle(xp+2,rect.top+2,xp+bw*2-1 ,rect.bottom-1);
      ListBox.Canvas.pen.Style:=psClear;
      s[i]:=#32;s[i+1]:=#32;
      xp:=xp+listbox.Canvas.TextWidth(#32);
      inc(i);
      continue;
    end;

  end;
  xp:=xp+listbox.Canvas.TextWidth(s[i]);
  inc(i);
end;
ListBox.Canvas.brush.Style:=bsClear;
ListBox.Canvas.font.color:=clBlack;
ListBox.Canvas.font.Style:=[];
ListBox.Canvas.TextOut(rect.left+2 ,rect.top,s);
end;

//Bewegt eine Figur von sx|sy zu zx|zy
function TZentralSpielVerwaltungBrandubh.BewegeFigur(sx_i,sy_i,zx_i,zy_i:integer):boolean;
var temp_xsfC:TSpielFeldC;
    t1_i,WeiseFiguren1_i,SchwarzeFiguren1_i,WeiseFiguren2_i,SchwarzeFiguren2_i,Stellungswert_i,tempIndex_i:integer;
    auftreten_i:integer;
    llElement,oldllElement:TLLElement;
    start,ziel:TPoint;
begin
 result:=false;
 try
  meldungsFeld_xccp.Caption:='';meldungsFeld_xccp.hint:='';
  if not spielFeld_xsfC.CanFigureFahren(sx_i,sy_i,zx_i,zy_i) then exit;
  if (ZugMerker_xlb.ItemIndex<>ZugMerker_xlb.items.Count-1) then begin
    t1_i:=0;
    llElement:=spielmerker_xll.start;
    oldllElement:=llElement;
    tempIndex_i:=ZugMerker_xlb.ItemIndex;
    while (llElement<>nil) do begin
      if t1_i>tempIndex_i then begin
        TSpielFeldC(llElement.wert).free;
        if (t1_i=tempIndex_i+1) then begin
          oldllElement.next:=nil;
          spielmerker_xll.ende:=oldllElement;
        end;
        oldllElement:=llElement;
        llElement:=llElement.next;
        oldllElement.free;
        ZugMerker_xlb.Items.Delete(tempIndex_i+1);
      end else begin
        oldllElement:=llElement;
        llElement:=llElement.next;
      end;
      inc(t1_i);
    end;
  end;

  spielFeld_xsfC.GetInfos(WeiseFiguren1_i,SchwarzeFiguren1_i,t1_i,t1_i,false);
  spielFeld_xsfC.BewegeFigur(sx_i,sy_i,zx_i,zy_i);

  renderTo(ausgabeFeld_xpb);

  temp_xsfC:=TSpielFeldC.create;
  temp_xsfC.CloneOther(spielFeld_xsfC);
  spielmerker_xll.add(temp_xsfC);

  StellungAnalyseAnzeigen(Stellungswert_i,WeiseFiguren2_i,SchwarzeFiguren2_i,auftreten_i);
  if spielFeld_xsfC.status_xs=sWeisAmZug then
    ZugMerker_xlb.Items.add(FigurenTypToString(spielfeld_xsfC.felder_xsf[zx_i,zy_i])+' '+KoordinatenToString(sx_i,sy_i)+'->'+KoordinatenToString(zx_i,zy_i)+' ('+IntToStr(spielFeld_xsfC.Stellungsanalyse_f)+' '+MakeString('\X',WeiseFiguren1_i-WeiseFiguren2_i)+ ')')
   else if spielFeld_xsfC.status_xs=sSchwarzAmZug then
    ZugMerker_xlb.Items.add(FigurenTypToString(spielfeld_xsfC.felder_xsf[zx_i,zy_i])+' '+KoordinatenToString(sx_i,sy_i)+'->'+KoordinatenToString(zx_i,zy_i)+' ('+IntToStr(spielFeld_xsfC.Stellungsanalyse_f)+' '+MakeString('\x',SchwarzeFiguren1_i-SchwarzeFiguren2_i)+')');
  ZugMerker_xlb.ItemIndex:=ZugMerker_xlb.items.Count-1;

  //status_xs prüfen
  if spielFeld_xsfC.status_xs=sWeisAmZug then
    aktiverSpieler_xsh.Brush.Color:=SetHelligkeit( $00EEEEEE,Konfiguration.OberflaecheHelligkeit_im-254)
   else if spielFeld_xsfC.status_xs=sSchwarzAmZug then
    aktiverSpieler_xsh.Brush.Color:=SetHelligkeit($00101010{clGray},Konfiguration.OberflaecheHelligkeit_im-254)
   else if spielFeld_xsfC.status_xs=sWeisGewann then begin
    raise ESpielVorbei.Create('Weiß hat gewonnen, da der König entkommen konnte');
   end else if spielFeld_xsfC.status_xs=sSchwarzGewann then begin
    raise ESpielVorbei.Create('Schwarz hat gewonnen, da der König gefangen wurde');
  end;
  //Anzahl der schwarzen Figuren testen
  if SchwarzeFiguren2_i=0 then
    if Konfiguration.RegelnweissgewinntwennschwarzKeineFigurenMehrHat_b then
      raise ESpielVorbei.Create('Weiß hat gewonnen, da Schwarz keine Figuren mehr hat')
    else
      raise ESpielVorbei.Create('Unentschieden, da Schwarz nicht mehr ziehen kann');

  if auftreten_i>=3 then begin
    spielFeld_xsfC.status_xs:=sUnentschieden;
    raise ESpielVorbei.Create('Unentschieden, da die gleiche Stellung zum drittenmal aufgetreten ist');
  end;
  {$INCLUDE Computerspieler.pas}
  if moeglicheZuege_xlb.Items.Count = 0 then
    raise ESpielVorbei.Create('Unentschieden, da es keine Zugmöglichkeit mehr gibt');

  result:=true;
 except
   on e:EZugError do meldungsFeld_xccp.Caption:=e.Message;
   on e:ESpielVorbei do begin
                          aktiverSpieler_xsh.Brush.Color:=SetHelligkeit($00808080,Konfiguration.OberflaecheHelligkeit_im-254);
                          meldungsFeld_xccp.Caption:=e.Message;
                          ShowMessage(e.Message);
                        end;
 end;
end;
//Fahren durck Klicken
procedure TZentralSpielVerwaltungBrandubh.spielfeldMouseDown(Sender_xo: TObject; Button_xmb: TMouseButton;Shift: TShiftState; X_i, Y_i: Integer);
var xFeldPos_i,yFeldPos_i:integer;
begin
  UpdateSize(ausgabeFeld_xpb);
  xFeldPos_i:=(X_i-BildVerschiebungX_i-15)  div FeldSize_i;
  yFeldPos_i:=(Y_i-BildVerschiebungY_i-15)  div FeldSize_i;
  if spielFeld_xsfC.felder_xsf[xFeldPos_i,yFeldPos_i]<>fLeer then begin
    SelectedX_i:=xFeldPos_i;SelectedY_i:=yFeldPos_i;
    tempFigurClickPosX_i:=X_i-xFeldPos_i *FeldSize_i-BildVerschiebungX_i-15;
    tempFigurClickPosY_i:=Y_i-yFeldPos_i *FeldSize_i-BildVerschiebungY_i-15;
  end else
    BewegeFigur(SelectedX_i,SelectedY_i,xFeldPos_i,yFeldPos_i);
  renderTo(ausgabeFeld_xpb);
end;
//Fahren durch Ziehen
procedure TZentralSpielVerwaltungBrandubh.spielfeldMouseMove(Sender_xo: TObject; Shift: TShiftState; X_i,
  Y_i: Integer);
begin
  if (ssLeft in Shift) and (spielFeld_xsfC.felder_xsf[SelectedX_i,SelectedY_i]<>fLeer) then begin
    tempFigurX_i:=x_i-tempFigurClickPosX_i;
    tempFigurY_i:=y_i-tempFigurClickPosY_i;
    renderTo(ausgabeFeld_xpb);
  end;
end;

procedure TZentralSpielVerwaltungBrandubh.spielfeldMouseUp(Sender_xo: TObject; Button_xmb: TMouseButton;
  Shift: TShiftState; X_i, Y_i: Integer);
begin
  if   (spielFeld_xsfC.felder_xsf[SelectedX_i,SelectedY_i]<>fLeer) then 
    BewegeFigur(SelectedX_i,SelectedY_i,(tempFigurX_i+tempFigurClickPosX_i-BildVerschiebungX_i-15)  div FeldSize_i,(tempFigurY_i+tempFigurClickPosY_i-BildVerschiebungY_i-15)  div FeldSize_i);
  tempFigurX_i:=-1;
  renderTo(ausgabeFeld_xpb);
end;

procedure TZentralSpielVerwaltungBrandubh.SelectOldZug(Sender_xo: TObject);

var start,ziel:TPoint;
begin

  spielFeld_xsfC.CloneOther(TSpielFeldC(spielmerker_xll.get(ZugMerker_xlb.ItemIndex+1)));
  case spielFeld_xsfC.status_xs of
    sSchwarzAmZug: aktiverSpieler_xsh.Brush.Color:=SetHelligkeit( $00101010,Konfiguration.OberflaecheHelligkeit_im-254);
    sWeisAmZug: aktiverSpieler_xsh.Brush.Color:=SetHelligkeit( $00EEEEEE,Konfiguration.OberflaecheHelligkeit_im-254);
    else aktiverSpieler_xsh.Brush.Color:=SetHelligkeit( $00808080,Konfiguration.OberflaecheHelligkeit_im-254);
  end;
  {$INCLUDE Computerspieler.pas}
  renderTo(ausgabeFeld_xpb);
end;
destructor TZentralSpielVerwaltungBrandubh.destroy;
var ele:TLLElement;
begin
  renderer_xbsfr.free;
  analyser_xza.free;
  ele:=spielmerker_xll.start;
  while (ele<>nil) do begin
    TSpielFeldC(ele.wert).free;
    ele:=ele.next;
  end;
  spielmerker_xll.Free;
  FConfig_xbc.free;
  spielFeld_xsfC.free;
end;
end.
