Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Probleme mit Umrechnung und korrekter Ausgabe (https://www.delphipraxis.net/126253-probleme-mit-umrechnung-und-korrekter-ausgabe.html)

SoD 21. Dez 2008 11:50


Probleme mit Umrechnung und korrekter Ausgabe
 
Mahlzeit liebe DPler,

ich arbeite derzeit an einem "kleinen" textbasierten RPG, bei dem ich einen Assistenten zur Charakter-Erstellung machen möchte. Dabei stoße ich jetzt auf ein unerwartet großes Problem: Es will mir nicht gelingen die 4 verschiedenen Währungseinheiten gemäß dem mir vorliegenden Regelwerk zu implementieren. Falls es

Folgende Einheiten gibt es (wer Das Schwarze Auge kennt erzähl ich hier wenig neues :wink:):

Kreuzer (kleinste)
Heller (klein)
Silber (Einheit vor der ausgegangen wird)
Dukaten (größte)

Das Problem an der ganzen Sache: Ich krieg es ums Verrecken nicht hin, dass mir diese vier Einheiten in vier verschiedenen Edits korrekt angezeigt werden, wenn man ab jeweils 10 in die nächste Einheit überwechselt. Das sieht dann nämlich so aus, als hätte man 2 EUR und 161 Cent und man meint, sich was für 3 EUR nicht leisten zu können.

Mir sind die Ideen ausgegangen, wie ich das richtig coden muss.

Delphi-Quellcode:
procedure TFrame2CharCreate.GetCountMoney(Sender: TObject);

var
  iSilber: Integer;

begin
  // Zufallsgenerator init
  Randomize;

  // Vermögen auswürfteln
  repeat
    iSilber := Random(6)
  until iSilber > 0; // Nullwert verhindern

  iSilber := (iSilber + 6) * 10; // = Gewürfeltes Silber
  EditSilber.Text := IntToStr(iSilber);

  // Währungs-Einheiten umrechnen
  if iSilber > 10 then
  begin
    {???}
  end;
end;
Hat hier jemand ne Idee, wie man das lösen könnte?

mkinzler 21. Dez 2008 12:10

Re: Probleme mit Umrechnung und korrekter Ausgabe
 
Schau dir mal DIV und MOD an

DeddyH 21. Dez 2008 12:21

Re: Probleme mit Umrechnung und korrekter Ausgabe
 
Zitat:

Delphi-Quellcode:
repeat
    iSilber := Random(6)
  until iSilber > 0; // Nullwert verhindern

:pale:

Mach das lieber so:
Delphi-Quellcode:
iSilber := Random(6) + 1;
, dann brauchst Du keine Schleife.

Ansonsten würde ich mir einen Record für die Währungen definieren sowie 2 Umrechnungsfunktionen, ausgehend von der kleinsten Währung. Das könnte dann so aussehen:
Delphi-Quellcode:
(* Im Normalfall genügt es, diese Typdefinition direkt unter "implementation" zu schreiben.
   Es handelt sich hierbei um eine Struktur mit 4 Feldern für die jeweilige Währung.
   Angesprochen werden können diese Felder über die Punkt-Notation (s.u.) *)
type
  TMoneyRec = record
    iKreuzer,
    iHeller,
    iSilber,
    iDukaten: Cardinal;
  end;

//Rechnet die angegebenen Kreuzer in Währungen um und gibt das Ergebnis als Record zurück
function KreuzerToMoneyRec(cKreuzer: Cardinal): TMoneyRec;
begin
  //Beispiel: 1234 wurden übergeben

  Result.iKreuzer := cKreuzer mod 10; // = 4 Kreuzer (Rest bei Teilung durch 10)

  //jetzt wird erst durch 10 geteilt (= 123)
  //und davon wieder der Rest bei erneuter Teilung durch 10 ermittelt (= 3 Heller)
  Result.iHeller := cKreuzer div 10 mod 10;

  //nun analog das Gleiche, allerdings wird jetzt durch 100 geteilt
  Result.iSilber := cKreuzer div 100 mod 10;

  //zum Schluss brauchen wir keinen Rest mehr, das Ergebnis der Division ergibt die Dukaten
  Result.iDukaten := cKreuzer div 1000;
end;

//Rechnet den übergebenen Record wieder in Kreuzer zurück
//Rechenweg umgekehrt zu oben
function MoneyRecToKreuzer(aRec: TMoneyRec): Cardinal;
begin
  Result := aRec.iKreuzer +
            aRec.iHeller * 10 +
            aRec.iSilber * 100 +
            aRec.iDukaten * 1000;
end;
P.S.: Willkommen in der DP :dp:

SoD 21. Dez 2008 14:40

Re: Probleme mit Umrechnung und korrekter Ausgabe
 
@mkinzler: div und mod kenn ich schon, aber man kennt das ja, "gewusst wie" :wink:

@DeddyH: Danke für den Tipp, ohne Schleife kommt mir das gleich sicherer vor, ich werd's ausprobieren, nur wo muss das type anfangen? Die Syntax-Überprüfung verwirrt mich etwas :oops: Hab vorher noch nie eigene Typen gecoded und mit Records auch noch nicht recht viel gemacht (= gar nichts :mrgreen:).

Und damit ich noch was von lerne eine Bitte: Könnte man den Code vielleicht dokumentieren? Wäre super :zwinker:

DeddyH 21. Dez 2008 14:55

Re: Probleme mit Umrechnung und korrekter Ausgabe
 
Dein Wunsch war mir Befehl :zwinker:

Luckie 21. Dez 2008 15:35

Re: Probleme mit Umrechnung und korrekter Ausgabe
 
Zitat:

Zitat von DeddyH
Ansonsten würde ich mir einen Record für die Währungen definieren sowie 2 Umrechnungsfunktionen, ausgehend von der kleinsten Währung. Das könnte dann so aussehen:

Dann kann man adas ganze auch gleich sauber in eine Klasse packen. Dui hast die daten und dazugehörig die Methoden, um sie zu manipulieren. Das schreit förmlich nach einer Klasse.

DeddyH 21. Dez 2008 15:37

Re: Probleme mit Umrechnung und korrekter Ausgabe
 
Eine Klasse musst Du aber instanziieren (es sei denn, man definiert die Umrechnungen als Klassenmethoden) und später wieder freigeben. Ich wollte den TE nicht noch mehr verwirren :mrgreen:.

Apollonius 21. Dez 2008 16:27

Re: Probleme mit Umrechnung und korrekter Ausgabe
 
Ab Delphi 2006 ist das ein Fall für einen 'advanced record' mit Methoden.

SoD 21. Dez 2008 16:55

Re: Probleme mit Umrechnung und korrekter Ausgabe
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von DeddyH
Eine Klasse musst Du aber instanziieren (es sei denn, man definiert die Umrechnungen als Klassenmethoden) und später wieder freigeben. Ich wollte den TE nicht noch mehr verwirren :mrgreen:.

Gut, dass du's nicht getan hast, das wär nämlich sonst passiert :zwinker:

Die Tipps und Erklärungen sind zwar gut, aber ich sollte wohl noch dazu sagen, dass ich noch ein bisschen "an der Hand geführt" werden muss, da ich noch über kein allzu umfassendes Programmierwissen in Delphi verfüge; steh erst am Anfang meiner Ausbildung :mrgreen:

Ich hänge mal einen Screenshot des Frames an, in dem die Werte ausgewürfelt werden sollen.

Kurze Erklärung:

Per "Würfeln!" soll der Würfel ins Rollen gebracht und mit erneutem Klick angehalten werden. Nun ist ein Wert erwürfelt und ein erneuter Klick wiederholt die ganze Show im jeweils nächsten Feld. Die Timer Komponente soll dabei die Geschwindigkeit der vorbeirauschenden Zahlen im Edit bestimmen, wobei dieser schnell eingestellt ist, sodass es sich mehr oder weniger schwierig gestaltet einen gewünschten hohen Wert ganz "zufällig" zu bekommen. Erst wenn alle Felder ausgefüllt sind, soll der Weiter-Button Active := true sein, damit man alle Schritte erst ausführen muss.

Die Unit bis jetzt:

Delphi-Quellcode:
unit FrameCharCreate2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, DBTables, StdCtrls, Mask, DBCtrls, ExtCtrls, jpeg;

type
  TFrame2CharCreate = class(TFrame)
    GroupBoxCharProperties: TGroupBox;
    LabelMU: TLabel;
    LabelKL: TLabel;
    LabelCH: TLabel;
    LabelGE: TLabel;
    LabelKK: TLabel;
    ButtonRandomize: TButton;
    ButtonCharCreateFrame2Next: TButton;
    ButtonCharCreateFrame2Back: TButton;
    LabelHeader: TLabel;
    LabelDescription: TLabel;
    Timer1: TTimer;
    ImageCharCreate: TImage;
    EditMU: TEdit;
    EditKL: TEdit;
    EditCH: TEdit;
    EditGE: TEdit;
    EditKK: TEdit;
    GroupBoxMoney: TGroupBox;
    LabelDukaten: TLabel;
    LabelSilbertaler: TLabel;
    LabelHeller: TLabel;
    LabelKreuzer: TLabel;
    ButtonMoneyRandomize: TButton;
    EditSilber: TEdit;
    EditKreuzer: TEdit;
    EditHeller: TEdit;
    EditDukaten: TEdit;
    Timer2: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure ButtonRandomizeClick(Sender: TObject);
    procedure ButtonMoneyRandomizeClick(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure GetCount (Sender: TObject);
    procedure GetCountMoney (Sender: TObject);
  public
    { Public-Deklarationen }
    var editCount: Byte;
    var editCountMoney: Byte;
  end;

implementation

{$R *.dfm}

procedure TFrame2CharCreate.ButtonMoneyRandomizeClick(Sender: TObject);
begin
  if EditKreuzer.Text = '' then
  begin
    editCountMoney := 0;
  end;

  if ButtonMoneyRandomize.Tag = 0 then
  begin
    ButtonMoneyRandomize.Tag := 1;
    Timer2.Enabled := True;
  end
  else
  begin
    if ButtonMoneyRandomize.Tag = 1 then
    begin
      ButtonMoneyRandomize.Tag := 0;
      Timer2.Enabled := False;
      Inc(editCountMoney);
    end;
  end;

  if (editCountMoney = 1) and (ButtonMoneyRandomize.Tag = 0) then
  begin
    ButtonMoneyRandomize.Enabled := False;
  end;
end;

procedure TFrame2CharCreate.ButtonRandomizeClick(Sender: TObject);
begin
  if EditMU.Text = '' then
  begin
    editCount := 0;
  end;

  if ButtonRandomize.Tag = 0 then
  begin
    ButtonRandomize.Tag := 1;
    Timer1.Enabled := True;
  end
  else
  begin
    if ButtonRandomize.Tag = 1 then
    begin
      ButtonRandomize.Tag := 0;
      Timer1.Enabled := False;
      Inc(editCount);    
    end;
  end;

  if (editCount = 5) and (ButtonRandomize.Tag = 0) then
  begin
    ButtonRandomize.Enabled := False;
  end;
end;

procedure TFrame2CharCreate.GetCount(Sender: TObject);

var
  i: Integer;

begin
  // Zufallsgenerator init
  Randomize;

  // Zufälligen Wert ermitteln
    i := Random(6) + 1;

  i := i+7;

  if editCount = 0 then
  begin
    EditMU.Text := IntToStr(i);
  end
  else
  begin
    if editCount = 1 then

    begin
      EditKL.Text := IntToStr(i);
    end
    else
    begin
      if editCount = 2 then
      begin
        EditCH.Text := IntToStr(i);
      end
      else
      begin
        if editCount = 3 then
        begin
          EditGE.Text := IntToStr(i);
        end
        else
        begin
          if editCount = 4 then
          begin
            EditKK.Text := IntToStr(i);
          end;
        end;
      end;
    end;
  end;
end;

procedure TFrame2CharCreate.GetCountMoney(Sender: TObject);

var
  iSilber: Integer;

begin
  // Zufallsgenerator init
  Randomize;

  // Vermögen auswürfteln
  iSilber := Random(6) + 1;

  iSilber := (iSilber + 6) * 10;
  EditSilber.Text := IntToStr(iSilber);

  // Währungs-Einheiten umrechnen
  if iSilber > 10 then
  begin
    EditDukaten.Text := IntToStr(iSilber - 10);
  end;
end;

procedure TFrame2CharCreate.Timer1Timer(Sender: TObject);
begin
  GetCount(Sender);
end;

procedure TFrame2CharCreate.Timer2Timer(Sender: TObject);
begin
  GetCountMoney(Sender);
end;

end.

DeddyH 21. Dez 2008 17:03

Re: Probleme mit Umrechnung und korrekter Ausgabe
 
Da sind ein bisschen viele Randomize-Aufrufe drin (einmalig z.B. im OnCreate genügt). Außerdem lassen sich die vielen Ifs meist durch case-Abfragen ersetzen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:18 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz