Autor Beitrag
Hidden
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Do 10.04.08 22:26 
Hi,

Ich habe eine Unit geschrieben, die den logischen Teil eines Schachprogramms übernehmen soll. Erstmal sollen nur Züge validitätsgeprüft werden, Stellungsbewertungen kommen eventuell später hinzu. Wenn sie fertig ist, soll die Unit in die Open-Source-Units-Sparte, daher wäre ich dankbar für eine generelle Bewertung von Konzept und(wenn dort etwas nicht stimmen sollte) auch Programmierstil.

Zur Indexierung: Ich habe mich entschlossen, mit Indizes, bezogen auf Arrays(Figuren, Felder), zu arbeiten; ich hätte zwischendurch auch(implizite) Pointer verwenden können, wodurch der Code teilweise leichter zu verstehen gewesen wäre(
ausblenden Delphi-Quelltext
1:
qFiguren[eineFigur].doSomeThing or eineFigur.doSomeThing					

). Allerdings wollte ich das Indizekonzept wenn, dann durchgängig, verwenden und Pointer auf Figuren in lokalen Array-Variablen(->Stellungsanalyse) wären nach der Methode invalid gewesen. Mit Indizes kann ich auch später noch arbeiten und z.B. dieselbe Figur zu einem anderen Zeitpunkt betrachten.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
unit logik_Schach;

interface

const
  Bauer = 0;
  Springer = 1;
  Laeufer = 2;
  Turm = 3;
  Dame = 4;
  Koenig = 5;
  atNil = 32;  //Indexrepresentative für nil
  Weiss = 0;
  Schwarz = 1;

type
  FigurIndex = 0..atNil;  //Nummerierung der Figuren
  TypIndex = Bauer..atNil;  //Bauer, Springer, etc.
  FeldIndex = -7..atNil;  //Nummerierung der Felder

type
  TFeld = record
    X, Y: FeldIndex;
  end;
  TFarbe = Weiss..Schwarz;

function cFeld(const X, Y: FeldIndex): TFeld;

type
  TFigur = record
    Typ: TypIndex;  //Bauer, Springer, etc.
    Farbe: TFarbe;
    Feld: TFeld;
  end;

type
  TFigurArray = array[0..31of TFigur;
  TFeldArray = array[0..70..7of FigurIndex;
  TStellung = record  //nur Rückgabewert für Stellungsanalysen
    Brett: TFeldArray;
    Figuren: TFigurArray;
  end;

procedure NeuePartie(var qFiguren: TFigurArray; var qFelder: TFeldArray);
function Zug(const qFelder: TFeldArray; const qFiguren: TFigurArray;
             const startFeld, zielFeld: TFeld): TStellung;
procedure Ziehe(var qFelder: TFeldArray; var qFiguren: TFigurArray;
                const startFeld, zielFeld: TFeld);
function VersucheZug(var qFelder: TFeldArray; var qFiguren: TFigurArray;
                     var qFigur: FigurIndex; zielFeld: TFeld): Boolean;
function gibKoenig(qFarbe: TFarbe): FigurIndex;

function ZugFeld(const qFigur: TFigur; const qFeld: TFeld;
           const qFiguren: TFigurArray; const qFelder: TFeldArray): Boolean;
function Bedroht(const qFelder: TFeldArray; const qFiguren: TFigurArray;
                const qFigur: TFigur): Boolean;
function AbzugsSchach(const qFiguren: TFigurArray; const qFelder: TFeldArray;
                      const qAbgzogeneFigur: TFigur): Boolean;

implementation

uses
  Types, Math;
                                                                   
function cFeld(const X, Y: FeldIndex): TFeld;
begin
  result.X := X;
  result.Y := Y;
end;

procedure NeuePartie(var qFiguren: TFigurArray; var qFelder: TFeldArray);
  procedure FigurAufFeld(const qFigur: FigurIndex; const qTyp: TypIndex;
                         const qFarbe: TFarbe; const qFeld: TFeld);
  begin
    with qFiguren[qFigur] do begin
      Typ := qTyp;
      Farbe := qFarbe;
      Feld := qFeld;
    end;
    qFelder[qFeld.X, qFeld.Y] := qFigur;
  end;

var
  i, j: FeldIndex;
const
  Kompl: Array[0..7of TypIndex =
    (Turm, Springer, Laeufer, Dame, Koenig, Laeufer, Springer, Turm);
begin
  for i := 0 to 7 do begin
    for j := 2 to 5 do
      qFelder[i][j] := atNil;  // leeres Feld
    FigurAufFeld(i,      Bauer,    Weiss,   cFeld(i, 6));
    FigurAufFeld(i + 16, Bauer,    Schwarz, cFeld(i, 1));
    FigurAufFeld(i + 8,  Kompl[i], Weiss,   cFeld(i, 7));
    FigurAufFeld(i + 24, Kompl[i], Schwarz, cFeld(i, 0));
  end;
end;

function Zug(const qFelder: TFeldArray; const qFiguren: TFigurArray;
             const startFeld, zielFeld: TFeld): TStellung;
var
  i, j: FeldIndex;
begin
  with result do begin
    for i := 0 to 31 do
      Figuren[i] := qFiguren[i];  //Figuren kopieren
    for i := 0 to 7 do
      for j := 0 to 7 do
        Brett[i][j] := qFelder[i][j];  //Stellung kopieren
    Figuren[Brett[startFeld.X, startFeld.Y]].Feld := zielFeld;
    if Brett[zielFeld.X, zielFeld.Y] <> atNil then
      Figuren[Brett[zielFeld.X, zielFeld.Y]].Typ := atNil;  //geschlagen
    Brett[zielFeld.X, zielFeld.Y] := Brett[startFeld.X, startFeld.Y];
    Brett[startFeld.X, startFeld.Y] := atNil;
  end;
end;

procedure Ziehe(var qFelder: TFeldArray; var qFiguren: TFigurArray;
                const startFeld, zielFeld: TFeld);
begin
  qFiguren[qFelder[startFeld.X, startFeld.Y]].Feld := zielFeld;
  if qFelder[zielFeld.X, zielFeld.Y] <> atNil then
    qFiguren[qFelder[zielFeld.X, zielFeld.Y]].Typ := atNil;  //geschlagen
  qFelder[zielFeld.X, zielFeld.Y] := qFelder[startFeld.X, startFeld.Y];
  qFelder[startFeld.X, startFeld.Y] := atNil;
end;

function VersucheZug(var qFelder: TFeldArray; var qFiguren: TFigurArray;
                     var qFigur: FigurIndex; zielFeld: TFeld): Boolean;
begin
  result := qFigur <> atNil;
  if result then begin
    result := ZugFeld(qFiguren[qFigur], zielFeld, qFiguren, qFelder);
    if result then
      Ziehe(qFelder, qFiguren, qFiguren[qFigur].Feld, zielFeld);
  end;
end;

function gibKoenig(qFarbe: TFarbe): FigurIndex;
begin
  if qFarbe = Weiss then
    result := 12
  else result := 28;
end;

function ZugFeld(const qFigur: TFigur; const qFeld: TFeld;
           const qFiguren: TFigurArray; const qFelder: TFeldArray): Boolean;
var
  tempFigur: FigurIndex;
begin
  result := false;
  tempFigur := qFelder[qFeld.X, qFeld.Y];  //eventuell geschlagene Figur
  with qFigur do begin
    if tempFigur <> atNil{nil} then
      if qFiguren[tempFigur].Farbe = Farbe then
        Exit;  //man kann keine eigenen Figuren schlagen
    case Typ of  //Liegt das Zielfeld im Zugmuster der Figur?
      {$REGION 'Bauer:'}
      Bauer: begin
        if Abs(Feld.X - qFeld.X) < 2 then begin  //Startfeld.X - Zielfeld.X
          //Ansonsten weicht Zielfeld.X um mehr als 1 von Startfeld.X ab!
          if qFeld.Y = Feld.Y + IfThen(Farbe = Weiss, -11then begin
            if Feld.X = qFeld.X then  //normaler Zug geradeaus
              result := tempFigur = atNil  //Feld ist leer
            else result := tempFigur <> atNil;
          end else begin  //Wenn Zug um mehr als 1 Feld
            result := (Feld.X = qFeld.X) and (tempFigur = atNil);
            if result then
              if Farbe = Weiss then
                result := (Feld.Y = 6and (qFeld.Y = 4)  //Doppelzug am Anfang
              else result := (Feld.Y = 1and (qFeld.Y = 3);
          end;
        end;
      end;
      {$ENDREGION}
      Springer: result := Abs((Feld.X - qFeld.X) * (Feld.Y - qFeld.Y)) = 2;
      Laeufer:  //        DeltaY        =         DeltaX
        result := Abs(qFeld.Y - Feld.Y) = Abs(qFeld.X - Feld.X);  
      Turm: result := (qFeld.X = Feld.X) or (qFeld.Y = Feld.Y);
      Dame: result := (qFeld.X = Feld.X) or (qFeld.Y = Feld.Y) or  //Turm
                      (Abs(qFeld.Y - Feld.Y) = Abs(qFeld.X - Feld.X));  //Läufer
      Koenig: result := (Abs(qFeld.X - Feld.X) < 2and
                        (Abs(qFeld.Y - Feld.Y) < 2);
    end;
  end;
  //result := result and not Bedroht(qFelder, qFiguren,
  //                           qFiguren[IfThen(qFigur.Farbe = Weiss, 12, 28)]);
  //result := result and not AbzugsSchach(qFiguren, qFelder, qFigur);
end;

function Bedroht(const qFelder: TFeldArray; const qFiguren: TFigurArray;
                const qFigur: TFigur): Boolean;
var
  i: Byte;
  j, k: FeldIndex;  //j = X; k = Y
  LaufVar: ^FeldIndex;
  incJ, incK: Boolean;
  tempFigur: FigurIndex;
const
  Linear = [Turm, Dame];  //Gefahrenquellen
  Diagonal = [Laeufer, Dame];
  SpringerFeld: Array[0..9of FeldIndex =  //i = 0..7 [i, i + 2] erfasst
    ( 2,  1, -1, -2, -2, -11221);   //alle Springerfelder
begin
  result := false;
  with qFigur do begin
    {$REGION 'Springer'}
      for i := 0 to 7 do begin
        j := Feld.X + SpringerFeld[i];
        k := Feld.Y + SpringerFeld[i + 2];
        if (j in [0..7]) and (k in [0..7]) then begin
          tempFigur := qFelder[j][k];
          if tempFigur <> atNil then begin
            if (qFiguren[tempFigur].Typ = Springer) and
               (qFiguren[tempFigur].Farbe <> Farbe) then
            begin
              result := true;  //Schach durch Springer
              Exit;
            end;
          end;
        end;
      end;
    {$ENDREGION}
    {$REGION 'Bauer'}
      k := Feld.Y + 2 * Farbe - 1;  //Y eines pot. schachgebenden Bauers
      if k in [0..7then begin
        tempFigur := qFelder[Feld.X, k];
        if tempFigur <> atNil then
          if qFiguren[tempFigur].Typ = Bauer then begin
            result := true;  //Schach durch Bauern
            Exit;
          end;
      end;
    {$ENDREGION}
    {$REGION 'König'}
      tempFigur := 12 * (2 - Farbe);  //gegnerischer König
      if Abs((Feld.X - qFiguren[tempFigur].Feld.X) *
             (Feld.Y - qFiguren[tempFigur].Feld.Y)) = 1 then
      begin
        result := true;  //Schach durch gegnerischen König
        Exit;
      end;
    {$ENDREGION}
    //In alle Richtungen nach Schachgebern suchen
    {$REGION 'Strahlenförmige Suche vom König weg'}
      for i := 0 to 3 do begin
      {$REGION 'Lineare Richtungen prüfen'}
        j := Feld.X;
        k := Feld.Y;
        if i < 2 then LaufVar := @j  //Die ersten zwei zählen X,
        else LaufVar := @k;  //Die letzten zwei Y-Richtung

        incJ := i mod 2 = 0;  //Jede zweite zählt nach unten
        if incJ then Inc(LaufVar^) else Dec(LaufVar^);
        while LaufVar^ in [0..7do begin
          tempFigur := qFelder[j, k];
          if tempFigur <> atNil then begin
            if (qFiguren[tempFigur].Farbe <> Farbe) and
               (qFiguren[tempFigur].Typ in Linear) then
            begin
              result := true;  //Schach durch Dame oder Turm
              Exit;
            end;
            Break;  //Figur blockiert Reihe, keine weitere Schachmöglichkeit
          end;
          if incJ then Inc(LaufVar^) else Dec(LaufVar^);
        end;
      {$ENDREGION}
      {$REGION 'Diagonale Richtungen prüfen'}
        incJ := i < 2;  //Die ersten zwei zählen X aufwärts
        incK := (i mod 2) = 0;  //jede zweite zählt Y abwärts
        j := Feld.X + IfThen(incJ, 1, -1);
        k := Feld.Y + IfThen(incK, 1, -1);
        while (j in [0..7]) and (k in [0..7]) do begin  //doppelte for(diagonal)
          tempFigur := qFelder[j, k];
          if tempFigur <> atNil then begin
            if (qFiguren[tempFigur].Farbe <> Farbe) and
               (qFiguren[tempFigur].Typ in Diagonal) then
            begin
              result := true;  //Schach
              Exit;
            end;
            Break;  //Figur blockiert Reihe, keine weitere Schachmöglichkeit
          end;
          if incJ then Inc(j) else Dec(j);
          if incK then Inc(k) else Dec(k);
        end;
      {$ENDREGION}
      end;
    {$ENDREGION}
  end;
end;

function AbzugsSchach(const qFiguren: TFigurArray; const qFelder: TFeldArray;
                      const qAbgzogeneFigur: TFigur): Boolean;
var
  Richtung: TFeld;  //Differenzvektor aus Ortsverktoren ZugFigur - König
  tempFigur: TFigur;
  tempTyp: TypIndex;
  MoveLinear, MoveDiagonal: Boolean;
  i, j: FeldIndex;  //Laufvariablen
const
  Linear = [Turm, Dame];  //Gefahrenquellen
  Diagonal = [Laeufer, Dame];
begin
  result := false;
  if qAbgzogeneFigur.Typ = Koenig then
    result := not Bedroht(qFelder, qFiguren, qAbgzogeneFigur)
  else begin
    tempFigur := qFiguren[gibKoenig(qAbgzogeneFigur.Farbe)];  //eigener König
    Richtung := cFeld(tempFigur.Feld.X - qAbgzogeneFigur.Feld.X,
                      tempFigur.Feld.Y - qAbgzogeneFigur.Feld.Y);
    MoveLinear := Richtung.X * Richtung.Y = 0;
    MoveDiagonal := Abs(Richtung.X) = Abs(Richtung.Y);
    if MoveLinear or MoveDiagonal then begin  //auf Abzugsschach prüfen
      Richtung.X := Sign(Richtung.X);
      Richtung.Y := Sign(Richtung.Y);
      i := tempFigur.Feld.X + Richtung.X;
      j := tempFigur.Feld.Y + Richtung.Y;
      while (i in [0..7]) and (j in [0..7]) do begin
        if qFelder[i, j] <> atNil then begin
          tempTyp := qFiguren[qFelder[i][j]].Typ;
          result := (MoveLinear  and  (tempTyp in Linear)) or
                    (MoveDiagonal and (tempTyp in Diagonal));
          Exit;
        end;
        Inc(i, Richtung.X);
        Inc(j, Richtung.Y);
      end;
    end;
  end;
end;

end.


Edit: Quelltext aktualisiert.

mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)


Zuletzt bearbeitet von Hidden am So 13.04.08 11:32, insgesamt 5-mal bearbeitet
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Fr 11.04.08 14:56 
hmm, also da bei Schach jetzt nicht so auf Rechenleistung zu achten ist (außer wenn der NPC einen zug macht) würde ich das ganze mehr auf Übersicht machen:

ausblenden Delphi-Quelltext
1:
2:
3:
type TPlayer=record
   Attacks: array [0..7,0..7of integer; 
end;


in dieses Array schreibst du nach jedem Zug, wo überall angegriffen wird (und wie viele). Dadurch könnte es dir auch später einfacher sein, einen Zug für den PC zu berechnen, denn man sieht sofort, welches Feld wie oft angegriffen ist. Wenn du das für jeden Spieler machst, siehst du z.B. sofort, wann eine Figur ungedeckt ist usw.
ausblenden Delphi-Quelltext
1:
2:
3:
if (Player[0].Feld[X,Y]=0)and(Brett[X,Y]<>FIG_NONE) then 
  ShowMessage('ungedeckte Figur von Spieler 1 auf Feld +'+inttostr(X)+'/'+inttostr(Y)
  +'. Sie wird '+ inttostr(Player[1].Feld[X,Y])+'x bedroht');


Zudem würde ich nicht die gleichen Figuren durch verschiedene Nummern kennzeichnen:
ausblenden Delphi-Quelltext
1:
2:
3:
const
 FIG_NONE=0;
 FIG_BAUER=1;

ggf eine Ausnahme würde da vielleicht der schwarze/weiße Läufer machen, aber das ist eher ein Stellungsvorteil.

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Hidden Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Fr 11.04.08 16:35 
Hi,

user profile iconXion hat folgendes geschrieben:
hmm, also da bei Schach jetzt nicht so auf Rechenleistung zu achten ist (außer wenn der NPC einen zug macht) würde ich das ganze mehr auf Übersicht machen:

ausblenden Delphi-Quelltext
1:
2:
3:
type TPlayer=record
   Attacks: array [0..7,0..7of integer; 
end;


in dieses Array schreibst du nach jedem Zug, wo überall angegriffen wird (und wie viele). Dadurch könnte es dir auch später einfacher sein, einen Zug für den PC zu berechnen, denn man sieht sofort, welches Feld wie oft angegriffen ist. Wenn du das für jeden Spieler machst, siehst du z.B. sofort, wann eine Figur ungedeckt ist usw.
ausblenden Delphi-Quelltext
1:
2:
3:
if (Player[0].Feld[X,Y]=0)and(Brett[X,Y]<>FIG_NONE) then 
  ShowMessage('ungedeckte Figur von Spieler 1 auf Feld +'+inttostr(X)+'/'+inttostr(Y)
  +'. Sie wird '+ inttostr(Player[1].Feld[X,Y])+'x bedroht');

eine nett Idee, aber kompliziert und daher wahrscheinlich leider unbrauchbar: Einerseits muss bei Figuren wie z.B. Dame dann vor einem Zug in jede Richtung dec(Attacks[dame.x, dame.y] und nach einem Zug in jede Richtung inc mit den neuen Koordinaten. Diese strahlenförmige Suche wird dann abgebrochen, wenn eine blockierende Figur gefunden wurde, wie gehabt.

Andererseits musst du bei der Gelegenheit auch auf Abzugsschach prüfen, d.h. schauen, in welchen Richtungen ein Zugstrahl(Dame, Turm, Läufer) blockiert wurde und diesen fortsetzen.

Entscheidend ist aber die bereits von dir genannte Problematik: sobald eine KI verwendet wird, muss dies für jeden simulierten Zug auch mitsimmuliert werden. Die Unit soll, wie gesagt, beliebig ausbaubar sein und dieser Ansatz würde einen Ausbau zur KI blockieren.

Zitat:
Zudem würde ich nicht die gleichen Figuren durch verschiedene Nummern kennzeichnen:
ausblenden Delphi-Quelltext
1:
2:
3:
const
 FIG_NONE=0;
 FIG_BAUER=1;

ggf eine Ausnahme würde da vielleicht der schwarze/weiße Läufer machen, aber das ist eher ein Stellungsvorteil.

Ich nehme mal an, du beziehst dich auf den Wert 32, der hier als Synonym für nil verwendet wird. Eventuell zuerst zur Kompatiblität des Umstiegs auf Zeiger belassen. Sauberer ist es natürlich ohne: "Keine Figur" ist strenggenommen kein Figurentyp.

Das mit den Läufern verstehe ich nicht ganz...

mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Sa 12.04.08 11:23 
user profile iconHidden hat folgendes geschrieben:

eine nett Idee, aber kompliziert und daher wahrscheinlich leider unbrauchbar: Einerseits muss bei Figuren wie z.B. Dame dann vor einem Zug in jede Richtung dec(Attacks[dame.x, dame.y] und nach einem Zug in jede Richtung inc mit den neuen Koordinaten. Diese strahlenförmige Suche wird dann abgebrochen, wenn eine blockierende Figur gefunden wurde, wie gehabt.

stelle ich mir eigentlich machbar vor.

user profile iconHidden hat folgendes geschrieben:

Andererseits musst du bei der Gelegenheit auch auf Abzugsschach prüfen, d.h. schauen, in welchen Richtungen ein Zugstrahl(Dame, Turm, Läufer) blockiert wurde und diesen fortsetzen.

ggf. das ganze array nach jedem Zug platt machen und komplett neu befüllen, das würde auch das erste problem vereinfachen (kein dec)

user profile iconHidden hat folgendes geschrieben:

Entscheidend ist aber die bereits von dir genannte Problematik: sobald eine KI verwendet wird, muss dies für jeden simulierten Zug auch mitsimmuliert werden. Die Unit soll, wie gesagt, beliebig ausbaubar sein und dieser Ansatz würde einen Ausbau zur KI blockieren.

hab mir die Idee nur so ausm stegreif überlegt...8x8 felder sind aber jetzt eigentlich nicht soo kompliziert zu berechnen.

user profile iconHidden hat folgendes geschrieben:

Ich nehme mal an, du beziehst dich auf den Wert 32, der hier als Synonym für nil verwendet wird. Eventuell zuerst zur Kompatiblität des Umstiegs auf Zeiger belassen. Sauberer ist es natürlich ohne: "Keine Figur" ist strenggenommen kein Figurentyp.

ich meine eigentlich noch zusätzlich, dass jeder Bauer eigentlich gleich ist (da du aber bis 32 zählst nimmst du für jeden bauer eine andre zahl). Das mit dem schwarzen/weißen Läufer bezieht sich darauf, dass die eigentlich nicht gleich sind (wie die Bauern), aber ich sie trotzdem mit der gleichen Nummer kennzeichnen würde und dafür auf Stellungsvorteil achten würde.

Man könnte jedem Bauer dann einen "Informations-Record" zuweisen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
Figur=array of TFigur;
PlayerColor[0]='black';
[...]
Figur[FIG_BAUER].Pic:='bauer.png';
//ggf. auch mit zugmöglichkeiten
[...]
Brett[x,y].Pic.LoadfromFile( PlayerColor[ Brett[x,y].Color ] + Figur[ Brett[x,y].Fig ].Pic)

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Hidden Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Sa 12.04.08 11:33 
Hi,

user profile iconXion hat folgendes geschrieben:

Man könnte jedem Bauer dann einen "Informations-Record" zuweisen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
Figuren=array of TFigur;
const PlayerColor='black';
[...]
Figur[FIG_BAUER].Pic=PlayerColor+'bauer.png';
//ggf. auch mit zugmöglichkeiten


Hi,

Es gibt ein Array FBmps[Schachbrett..Koenig] of TBitmap, das genau diesem Vorschlag entspricht, allerdings dann im Program, das diese Unit einbindet. :wink: .

Zu deinem Edit: Ich zeichne die Figuren am Ende mit Draw(x, y, FBmps[meineFigur.Typ]], bzw. strechdraw, auf die Paintbox.

Zitat:
(da du aber bis 32 zählst nimmst du für jeden bauer eine andre zahl)

0..31 sind die Referenzen zu den von dir erwähnten Informationsrecords. Sie enthalten Typ, Farbe, Feld.

Edit: Wobei Farbe und Typ sich im Prinzip auch aus der Referenznummer ergeben. Typ setze ich auf 32, wenn die Figur geschlagen wurde. 32 war ursprünglich einfach die erste Zahl außerhalb des Arrays der Figuren und ist hiermit eigentlich zu einem Synonym für nil geworden. Wie o.e., kann ich keine Zeiger verwenden, da bei vorausberechneten Stellungen diese auf ein beliebiges Figurenarray(Infomationsrecords) anwendbar sein sollen.

Edit2: die Farben sind übrigens mit Boolean realisiert:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
type
  TFarbe = Boolean;
const
  Weiss = true;
  Schwarz = false;


mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Sa 12.04.08 11:46 
user profile iconHidden hat folgendes geschrieben:

Edit: Wobei Farbe und Typ sich im Prinzip auch aus der Referenznummer ergeben. Typ setze ich auf 32, wenn die Figur geschlagen wurde. 32 war ursprünglich einfach die erste Zahl außerhalb des Arrays der Figuren und ist hiermit eigentlich zu einem Synonym für nil geworden. Wie o.e., kann ich keine Zeiger verwenden, da bei vorausberechneten Stellungen diese auf ein beliebiges Figurenarray(Infomationsrecords) anwendbar sein sollen.

hmm, also ich würde statt 32 eine -1 nehmen...

Edit: ich mag für sowas keine booleans, da man diese nicht einfach aus einem array auslesen kann:
ausblenden Delphi-Quelltext
1:
2:
 Color:=C_BlackColor;
 LoadPicture(Pic[Color]);

bei einem boolean braucht man dann immer if abfragen usw.

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Hidden Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Sa 12.04.08 11:57 
user profile iconXion hat folgendes geschrieben:
user profile iconHidden hat folgendes geschrieben:

Edit: Wobei Farbe und Typ sich im Prinzip auch aus der Referenznummer ergeben. Typ setze ich auf 32, wenn die Figur geschlagen wurde. 32 war ursprünglich einfach die erste Zahl außerhalb des Arrays der Figuren und ist hiermit eigentlich zu einem Synonym für nil geworden. Wie o.e., kann ich keine Zeiger verwenden, da bei vorausberechneten Stellungen diese auf ein beliebiges Figurenarray(Infomationsrecords) anwendbar sein sollen.

hmm, also ich würde statt 32 eine -1 nehmen...

Gute Idee. Leider verwende ich Byte; sollte ich generell auf Shortint umsteigen?
Zitat:
Edit: ich mag für sowas keine booleans, da man diese nicht einfach aus einem array auslesen kann:
ausblenden Delphi-Quelltext
1:
2:
 Color:=C_BlackColor;
 LoadPictures(Pic[Color]);

bei einem boolean braucht man dann immer if abfragen usw.

Das stimmt für Arrays.. Wenn ich allerdings(was vergleichsweise ständig vorkommt) im logik-Teil auf die Farbe prüen muss, ist das if Farbe = C_BlackColor statt if Farbe. Andererseits wird der code dadurch unleserlich und ich brauche häufiger einen kommentar //Weiss entspricht true.

Edit: Mal was anderes: Wenn das System am Ende auf KI umgerüstet wird, ist es dann nicht günstiger, wenn ich statt dieser methematischen Zugmusterprüfung vordefinierte Arrays [-7..7, -7..7] of Boolean für jede Figur definiere?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
case Typ of  //Liegt das Zielfeld im Zugmuster der Figur?
  {$REGION 'Bauer:'}
  Bauer: begin
    if Abs(Feld.X - qFeld.X) < 2 then begin  //Startfeld.X - Zielfeld.X
      //Ansonsten weicht Zielfeld.X um mehr als 1 von Startfeld.X ab!
      if qFeld.Y = Feld.Y + IfThen(Farbe, -11then begin
        if Feld.X = qFeld.X then  //normaler Zug geradeaus
          result := tempFigur = 32  //Feld ist leer
        else result := tempFigur <> 32
      end else //Wenn Zug um mehr als 1 Feld
        if Farbe {= Weiss} then  //Weiss entspricht true
          result := (Feld.Y = 6and (qFeld.Y = 4)  //Doppelzug am Anfang
        else result := (Feld.Y = 1and (qFeld.Y = 3);
    end;
  end;
  {$ENDREGION}
  Springer: result := Abs((Feld.X - qFeld.X) * (Feld.Y - qFeld.Y)) = 2;
  Laeufer:  //        DeltaY        =         DeltaX
    result := Abs(qFeld.Y - Feld.Y) = Abs(qFeld.X - Feld.X);  
  Turm: result := (qFeld.X = Feld.X) or (qFeld.Y = Feld.Y);
  Dame: result := (qFeld.X = Feld.X) or (qFeld.Y = Feld.Y) or  //Turm
                  (Abs(qFeld.Y - Feld.Y) = Abs(qFeld.X - Feld.X));  //Läufer
  Koenig: result := Abs((qFeld.X - Feld.X) * (qFeld.Y - Feld.Y)) = 1;
end;


mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)


Zuletzt bearbeitet von Hidden am Sa 12.04.08 12:10, insgesamt 2-mal bearbeitet
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Sa 12.04.08 12:03 
user profile iconHidden hat folgendes geschrieben:

Gute Idee. Leider verwende ich Byte; sollte ich generell auf Shortint umsteigen?

wie wäre es mit var I: [-1..31](irgendwie so geht das ;) ggf. mit runden klammern)

user profile iconHidden hat folgendes geschrieben:

Wenn ich allerdings(was vergleichsweise ständig vorkommt) im logik-Teil auf die Farbe prüen muss, ist das if Farbe = C_BlackColor statt if Farbe. Andererseits wird der code dadurch unleserlich und ich brauche häufiger einen kommentar //Weiss entspricht true.

das versteh ich nicht...du hast doch für deine möglichkeit weiss=True definiert (unter const) somit ist es doch leserlich. Und statt True kannst du auch 0 zuweisen. :gruebel:

//Edit: du solltest natürlich NICHT if Farbe then schreiben :lol: sondern if Farbe=weiss then

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Sa 12.04.08 13:03 
user profile iconHidden hat folgendes geschrieben:

Edit: Mal was anderes: Wenn das System am Ende auf KI umgerüstet wird, ist es dann nicht günstiger, wenn ich statt dieser methematischen Zugmusterprüfung vordefinierte Arrays [-7..7, -7..7] of Boolean für jede Figur definiere?


hmmm, jo, könnte durchaus sinnvoll sein. Beim Bauer ist das nur etwas schwierig...Hmmm, ne, ich denke mal, die allgemeinen Regeln sind besser. Man müsste sich erstmal n Konzept überlegen, wie die KI vorgehen soll.

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Hidden Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Sa 12.04.08 14:19 
user profile iconXion hat folgendes geschrieben:
user profile iconHidden hat folgendes geschrieben:

Edit: Mal was anderes: Wenn das System am Ende auf KI umgerüstet wird, ist es dann nicht günstiger, wenn ich statt dieser methematischen Zugmusterprüfung vordefinierte Arrays [-7..7, -7..7] of Boolean für jede Figur definiere?


hmmm, jo, könnte durchaus sinnvoll sein. Beim Bauer ist das nur etwas schwierig...Hmmm, ne, ich denke mal, die allgemeinen Regeln sind besser. Man müsste sich erstmal n Konzept überlegen, wie die KI vorgehen soll.


Hi und erstmal danke für dein reges Engagement :wink: ,

Ich dachte an eine function ZugMusterCheck(Figur, Zielfeld - Startfeld): Boolean. Zielfeld - Startfeld ist dabei die Projektion auf das Muster. Diese Funktion könnte ja ohne weiteres für andere Figuren ein vordefiniertes Array nehmen und einen Bauern seperat prüfen...

Die Frage, die ich mir stelle, ist diese: Wie sollte ich das Verhältnis zwischen Rechenleistung und Musterspeicher gestalten? Ich könnte z.B. bei Symmetrischen Figuren(also alles bis auf Bauer) die Arrays als [0..70..7] definieren und Abs(Zielfeld - Startfeld) nehmen, IMHO durchaus praktikabel. Abs() hätte ja sogar Laufzeit O(0), da ja nichts gerechnet werden muss, sondern nur das Vorzeichen nicht mit ausgelesen, oder?

Eigentlich geht es hier ja nicht hauptsächlich um eine KI, also hier [OT]: Eine Schach-KI stelle ich mir so vor, dass sie für jeden möglichen Zug wiederum jeden möglichen Zug im voraus berechnet. Die sich daraus ergebenden Zugketten hätten verschiedene Abbruchbedingungen. Nun werden so lange Zugketten fortgesetzt, bis entweder nurnoch ein Zug verbleibt oder n Züge erreicht sind. Nach n Zügen Auswertung wird dann der Zug gewählt, der, vorausgesetzt, dass beide Seiten jeweils nach diesem Modell spielen, nach n Zügen die beste Stellungsbewertung hat. Verbleiben mehrere Möglichkeiten, liefert rnd() Entscheidungshilfe :mrgreen:

Zusammenfassend gesagt, dachte ich also an eine rekursive Lösung. Gehen wir es noch einmal einfach durch: angenommen n = 1, so wird der Zug gewählt, der die Stellungsbewertung am positivsten verändert. ist n = 2, so wird der gewählt, der bei optimaler Reaktion des Gegners mit optimaler Bewertungsänderung ausgeht. Usw...

Eine Stellungsbewertung kann für große n einfach als der Quotient der Summen der Figurenwerte angesehen werden. Dabei bekommt der König einen Wert, der das Programm ein sicheres Schlagen des Königs(Matt) stets bevorzugen lässt.[/OT]

mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Sa 12.04.08 14:30 
diese Methode ist zwar die normale Methode, allerdings braucht die 32^n Berechnungsschritte, was durchaus problematisch wird.

Deshalb verwenden Schachprogramme meist eine Datenbank, und rechnen nur im Notfall. Dies ist z.B. bei der Eröffnung praktisch.

Ich fände ja ein Schachprogramm lustig, das eine solche Datenbank erst im Laufe der Zeit erstellt => am Anfang ist er erstmal sehr dumm. Aber nach kurzer Zeit funktionieren schon einige Tricks nicht mehr. Ich bin auch der Meinung, man sollte dem Rechner das vorgehen geben, welches auch ein echter Spieler hat. Ich z.B. berechne nie alle Zugmöglichkeiten im Kopf vorher. ;) z.B. sind Züge gut, die eine gegnerische Figur vor dem König fesseln usw.. Ich würde mehr mit solchen Dingen arbeiten, als zu rechnen bis der PC platzt, aber dafür weiß ich nicht, ob meine Methode auf Dauer funktioniert.

//Edit: unter "Logik-Part" verstehe ich auch KI ;)

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Hidden Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Sa 12.04.08 14:51 
user profile iconXion hat folgendes geschrieben:
unter "Logik-Part" verstehe ich auch KI ;)
Könntest du mit durchkommen :lol:

Was den "Menschenähnlich-Part" angeht, die Idee hatte ich auch schon und dachte mir man könnte das vielleicht als Spielstufe möglich machen, eine KI, die wie ein Mensch spielt!

@(Dynamische Buchzüge und Gedächnis)^: Man könnte sogar eine KI programmieren, die explizit nach deinen typischen Fehlern spielt, die würde, glaube ich, in kürzester Zeit dein Schachspiel verbessern :!: leider ziemlich kompliziert...

mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)


Zuletzt bearbeitet von Hidden am So 13.04.08 01:58, insgesamt 2-mal bearbeitet
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Sa 12.04.08 15:10 
da liegt halt das Problem, KI(=künstliche Intelligenz) gibt es einfach nicht (bis heute zumindest).

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Hidden Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Sa 12.04.08 15:16 
Ich hab den Quelltext oben mal auf den neusten Stand gebracht, sind aber eigentlich nur ein paar kleine Änderungen.

Edit: Kennt sich jemand mit GNU-Lizenzen aus? Dürfte ich z.B. diese Figur aus den Wikipedia-Comments einfach in mein Programm einbinden, wenn ich es hier gezippt hochladen würde: de.wikipedia.org/wiki/Bild:Chess_rdl44.png ?

Edit2: Ja, ist erlaubt.

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)


Zuletzt bearbeitet von Hidden am So 13.04.08 01:59, insgesamt 1-mal bearbeitet
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Sa 12.04.08 19:16 
user profile iconHidden hat folgendes geschrieben:
Edit: Kennt sich jemand mit GNU-Lizenzen aus? Dürfte ich z.B. diese Figur aus den Wikipedia-Comments einfach in mein Programm einbinden, wenn ich es hier gezippt hochladen würde: de.wikipedia.org/wiki/Bild:Chess_rdl44.png ?


Bitte erstelle für eine neue Frage ein neues Topic (vgl. Foren-Richtlinien)

Danke
AXMD
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: So 13.04.08 10:51 
auch wenns nicht zum Logik-Part des Schachprogramms gehört:
ich hab mal ein "Schachbrett" programmiert (völlig ohne jede Logik). Wenn du die Bilder verwenden willst, kannst die gerne haben (bitte vorher bescheidsagen). Das gilt auch für andre Leute, bei interesse könnt ihr euch diese Bilder nehmen, aber schreibt mir pls. vorher eine PN, damit ich bescheid weiß.
Einloggen, um Attachments anzusehen!
_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Grenzgaenger
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 13.04.08 11:01 
Was mich 'n biserl stört, ist die verwenndung von nummern...

user profile iconHidden hat folgendes geschrieben:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
begin
  qFiguren[qFelder[startFeld.X, startFeld.Y]].Feld := zielFeld;
  if qFelder[zielFeld.X, zielFeld.Y] <> 32 then
    qFiguren[qFelder[zielFeld.X, zielFeld.Y]].Typ := 32;  //geschlagen
  qFelder[zielFeld.X, zielFeld.Y] := qFelder[startFeld.X, startFeld.Y];
  qFelder[startFeld.X, startFeld.Y] := 32;
end;



dabei hast du sie eigentlich schon definiert:
user profile iconHidden hat folgendes geschrieben:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
  Bauer = 0;
  Springer = 1;
  Laeufer = 2;
  Turm = 3;
  Dame = 4;
  Koenig = 5;
  atNil = 32;  //Indexrepresentative für nil
  Weiss = 0;
  Schwarz = 1;

type
  FigurIndex = Byte;  //Nummerierung der Figuren
  TypIndex = Byte;  //Bauer, Springer, etc.
  FeldIndex = ShortInt;  //Nummerierung der Felder



fänd es gut, wenn du die zahlen gegen die konstanten austauschen würdest, dann kannst du dein programm wohl auch noch in ein paar wochen lesen.

BTW: man könnte sie ja auch anderweitig schreiben z.b.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  type 
   tFigur = (figBauer, figLaeufer, figTurm, figSpringer, figDame, figKoenig);
   tColor = (clWhite, clBlack);

   tFigurs = Set of tFigur;
   tColors = Set of tColor;


dann könntest du über mengenoperatoren auch einfach darauf zugreifen.

BTW2: beim überfliegen deines codes, hatte ich den eindruck, dass hier noch keine logik für die züge vorhanden ist, sondern dass diese unit eher das regelwerk abbildet... das regelwerk ist natürlich elementar, ohne einem funktionierenden macht eine logik auch keinen sinn. von daher eine design frage, willst du für das regelwerk und die logik eine unit verwenden oder diese auf zwei units aufteilen?

das Regelwerk hat sich seit jahrtausenden praktisch nicht verändert (wenn man von der einführung einer zeitbeschränkung (z. b. blitzschach)) absieht.

während du wohl noch lange an der logik zur optimierung herumtüfteln kannst...
Hidden Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: So 13.04.08 11:30 
Hi,

user profile iconGrenzgaenger hat folgendes geschrieben:
Was mich 'n biserl stört, ist die verwenndung von nummern...

Umgesetzt und neue Version hochgeladen.

user profile iconGrenzgaenger hat folgendes geschrieben:
BTW2: beim überfliegen deines codes, hatte ich den eindruck, dass hier noch keine logik für die züge vorhanden ist, sondern dass diese unit eher das regelwerk abbildet... das regelwerk ist natürlich elementar, ohne einem funktionierenden macht eine logik auch keinen sinn. von daher eine design frage, willst du für das regelwerk und die logik eine unit verwenden oder diese auf zwei units aufteilen?

das Regelwerk hat sich seit jahrtausenden praktisch nicht verändert (wenn man von der einführung einer zeitbeschränkung (z. b. blitzschach)) absieht.

während du wohl noch lange an der logik zur optimierung herumtüfteln kannst...


Ja, das kommt auf jeden Fall in eine getrennte Unit. Insofern war vielleicht der Titel des Treads nicht ganz richtig gewählt(werde ihn trotzdem mal lassen, da hier ja schon über logik generell gesprochen wurde).

Edit: Ich habe mich mal mit der praktischen Umsetzung meiner o.e. Idee befasst, den Zugmustercheck auf Arrays zurückzuführen. Hat das hier ncoh etwas mit sauberem Porogrammierstil zu tun, oder sollte ich die Arrays zur Laufzeit erstellen und nach meinen Formeln befüllen?
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
const
  § = true;
  ² = false;
  ZugMuster: Array[Bauer..Koenig] of
             Array[ValidFeld] of
             Array[ValidFeld] of Boolean =
    (((², ², ², ², ², ², ², ²),  //Bauer
      (², ², ², ², ², ², ², ²),
      (², ², ², ², ², ², ², ²),
      (², ², ², ², ², ², ², ²),
      (², ², ², ², ², ², ², ²),
      (², ², ², ², ², ², ², ²),
      (², §, ², ², ², ², ², ²),
      (², ², ², ², ², ², ², ²)),
     ((², ², ², ², ², ², ², ²),  //Springer
      (², ², ², ², ², ², ², ²),
      (², ², ², ², ², ², ², ²),
      (², ², ², ², ², ², ², ²),
      (², ², ², ², ², ², ², ²),
      (², §, ², ², ², ², ², ²),
      (², ², §, ², ², ², ², ²),
      (², ², ², ², ², ², ², ²)),
     ((², ², ², ², ², ², ², §),  //Laeufer
      (², ², ², ², ², ², §, ²),
      (², ², ², ², ², §, ², ²),
      (², ², ², ², §, ², ², ²),
      (², ², ², §, ², ², ², ²),
      (², ², §, ², ², ², ², ²),
      (², §, ², ², ², ², ², ²),
      (², ², ², ², ², ², ², ²)),
     ((§, ², ², ², ², ², ², ²),  //Turm
      (§, ², ², ², ², ², ², ²),
      (§, ², ², ², ², ², ², ²),
      (§, ², ², ², ², ², ², ²),
      (§, ², ², ², ², ², ², ²),
      (§, ², ², ², ², ², ², ²),
      (§, ², ², ², ², ², ², ²),
      (², §, §, §, §, §, §, §)),
     ((§, ², ², ², ², ², ², §),  //Dame
      (§, ², ², ², ², ², §, ²),
      (§, ², ², ², ², §, ², ²),
      (§, ², ², ², §, ², ², ²),
      (§, ², ², §, ², ², ², ²),
      (§, ², §, ², ², ², ², ²),
      (§, §, ², ², ², ², ², ²),
      (§, §, §, §, §, §, §, §)),
     ((², ², ², ², ², ², ², ²),  //Koenig
      (², ², ², ², ², ², ², ²),
      (², ², ², ², ², ², ², ²),
      (², ², ², ², ², ², ², ²),
      (², ², ², ², ², ², ², ²),
      (², ², ², ², ², ², ², ²),
      (§, §, ², ², ², ², ², ²),
      (², §, ², ², ², ², ², ²)));


mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: So 13.04.08 12:47 
sollte die Figur nicht in der Mitte des Arrays stehen? Weil dein Läufer-Array ist so ja völlig unbrauchbar ^^

Springer:

- - - - - - - - - - - - - -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - -
- - - - - - x - x - - - - -
- - - - - x - - - x - - - -
- - - - - - - P - - - - - -
- - - - - x - - - x - - - -
- - - - - - x - x - - - - -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - -

=> projeziert auf das Feld hast du dann alle Felder, auf die der Springer ziehen kann.

//Edit: naja, nach deinen arrays musst du sie dann noch nach unten/links spiegeln

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Hidden Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: So 13.04.08 12:56 
user profile iconXion hat folgendes geschrieben:
//Edit: naja, nach deinen arrays musst du sie dann noch nach unten/links spiegeln

Ups, danke. die Arrays haben ja oben links ihren Ursprung.

Zu der Sache mit der Mitte: Alle Figuren außer Bauer sind Symmetrisch, d.h., ich bilde Abs(StartFeld.X - Zielfeld.X) und dasgleiche mit Y und greife damit aufs Array zu.

Is es denn besser, sie als konstante drin zu haben oder sollte ich sie zur Laufzeit erzeugen?

mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)