![]() |
LottoTippErstellen
Hallo,
ich hab mal in der Suchfunktion geguckt, aber immer nur Threads gefunden in denen Lottozahlen erstellt werden sollen. Ich will aber einen LottoTippZettel erstellen. Man soll die Anzahl an Tipps angeben können die man abgibt und daraufhin sollen einem genau so viele 6er Lotto Tipps erstellt werden. Dazu habe ich folgendes geschrieben:
Delphi-Quellcode:
Das komische ist nur: Wenn ich diese Prozedur mit Anzahl=1 aufrufe funktioniert sie. Rufe ich sie mit Anzahl=2 auf funktioniert sie nicht mehr. Dann kommt die Fehlermeldung "Zugriffsverletzung bei Adresse 0045845A5". Leider finde ich den Fehler nicht.
unit ULotto;
interface type TLotto=class private Tipp:array of array of word; public procedure LottoTippErstellen(Anzahl:integer); procedure SetTipp(x,y,Wert:integer); end; implementation procedure TLotto.SetTipp(x,y,Wert:integer); begin Tipp[x,y]:=Wert; end; procedure TLotto.LottoTippErstellen(Anzahl: Integer); VAR n,m,o:integer; korekt:boolean; begin korekt:=false; SetLength(Tipp,0,0); SetLength(Tipp,Anzahl,6); For n:=1 to Anzahl do begin For m:=1 to 6 do begin Repeat korekt:=true; SetTipp(n,m,(random(49)+1)); For o:=0 to m-1 do begin IF Tipp[n,m]=Tipp[n,o] then korekt:=false; end; Until korekt=true; end; end; end; end. Ich wäre euch sehr dankbar wenn mir jemande helfen könnte :) |
AW: LottoTippErstellen
Dynamische Arrays sind nullbasierend. Kontrolliere deinen Quellcode daraufhin noch mal.
|
AW: LottoTippErstellen
Achja genau. Das war der Fehler. Vielen Danke :) Jetzt funktioniert es :)
|
AW: LottoTippErstellen
Tipp: Projektoptionen > Bereichsprüfung aktivieren (prüft z.B. die Indize von Arrayzugriffen)
|
AW: LottoTippErstellen
Zudem bietet es sich ja bei OOP an hier etwas feiner zu gliedern:
Delphi-Quellcode:
Jetzt nur noch eine "Sammelklasse" drüberziehen und einen Zugriff auf die Tippfelder gelegt und schon ist die gesamte Klasse fertig ;)
type
TLottoTipp = array [1..49] of Boolean; TLottoFeld = class private FTipp : TLottoTipp; public constructor Create; procedure Reset; // alle Felder zurücksetzen procedure FillUp; end; procedure TLottoFeld.Reset; var idx : integer; begin for idx := Low( FTipp ) to High( FTipp ) do FTipp[ idx ] := False; end; constructor Create; begin inherited; Reset; end; procedure TLottoFeld.FillUp; var idx, Value : integer; begin Reset; for idx := 1 to 6 do begin repeat Value := Random( High( FTipp ) - Low( FTipp ) - 1 ) + Low( FTipp ); // Falls das mal nicht bei 1 anfängt =;0) until not FTipp[ Value ]; FTipp[ Value ] := True; end; end; |
AW: LottoTippErstellen
oder
Delphi-Quellcode:
aka
TLottoTipp = array[1..6] of 1..49;
Delphi-Quellcode:
(andersrum gespeichert, mit fast 'nem 8-tel an Speicher)
TLottoTipp = array[1..6] of Byte;
oder
Delphi-Quellcode:
(das Gleiche, wie array of Boolean, nur mit einem Achtel an Speicherverbrauch)
TLottoTipp = set of 1..49;
(wer es ganz schnell/einfach braucht, nimmt einfach Beides gleichzeitig, also
Delphi-Quellcode:
und
array[1..49] of Boolean
Delphi-Quellcode:
)
array[1..6] of Byte
|
AW: LottoTippErstellen
Zitat:
|
AW: LottoTippErstellen
Zitat:
Delphi-Quellcode:
die Klasse immer noch funktioniert.
TLottoTipp = array [1..64] of Boolean;
Und um es ganz flexibel zu gestalten könnte man ein dynamisches Array benutzen und dem Create als Parameter die Anzahl der Tippfelder und Tipps mitgeben :cyclops:
Delphi-Quellcode:
Jetzt sind die Tipp-Felder allerdings 0 basierend ;) jedoch auch für die Zukunft gerüstet, falls sich beim Lotto mal was ändert :mrgreen:
type
TLottoFeld = class private FTipp : array of Boolean; FMarks : integer; public constructor Create( AFieldCount, AMarks : integer ); destructor Destroy; override; procedure Reset; // alle Felder zurücksetzen procedure FillUp; end; procedure TLottoFeld.Reset; var idx : integer; begin for idx := Low( FTipp ) to High( FTipp ) do FTipp[ idx ] := False; end; constructor TLottoFeld.Create( AFieldCount, AMarks : integer ); begin inherited; SetLength( FTipp, AFieldCount + 1 ); FMarks := AMarks; Reset; end; destructor TLottoFeld.Destroy; begin SetLength( FTipp, 0 ); inherited; end; procedure TLottoFeld.FillUp; var idx, Value : integer; begin Reset; for idx := 1 to FMarks do begin repeat Value := Random( High( FTipp ) + 1 ); until not FTipp[ Value ]; FTipp[ Value ] := True; end; end; |
AW: LottoTippErstellen
Zitat:
Hat Beides also seine Vor-/Nachteile versuch bei dem array of bool mal die gesetzten Zahlen aufzulisten ... muß man erstmal suchen |
AW: LottoTippErstellen
Zitat:
|
AW: LottoTippErstellen
War ein Indexfehler und Sortieren hat auch gefehlt. Die Lösung mit dem repeat/until ist übrigens nicht besonders schön, aber das soll jetzt erst mal egal sein.
Delphi-Quellcode:
unit uLotto;
interface type TLotto = class(TObject) private Tipp: array of array of integer; public procedure LottoTippErstellen(Anzahl: integer); end; implementation procedure TLotto.LottoTippErstellen(Anzahl: integer); const N = 6; var I, J, K, T: integer; Result: boolean; begin SetLength(Tipp, Anzahl, N); for K:= 0 to Anzahl-1 do for I:= 0 to N-1 do repeat Result:= true; Tipp[K, I]:= Random(49)+1; for J:= 0 to I-1 do if Tipp[K, I] = Tipp[K, J] then Result:= false; until Result; for K:= 0 to Anzahl-1 do for I:= 0 to N-2 do for J:= I+1 to N-1 do begin if Tipp[K, I] > Tipp[K, J] then begin T:= Tipp[K, I]; Tipp[K, I]:= Tipp[K, J]; Tipp[K, J]:= T; end; end; end; end. |
AW: LottoTippErstellen
Oder etwas verteilter (enthält noch Verbesserungspotential, aber ich wollte auch nicht übertreiben):
Delphi-Quellcode:
type
TZahlen = array[0..5] of Byte; TLottofeld = class private FZahlen: TZahlen; public constructor Create; property Zahlen: TZahlen read FZahlen; end; TLottoFelder = array of TLottofeld; TLottotipp = class private FTipps: TLottofelder; function GetTipps(Index: integer): TLottofeld; function GetTippCount: integer; public constructor Create(Anzahl: Cardinal); destructor Destroy; override; property Tipps[Index: integer]: TLottofeld read GetTipps; default; property TippCount: integer read GetTippCount; end; { TLottofeld } constructor TLottofeld.Create; var Liste: TList; i, Index: integer; procedure Swap(var a, b: Byte); var tmp: Byte; begin tmp := a; a := b; b := tmp; end; procedure Bubblesort; var Done: Boolean; j, LastPos: integer; begin LastPos := High(FZahlen); repeat Done := true; for j := Low(FZahlen) to LastPos - 1 do if FZahlen[j] > FZahlen[j + 1] then begin Swap(FZahlen[j], FZahlen[j + 1]); Done := false; end; dec(LastPos); until Done; end; begin Liste := TList.Create; try for i := 1 to 49 do Liste.Add(Pointer(i)); for i := Low(FZahlen) to High(FZahlen) do begin Index := Random(Liste.Count); FZahlen[i] := integer(Liste[Index]); Liste.Delete(Index); end; Bubblesort; finally Liste.Free; end; end; { TLottotipp } constructor TLottotipp.Create(Anzahl: Cardinal); var i: integer; begin SetLength(FTipps, Anzahl); for i := 0 to Anzahl - 1 do FTipps[i] := TLottofeld.Create; end; destructor TLottotipp.Destroy; var i: integer; begin for i := Low(FTipps) to High(FTipps) do FTipps[i].Free; SetLength(FTipps, 0); inherited; end; function TLottotipp.GetTippCount: integer; begin Result := Length(FTipps); end; function TLottotipp.GetTipps(Index: integer): TLottofeld; begin Result := FTipps[Index]; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz