Autor |
Beitrag |
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: 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(
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.
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; Weiss = 0; Schwarz = 1;
type FigurIndex = 0..atNil; TypIndex = Bauer..atNil; FeldIndex = -7..atNil; type TFeld = record X, Y: FeldIndex; end; TFarbe = Weiss..Schwarz;
function cFeld(const X, Y: FeldIndex): TFeld;
type TFigur = record Typ: TypIndex; Farbe: TFarbe; Feld: TFeld; end;
type TFigurArray = array[0..31] of TFigur; TFeldArray = array[0..7, 0..7] of FigurIndex; TStellung = record 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..7] of 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; 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]; for i := 0 to 7 do for j := 0 to 7 do Brett[i][j] := qFelder[i][j]; Figuren[Brett[startFeld.X, startFeld.Y]].Feld := zielFeld; if Brett[zielFeld.X, zielFeld.Y] <> atNil then Figuren[Brett[zielFeld.X, zielFeld.Y]].Typ := atNil; 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; 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]; with qFigur do begin if tempFigur <> atNil then if qFiguren[tempFigur].Farbe = Farbe then Exit; case Typ of {$REGION 'Bauer:'} Bauer: begin if Abs(Feld.X - qFeld.X) < 2 then begin if qFeld.Y = Feld.Y + IfThen(Farbe = Weiss, -1, 1) then begin if Feld.X = qFeld.X then result := tempFigur = atNil else result := tempFigur <> atNil; end else begin result := (Feld.X = qFeld.X) and (tempFigur = atNil); if result then if Farbe = Weiss then result := (Feld.Y = 6) and (qFeld.Y = 4) else result := (Feld.Y = 1) and (qFeld.Y = 3); end; end; end; {$ENDREGION} Springer: result := Abs((Feld.X - qFeld.X) * (Feld.Y - qFeld.Y)) = 2; Laeufer: 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 (Abs(qFeld.Y - Feld.Y) = Abs(qFeld.X - Feld.X)); Koenig: result := (Abs(qFeld.X - Feld.X) < 2) and (Abs(qFeld.Y - Feld.Y) < 2); end; end; end;
function Bedroht(const qFelder: TFeldArray; const qFiguren: TFigurArray; const qFigur: TFigur): Boolean; var i: Byte; j, k: FeldIndex; LaufVar: ^FeldIndex; incJ, incK: Boolean; tempFigur: FigurIndex; const Linear = [Turm, Dame]; Diagonal = [Laeufer, Dame]; SpringerFeld: Array[0..9] of FeldIndex = ( 2, 1, -1, -2, -2, -1, 1, 2, 2, 1); 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; Exit; end; end; end; end; {$ENDREGION} {$REGION 'Bauer'} k := Feld.Y + 2 * Farbe - 1; if k in [0..7] then begin tempFigur := qFelder[Feld.X, k]; if tempFigur <> atNil then if qFiguren[tempFigur].Typ = Bauer then begin result := true; Exit; end; end; {$ENDREGION} {$REGION 'König'} tempFigur := 12 * (2 - Farbe); if Abs((Feld.X - qFiguren[tempFigur].Feld.X) * (Feld.Y - qFiguren[tempFigur].Feld.Y)) = 1 then begin result := true; Exit; end; {$ENDREGION} {$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 else LaufVar := @k; incJ := i mod 2 = 0; if incJ then Inc(LaufVar^) else Dec(LaufVar^); while LaufVar^ in [0..7] do 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; Exit; end; Break; end; if incJ then Inc(LaufVar^) else Dec(LaufVar^); end; {$ENDREGION} {$REGION 'Diagonale Richtungen prüfen'} incJ := i < 2; incK := (i mod 2) = 0; 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 tempFigur := qFelder[j, k]; if tempFigur <> atNil then begin if (qFiguren[tempFigur].Farbe <> Farbe) and (qFiguren[tempFigur].Typ in Diagonal) then begin result := true; Exit; end; Break; 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; tempFigur: TFigur; tempTyp: TypIndex; MoveLinear, MoveDiagonal: Boolean; i, j: FeldIndex; const Linear = [Turm, Dame]; Diagonal = [Laeufer, Dame]; begin result := false; if qAbgzogeneFigur.Typ = Koenig then result := not Bedroht(qFelder, qFiguren, qAbgzogeneFigur) else begin tempFigur := qFiguren[gibKoenig(qAbgzogeneFigur.Farbe)]; 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 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
      

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)
|
Verfasst: 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:
Delphi-Quelltext 1: 2: 3:
| type TPlayer=record Attacks: array [0..7,0..7] of 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.
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:
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 
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Fr 11.04.08 16:35
Hi,
Xion 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:
Delphi-Quelltext 1: 2: 3:
| type TPlayer=record Attacks: array [0..7,0..7] of 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.
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:
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
      

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)
|
Verfasst: Sa 12.04.08 11:23
Hidden 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.
Hidden 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)
Hidden 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.
Hidden 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:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| Figur=array of TFigur; PlayerColor[0]='black'; [...] Figur[FIG_BAUER].Pic:='bauer.png'; [...] 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 
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Sa 12.04.08 11:33
Hi,
Xion hat folgendes geschrieben: |
Man könnte jedem Bauer dann einen "Informations-Record" zuweisen:
Delphi-Quelltext 1: 2: 3: 4: 5:
| Figuren=array of TFigur; const PlayerColor='black'; [...] Figur[FIG_BAUER].Pic=PlayerColor+'bauer.png'; | |
Hi,
Es gibt ein Array FBmps[Schachbrett..Koenig] of TBitmap, das genau diesem Vorschlag entspricht, allerdings dann im Program, das diese Unit einbindet.  .
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: 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
      

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)
|
Verfasst: Sa 12.04.08 11:46
Hidden 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:
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 
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Sa 12.04.08 11:57
Xion hat folgendes geschrieben: | Hidden 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:
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 .
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?
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 {$REGION 'Bauer:'} Bauer: begin if Abs(Feld.X - qFeld.X) < 2 then begin if qFeld.Y = Feld.Y + IfThen(Farbe, -1, 1) then begin if Feld.X = qFeld.X then result := tempFigur = 32 else result := tempFigur <> 32; end else if Farbe then result := (Feld.Y = 6) and (qFeld.Y = 4) else result := (Feld.Y = 1) and (qFeld.Y = 3); end; end; {$ENDREGION} Springer: result := Abs((Feld.X - qFeld.X) * (Feld.Y - qFeld.Y)) = 2; Laeufer: 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 (Abs(qFeld.Y - Feld.Y) = Abs(qFeld.X - Feld.X)); 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
      

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)
|
Verfasst: Sa 12.04.08 12:03
Hidden 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)
Hidden 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 . |
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.
//Edit: du solltest natürlich NICHT if Farbe then schreiben  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
      

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)
|
Verfasst: Sa 12.04.08 13:03
Hidden 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 
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Sa 12.04.08 14:19
Xion hat folgendes geschrieben: | Hidden 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  ,
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..7, 0..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
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
      

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)
|
Verfasst: 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 
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Sa 12.04.08 14:51
Xion hat folgendes geschrieben: | unter "Logik-Part" verstehe ich auch KI  |
Könntest du mit durchkommen
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
      

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)
|
Verfasst: 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 
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: 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
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Sa 12.04.08 19:16
Hidden 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
      

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)
|
Verfasst: 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
|
Verfasst: So 13.04.08 11:01
Was mich 'n biserl stört, ist die verwenndung von nummern...
Hidden hat folgendes geschrieben: |
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; qFelder[zielFeld.X, zielFeld.Y] := qFelder[startFeld.X, startFeld.Y]; qFelder[startFeld.X, startFeld.Y] := 32; end; |
|
dabei hast du sie eigentlich schon definiert:
Hidden hat folgendes geschrieben: |
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; Weiss = 0; Schwarz = 1;
type FigurIndex = Byte; TypIndex = Byte; FeldIndex = ShortInt; |
|
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.
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 
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: So 13.04.08 11:30
Hi,
Grenzgaenger hat folgendes geschrieben: | Was mich 'n biserl stört, ist die verwenndung von nummern... |
Umgesetzt und neue Version hochgeladen.
Grenzgaenger 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?
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 = (((², ², ², ², ², ², ², ²), (², ², ², ², ², ², ², ²), (², ², ², ², ², ², ², ²), (², ², ², ², ², ², ², ²), (², ², ², ², ², ², ², ²), (², ², ², ², ², ², ², ²), (², §, ², ², ², ², ², ²), (², ², ², ², ², ², ², ²)), ((², ², ², ², ², ², ², ²), (², ², ², ², ², ², ², ²), (², ², ², ², ², ², ², ²), (², ², ², ², ², ², ², ²), (², ², ², ², ², ², ², ²), (², §, ², ², ², ², ², ²), (², ², §, ², ², ², ², ²), (², ², ², ², ², ², ², ²)), ((², ², ², ², ², ², ², §), (², ², ², ², ², ², §, ²), (², ², ², ², ², §, ², ²), (², ², ², ², §, ², ², ²), (², ², ², §, ², ², ², ²), (², ², §, ², ², ², ², ²), (², §, ², ², ², ², ², ²), (², ², ², ², ², ², ², ²)), ((§, ², ², ², ², ², ², ²), (§, ², ², ², ², ², ², ²), (§, ², ², ², ², ², ², ²), (§, ², ², ², ², ², ², ²), (§, ², ², ², ², ², ², ²), (§, ², ², ², ², ², ², ²), (§, ², ², ², ², ², ², ²), (², §, §, §, §, §, §, §)), ((§, ², ², ², ², ², ², §), (§, ², ², ², ², ², §, ²), (§, ², ², ², ², §, ², ²), (§, ², ², ², §, ², ², ²), (§, ², ², §, ², ², ², ²), (§, ², §, ², ², ², ², ²), (§, §, ², ², ², ², ², ²), (§, §, §, §, §, §, §, §)), ((², ², ², ², ², ², ², ²), (², ², ², ², ², ², ², ²), (², ², ², ², ², ², ², ²), (², ², ², ², ², ², ², ²), (², ², ², ², ², ², ², ²), (², ², ², ², ², ², ², ²), (§, §, ², ², ², ², ², ²), (², §, ², ², ², ², ², ²))); |
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
      

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)
|
Verfasst: 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 
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: So 13.04.08 12:56
Xion 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)
|
|
|