Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- unit UOperator;
- interface
- uses
- Classes,sysutils,math,strutils,Graphics, windows, dialogs;
- type
- TTypeOperation = (OPaddition, OPsoustraction, OPmultiplication, OPdivision);
- TTypeEtape=(ET_Lancement,ET_Poser,ET_EcrireChiffre,ET_EcrireRetenue,ET_EcrireSigne);
- PEtape = ^TEtape;
- TEtape = record
- Ordre : Integer; // permet de n'afficher que certaines étapes
- // typiquement : 0 = avant alignement
- // 1 = Aligner
- // 2...n calculs détailés
- TypeEtape:TTypeEtape; // identifie ce que fait l'étape
- nombre : Integer; // éventuellement le chiffre ou la retenue à écrire
- commentaire:string[255]; // pour éventuelle sortie
- x,y : integer; // coordonnées du carreau concerné
- end;
- TOperation = class
- private
- FTypeOperation: TTypeOperation;
- fN1, fN2: Currency;
- fListeEtapes: TList;
- fSLNombres : TStrings;
- // taille d'un carreau
- fcote : Integer;
- // marges gauche et heut pour centrer dans le canevas
- fMargeG,fMargeH : Integer;
- // puissance minimum et maximum atteinte par les nombres
- fPmax,fPmin : Integer;
- // nombre de carreaux nécessaires pour poser l'opération
- fnbx,fnby : integer;
- // Tstrings pour sortie débuggage
- FSLDebug: TStrings;
- fCanvas : Tcanvas;
- // couleurs
- fCoulFond: Tcolor;
- fCoulTrait : Tcolor;
- fCoulTraitFin : Tcolor;
- fCoulChiffres : Tcolor;
- fCoulRetenues : Tcolor;
- property ListeEtapes: TList read fListeEtapes;
- procedure WriteDebug(const Msg: string);
- procedure SetSLDebug(const Value: TStrings);
- procedure SetTypeOperation(ATypeOperation: TTypeOperation);
- function GetTypeOperation: TTypeOperation;
- procedure SetN1(Value: Currency);
- function GetN1: Currency;
- procedure SetN2(Value: Currency);
- function GetN2: Currency;
- Procedure RAZ;
- procedure TraceCarreaux;
- procedure PrepareAddSous(TypeOperation : TTypeOperation = OPaddition);
- procedure AjouteEtape(aOrdre : integer ; aTypeetape : TTypeEtape; aNombre : integer;aCommentaire : string; ax,ay : INteger );
- procedure MoteurAddition;
- public
- constructor Create(ATypeOperation: TTypeOperation; AN1, AN2: Currency;ACanvas : TCanvas);
- destructor Destroy; override;
- procedure PrepareOperation;
- property TypeOperation: TTypeOperation read GetTypeOperation write SetTypeOperation;
- property N1: Currency read GetN1 write SetN1;
- property N2: Currency read GetN2 write SetN2;
- property SLDebug: TStrings read FSLDebug write SetSLDebug;
- Procedure AfficheOperation;
- end;
- implementation
- Procedure TOperation.AfficheOperation;
- var i: Integer;
- Etape:PEtape;
- begin
- WriteDebug('AfficheOperation ****');
- WriteDebug(format(' nb étapes : %d',[fListeEtapes.Count]));
- For i := 0 to fListeEtapes.Count-1 do
- begin
- Etape := fListeEtapes[i];
- WriteDebug(format(' étape : %d %s',[i, etape^.commentaire]));
- case etape^.TypeEtape of
- ET_Lancement : begin
- TraceCarreaux;
- fCanvas.TextOut(50,50,'LANCEMENT');
- fCanvas.Refresh;
- end;
- ET_Poser : begin
- end;
- end; //case etape.TypeEtape of
- end;
- end;
- procedure TOperation.AjouteEtape(aOrdre : integer ; aTypeetape : TTypeEtape; aNombre : integer;aCommentaire : string; aX,ay : INteger );
- var Etape:PEtape;
- begin
- new(Etape);
- with Etape^ do
- begin
- Ordre :=aOrdre;
- nombre :=aNombre;
- commentaire :=aCommentaire;
- x := ax;
- y := ay;
- end;
- fListeEtapes.Add(Etape);
- //WriteDebug( format('AjouteEtape : ordre %d type,n° d n=%d, comm=%s x,y = %d,%d',[aOrdre,{ord(aTypeetape),} aNombre, aCommentaire,aX,ay]));
- end;
- procedure TOperation.MoteurAddition;
- var i,j : Integer;
- ordre_etape : Integer;
- begin
- WriteDebug('moteuraddition *******************');
- writedebug(Format('puiss mini %d maxi %d',[fPmin,fPmax]));
- writedebug(Format('n1 n2 = %g et %g',[fN1,fN2]));
- WriteDebug('fSLNombres :');
- for i := 0 to fSLNombres.Count -1 do
- begin
- WriteDebug(format('%d [%s]',[i,fSLNombres[i]]));
- end;
- AjouteEtape(0,
- ET_Lancement,-1,
- format('Addition : %g + %g : prochaine étape : opération posée',[fn1,fn2]),
- -1,-1);
- for i := 0 to 1 do
- begin
- end;
- end;
- procedure TOperation.TraceCarreaux;
- var i,j : Integer;
- begin
- with fCanvas do
- begin
- brush.Style := bsSolid;
- brush.Color := fCoulFond;
- FillRect(ClipRect);
- // tracé des lignes horizontales
- for i := 0 to 3 do
- begin
- // traits épais
- pen.Width := 3;
- pen.Color := fCoulTrait;
- polyline([point(fmargeG,fmargeH+i*fcote),point(fmargeG+fnbx*fcote,fmargeH+i*fcote)]);
- // traits fins
- if i<3 then
- for j := 1 to 3 do
- begin
- pen.Width := 1;
- pen.Color := fCoulTraitFin;
- polyline([point(fmargeG,fmargeH+i*fcote + fcote div 4 *j),point(fmargeG+fnbx*fcote,fmargeH+i*fcote+fcote div 4 *j)]);
- end;
- end;
- // tracé des lignes verticales
- pen.Width := 3;
- pen.Color := fCoulTrait;
- for i := 0 to fnbx do
- polyline([point(fMargeG + i*fcote,fMargeH ),point(fMargeG + i*fcote,fMargeH+fnby *fcote)]);
- brush.Style := bsClear;
- // affichage nom colonne
- font.Height := fcote div 10;
- font.color := clBlack ;
- end;
- end;
- (*
- Aligner l'opération
- mettre à jour pPmin, fPmax, fnbx, fnby
- *)
- procedure TOperation.PrepareAddSous(TypeOperation : TTypeOperation = OPaddition);
- var
- placevirg: Integer;
- i: Integer;
- Decimales,MaxDecimals: Integer;
- Entiere, MaxEntiere : Integer;
- OB: integer;
- FormatStr: string;
- StrN : string;
- TabNombres: array[0..2] of currency;
- begin
- if (TypeOperation = opSoustraction) and(n1<n2) then
- begin
- fn1 := n2;
- fn2 := n1;
- end
- else
- begin
- fn1 := n1;
- fn2 :=n2;
- end;
- WriteDebug(format('PrepareAddSous : n1 %g n2 %g', [fn1,fn2]));
- TabNombres[0]:=fN1;
- TabNombres[1]:=fN2;
- case TypeOperation of
- opAddition : begin
- TabNombres[2]:=fn1+fn2;
- end;
- opSoustraction : begin
- TabNombres[2]:=fn1-fn2;
- end;
- end;
- // Initialisations
- MaxDecimals := 0;
- MaxEntiere :=0;
- for i := 0 to 2 do
- begin
- (* copier les nombres au format court %g dans le StringList
- calculer maxdecimales et maxentieres
- Mémoriser la longueur de la partie entière et cele de la partie décimale
- dans le Tobject de la liste SL 1000*longueurentiere + longueur décimale
- *)
- StrN := format('%g',[TabNombres[i]]);
- placevirg := pos(DecimalSeparator,StrN);
- if placevirg > 0 then
- begin
- Decimales :=length(StrN) - placevirg;
- Entiere := placevirg -1;
- MaxDecimals := Max(MaxDecimals, Decimales);
- MaxEntiere := Max(MaxEntiere , Entiere);
- end
- else // entier
- begin
- Entiere := length(StrN);
- Decimales := 0;
- MaxEntiere := Max(MaxEntiere ,Entiere);
- end;
- OB := 1000* Entiere + Decimales;
- fSLNombres.AddObject(Strn,Tobject(OB)) ;
- end;
- // formater les nombres SANS separateur décimal
- // des espaces à gauche de la partie entière
- // des 'o' pour compléter la partie décimale
- for i := 0 to fSLNombres.Count-1 do
- begin
- OB := Integer(fSLNombres.Objects[i]);
- Entiere := OB div 1000;
- decimales := OB mod 1000;
- StrN := StringReplace(fSLNombres[i],DecimalSeparator,'',[rfReplaceAll]) ;
- StrN := StrN + DupeString('o',MaxDecimals-Decimales);
- StrN := DupeString(' ',MaxEntiere-entiere) + StrN ;
- fSLNombres[i]:=strn;
- end;
- // ajouter le signe
- case TypeOperation of
- OPaddition : begin
- fSLNombres[0] := ' ' + fSLNombres[0];
- fSLNombres[1] := '+' + fSLNombres[1];
- fSLNombres[2] := ' ' + fSLNombres[2];
- end;
- OPsoustraction : begin
- fSLNombres[0] := ' ' + fSLNombres[0];
- fSLNombres[1] := '-' + fSLNombres[1];
- fSLNombres[2] := ' ' + fSLNombres[2];
- end;
- end;
- fPmax := MaxEntiere;
- fPmin := -MaxDecimals;
- fnbx := (fpmax - fPmin) + 1;
- fnby := 3;
- fcote := Min((fCanvas.ClipRect.Right - 1) div fnbx, (fCanvas.ClipRect.Bottom ) div fnby -1);
- fMargeG := (fCanvas.ClipRect.Right - fnbx * fcote) div 2;
- fMargeH := (fCanvas.ClipRect.Bottom - fnby * fcote) div 2;
- case TypeOperation of
- OPaddition : MoteurAddition;
- OPsoustraction : ;
- OPmultiplication : ;
- OPdivision : ;
- end;
- //ecrirevirgule := (fpmin<0);
- //Result := Point(MaxEntiere, MaxDecimals );
- end;
- procedure TOperation.WriteDebug(const Msg: string);
- begin
- if Assigned(FSLDebug) then FSLDebug.Add(Msg);
- end;
- procedure TOperation.SetSLDebug(const Value: TStrings);
- begin
- FSLDebug := Value;
- end;
- constructor TOperation.Create(ATypeOperation: TTypeOperation; AN1, AN2: Currency;ACanvas : TCanvas);
- begin
- fCoulFond := clWhite; // Couleur de fond par défaut
- fCoulTrait := rgb(167,221,245); // Couleur des traits par défaut
- fCoulTraitFin := rgb(161,226,250);
- fCoulChiffres := rgb(0,4,246);
- fCoulRetenues := clRed ;
- FTypeOperation := ATypeOperation;
- fN1 := AN1;
- fN2 := AN2;
- fListeEtapes := TList.Create;
- fSLNombres:=TStringList.Create;
- fSLNombres.Clear;
- fCanvas := ACanvas;
- PrepareOperation;
- AfficheOperation;
- end;
- Procedure TOperation.RAZ;
- var
- i: Integer;
- begin
- fSLNombres.Clear;
- for i := 0 to fListeEtapes.Count - 1 do
- Dispose(PEtape(fListeEtapes[i]));
- end;
- destructor TOperation.Destroy;
- var
- i: Integer;
- begin
- RAZ;
- fListeEtapes.Free;
- inherited Destroy;
- end;
- procedure TOperation.SetTypeOperation(ATypeOperation: TTypeOperation);
- begin
- FTypeOperation := ATypeOperation;
- end;
- function TOperation.GetTypeOperation: TTypeOperation;
- begin
- Result := FTypeOperation;
- end;
- procedure TOperation.SetN1(Value: Currency);
- begin
- fN1 := Value;
- end;
- function TOperation.GetN1: Currency;
- begin
- Result := fN1;
- end;
- procedure TOperation.SetN2(Value: Currency);
- begin
- fN2 := Value;
- end;
- function TOperation.GetN2: Currency;
- begin
- Result := fN2;
- end;
- procedure TOperation.PrepareOperation;
- begin
- RAZ;
- case FTypeOperation of
- OPaddition, OPsoustraction:
- begin
- PrepareAddSous(FTypeOperation);
- end;
- OPmultiplication:
- begin
- // Code pour préparer la multiplication
- end;
- OPdivision:
- begin
- // Code pour préparer la division
- end;
- end;
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment