belthebut
Messages postés7Date d'inscriptionvendredi 25 février 2005StatutMembreDernière intervention20 septembre 2006 20 sept. 2006 à 11:27
hey!!! H60
Il y avait un bug ke G remodifier....
il faut juste initialiser nCount := 1 au lieu de := 0
tu vera la sa marchera mais je V rebalancer mon source....
Je croyai l'avoir déjà fait...
Salut
je viens de compiler et lancer ton programme. Première grille pour débutant pour voir je tombe sur une boucle infinie. Je n'ai pas eu le temps de regarder ton code.
belthebut
Messages postés7Date d'inscriptionvendredi 25 février 2005StatutMembreDernière intervention20 septembre 2006 15 sept. 2006 à 18:33
=> tigris
ton code peut-être optimisé...
un truc tt simple:
function testval(cordx : integer ; cordy : integer ; nbr : integer) : integer;
var
i, j : integer;
begin
Result := 1;
// Test sur la ligne et la colonne
for i := 1 to 9 do begin
if (grille[i, cordy] = nbr) // Test sur la ligne
or (grille[cordx, i] = nbr) then begin // Test sur la colonne
Result := 2;
Exit;
end;
end;
// Test dans le pavé de 3x3 cases
for i := ((cordx-1) div 3*3)+1 to ((cordx-1) div 3*3)+3 do
for j :=((cordy-1) div 3*3)+1 to ((cordy-1) div 3*3)+3 do
begin
if (grille[i, j] = nbr) then
begin
Result := 2;
Exit;
end;
end;
end;
le begin de la première boucle FOR peut être suprimé... C rien de bien grave mais C juste pour le signaler
et merci encore...
belthebut
Messages postés7Date d'inscriptionvendredi 25 février 2005StatutMembreDernière intervention20 septembre 2006 15 sept. 2006 à 14:10
merci tigris je V y réfléchir mais hier soir sa ma pris jusqu'à 1 h du mat G commencé un faire (dans la même interface) un resolveur de grille.... une fois fini et expliké je la remettrai sur CS...
j'avai pensé à ta méthode mais je voulai pas me prendre la tête avec des boucle alors G fait fait en sorte ke sa test tt d'un coup...
Comme je te l'avai dit je sui pas un pro, j'essaye juste de bricolé un peu... Mais merci quand C fort interressant...
@ biantot pour la mise à jour de mon log... lol
;-)
666
tigris1
Messages postés57Date d'inscriptiondimanche 27 mars 2005StatutMembreDernière intervention15 janvier 2009 14 sept. 2006 à 17:35
Hello belthebut!
Félicitations! le code est beaucoup plus léger et un grand merci pour les commentaires. Je vais me pencher sur la création de la grille car j'ai fait un bout de programme qui résoud les grilles. Je commence par tester s'il existe une solution unique. Si ce n'est pas le cas, j'utilise la méthode BruteForce qui appelle mes routines pour tester une solution unique, si pas de possibilité, je reviens sur mes pas, j'essaie une autre valeur, etc...
Cela fonctionne bien mais j'ai l'intation de faire un programme complet et il faut que je me penche sur la création avec des niveaux de difficulté, plus d'autres idées, mais ce sera pour un peu plus tard.
Je sais, je vais passé pour un pénible, mais je te propose une nouvelle simplification pour la fonction testval et mon code se trouve ci-dessous:
function testval(cordx : integer ; cordy : integer ; nbr : integer) : integer;
var
i, j : integer;
begin
Result := 1;
// Test sur la ligne et la colonne
for i := 1 to 9 do begin
if (grille[i, cordy] = nbr) // Test sur la ligne
or (grille[cordx, i] = nbr) then begin // Test sur la colonne
Result := 2;
Exit;
end;
end;
// Test dans le pavé de 3x3 cases
for i := ((cordx-1) div 3*3)+1 to ((cordx-1) div 3*3)+3 do begin
for j :=((cordy-1) div 3*3)+1 to ((cordy-1) div 3*3)+3 do begin
if (grille[i, j] = nbr) then begin
Result := 2;
Exit;
end;
end;
end;
end;
Il est aussi possible de retourner un boolean mais il te faudra modifier Button2Click
Amicalement tigris1
belthebut
Messages postés7Date d'inscriptionvendredi 25 février 2005StatutMembreDernière intervention20 septembre 2006 14 sept. 2006 à 11:04
merci à tigris et à nono...
belthebut
Messages postés7Date d'inscriptionvendredi 25 février 2005StatutMembreDernière intervention20 septembre 2006 12 sept. 2006 à 15:04
merci les gars !!!
J'V pouvoir optimiser mon prog !!!
mais sa a pas été bien long C T rempli de copier/coller...
et pour les fonctions je faisai ça comme ça m'venai au plus simple...
mais J'V l'expliké plus en détail et je balance ça sur CS.
tigris1
Messages postés57Date d'inscriptiondimanche 27 mars 2005StatutMembreDernière intervention15 janvier 2009 12 sept. 2006 à 14:28
Hello kannibal!
La propriété Tag stocke une valeur entière. Peux-tu m'indiquer comment l'utiliser pour le code concerné?
Merci
kannibal
Messages postés17Date d'inscriptionmercredi 24 avril 2002StatutMembreDernière intervention 6 février 2007 12 sept. 2006 à 13:56
Pourquoi ne pas utiliser la propriété TAG du composant TEdit?
tigris1
Messages postés57Date d'inscriptiondimanche 27 mars 2005StatutMembreDernière intervention15 janvier 2009 12 sept. 2006 à 09:09
Hello Nono40!
Très bien vu! Merci pour la rectification.
Amicalement tigris1
cs_Nono40
Messages postés962Date d'inscriptionmercredi 3 avril 2002StatutMembreDernière intervention12 septembre 20062 12 sept. 2006 à 03:31
=> Tigris1.
Ton approche est bonne mais la solution imparfaite.
Le (1) est inutile voire dangereux, car le TEdit que tu crées ne sera pas celui que tu vas détruire. Vu que ta variable Edit va contenir le dernier TEdit sélectionné par ta ligne Edit := TEdit(FindComponent('Edit' + IntToStr(nCount)));
Edit n'a nullement besoin d'être instancié avant l'appel de FindComponent. Il suffit juste de vérifier (comme tu le soulignes) le <> de nil avant de l'utiliser.
tigris1
Messages postés57Date d'inscriptiondimanche 27 mars 2005StatutMembreDernière intervention15 janvier 2009 11 sept. 2006 à 23:03
Hello belthebut!
On remarque que le code suivant est écrit 81 fois dans ton programme (sans les numéros du nom des composants)
Edit.ReadOnly := false;
Edit.Font.Color := clblack;
if (gry_aff[i, j] = true) then begin
Edit.Text := inttostr(grille[i, j]);
Edit.ReadOnly := true;
Edit.Font.Color := clred;
end;
La seule différence est que tu identifie chaque composant par son nom, avec une numérotation (puisqu'il y 81 TEdit dans ton interface).
Pour simplifier:
1 - J'ai défini un TEdit local pour la fonction concernée. Je fais un Create au début pour l'instancier et un Free à la fin pour le détruire.
2 - Je boucle sur la grille du jeu à l'aide des 2 boucles imbriquées. A l'intérieur de ces 2 boucles je fais un incrément d'un compteur (nCount) qui va prendre les valeurs de 1 à 81 (9 x 9)
3 - Je compose le nom du composant : 'Edit' + IntToStr(nCount) (de Edit1 à Edit81)
4 - Je cherche le composant correspondant à ce nom dans la Form à l'aide de la function FindComponent (qui est un membre de TForm)
5 - J'affecte le composant retourné par FindComponent au composant Edit local en en indiquant le type de composant retourné par FindComponent : Edit := TEdit(FindComponent('Edit' + IntToStr(nCount)));
6 - Je teste l'existence du composant (if Edit <> nil then begin) avant d'exécuter le reste du code, pour le cas ou un composant viendrait à manquer (erreur lors de la définition de l'interface, par exemple).
Cette approche peut être faite dans plusieurs endroit de ton programme. De plus FindComponent peut retourner tous les type de composants d'une Form.
Il y a d'autres améliorations possibles mais j'en citerai qu'une : dans la fonction testval il me semble qu'il s'agit des tests pour les zones 3x3 cases et pour la ligne et pour la colonne. Il est possible de simplifier le code par des boucles. Mais là je pense que la simplification doit être plus facilement accessible.
Pour améliorer ton aisance dans l'utilisation de Delphi tu devrais essayer d'optimiser le code de ton programme. Il n'en sera que plus lisible et plus facile à comprendre pour les autres.
J'espère avoir répondu et expliqué mon petit bout de code.
Amicalement tigris1
belthebut
Messages postés7Date d'inscriptionvendredi 25 février 2005StatutMembreDernière intervention20 septembre 2006 11 sept. 2006 à 21:42
hey tigris1
OK je vé rajouté quelque explications en plus et je rechengerai sur CS...
mais je tien à dire qd mêm que ça fait pas longtemp que je fait du delphi, environ 2 ans...
et je connai pas encore tt d'ailleur G pas trop compris le petit bout de prog que tu ma exélament sugéré.
mon gros problème étai justement de gérer les différente cases sans à chak fois reprendre leur nom...
si tu peut me donnée plus d'explication dessus j'en serai ravi...
à+
tigris1
Messages postés57Date d'inscriptiondimanche 27 mars 2005StatutMembreDernière intervention15 janvier 2009 11 sept. 2006 à 19:09
Hello belthebut!
Très sérieusement, je pense que j'ai écrit plus rapidement ma vingtaine de lignes que tes 800 lignes quelles remplacent. De même pour écrire correctement la plupart de tes fonctions ou procédures, pour remplacer des cases interminables par des boucles, etc... De plus, dans les parties intéressantes du code, pas de commentaires !!!
Je pense qu'un site comme celui-ci est là pour montrer des choses un peu abouties quand même pour que d'autres puissent en profiter.
Le code écrite par un programmeur est une image de celui-ci....
Amicalement tigris1
belthebut
Messages postés7Date d'inscriptionvendredi 25 février 2005StatutMembreDernière intervention20 septembre 2006 11 sept. 2006 à 18:31
merci tigris
C clair que c'est plus cour.... lol
mais je les fait assez rapidement...
tigris1
Messages postés57Date d'inscriptiondimanche 27 mars 2005StatutMembreDernière intervention15 janvier 2009 11 sept. 2006 à 14:53
Hello belthebut!
Mille excuses!!! J'ai oublié d'abord de te féliciter pour les choses intéressantes de ton code et quelques idées nouvelles (chaque SuDoku posté sur ce site a son lot d'originalités). Peut-être que cela me donne envie de faire le mien, à l'occasion.
Amicalement tigris1
tigris1
Messages postés57Date d'inscriptiondimanche 27 mars 2005StatutMembreDernière intervention15 janvier 2009 11 sept. 2006 à 14:47
Hello belthebut!
Il me semble qu'il peut y avoir beaucoup de possibilités d'optimisation du code et une grande différence d'écriture entre le code de l'algorithme du jeu et le code de l'interface.
Comme exemple de ces améliorations, les plus de 800 lignes de la procédure config.grille peuvent être remplacées par le code ci-dessous d'une vingtaine de lignes (j'espère que l'éditeur du site ne colle pas le code tout à gauche!).
procedure Tform1.config_grille;
var
i, j : integer;
nCount : integer;
Edit : TEdit;
begin
Edit := TEdit.Create(Self);
nCount := 0;
for i := 1 to 9 do begin
for j := 1 to 9 do begin
//------- Pour récupérer le composant à partir de son nom
inc (nCount);
Edit := TEdit(FindComponent('Edit' + IntToStr(nCount)));
if Edit <> nil then begin
//------
Edit.ReadOnly := false;
Edit.Font.Color := clblack;
if (gry_aff[i, j] = true) then begin
Edit.Text := inttostr(grille[i, j]);
Edit.ReadOnly := true;
Edit.Font.Color := clred;
end;
end;
end;
end;
Edit.Free;
end;
20 sept. 2006 à 11:27
Il y avait un bug ke G remodifier....
il faut juste initialiser nCount := 1 au lieu de := 0
tu vera la sa marchera mais je V rebalancer mon source....
Je croyai l'avoir déjà fait...
18 sept. 2006 à 17:17
je viens de compiler et lancer ton programme. Première grille pour débutant pour voir je tombe sur une boucle infinie. Je n'ai pas eu le temps de regarder ton code.
15 sept. 2006 à 18:33
ton code peut-être optimisé...
un truc tt simple:
function testval(cordx : integer ; cordy : integer ; nbr : integer) : integer;
var
i, j : integer;
begin
Result := 1;
// Test sur la ligne et la colonne
for i := 1 to 9 do begin
if (grille[i, cordy] = nbr) // Test sur la ligne
or (grille[cordx, i] = nbr) then begin // Test sur la colonne
Result := 2;
Exit;
end;
end;
// Test dans le pavé de 3x3 cases
for i := ((cordx-1) div 3*3)+1 to ((cordx-1) div 3*3)+3 do
for j :=((cordy-1) div 3*3)+1 to ((cordy-1) div 3*3)+3 do
begin
if (grille[i, j] = nbr) then
begin
Result := 2;
Exit;
end;
end;
end;
le begin de la première boucle FOR peut être suprimé... C rien de bien grave mais C juste pour le signaler
et merci encore...
15 sept. 2006 à 14:10
j'avai pensé à ta méthode mais je voulai pas me prendre la tête avec des boucle alors G fait fait en sorte ke sa test tt d'un coup...
Comme je te l'avai dit je sui pas un pro, j'essaye juste de bricolé un peu... Mais merci quand C fort interressant...
@ biantot pour la mise à jour de mon log... lol
;-)
666
14 sept. 2006 à 17:35
Félicitations! le code est beaucoup plus léger et un grand merci pour les commentaires. Je vais me pencher sur la création de la grille car j'ai fait un bout de programme qui résoud les grilles. Je commence par tester s'il existe une solution unique. Si ce n'est pas le cas, j'utilise la méthode BruteForce qui appelle mes routines pour tester une solution unique, si pas de possibilité, je reviens sur mes pas, j'essaie une autre valeur, etc...
Cela fonctionne bien mais j'ai l'intation de faire un programme complet et il faut que je me penche sur la création avec des niveaux de difficulté, plus d'autres idées, mais ce sera pour un peu plus tard.
Je sais, je vais passé pour un pénible, mais je te propose une nouvelle simplification pour la fonction testval et mon code se trouve ci-dessous:
function testval(cordx : integer ; cordy : integer ; nbr : integer) : integer;
var
i, j : integer;
begin
Result := 1;
// Test sur la ligne et la colonne
for i := 1 to 9 do begin
if (grille[i, cordy] = nbr) // Test sur la ligne
or (grille[cordx, i] = nbr) then begin // Test sur la colonne
Result := 2;
Exit;
end;
end;
// Test dans le pavé de 3x3 cases
for i := ((cordx-1) div 3*3)+1 to ((cordx-1) div 3*3)+3 do begin
for j :=((cordy-1) div 3*3)+1 to ((cordy-1) div 3*3)+3 do begin
if (grille[i, j] = nbr) then begin
Result := 2;
Exit;
end;
end;
end;
end;
Il est aussi possible de retourner un boolean mais il te faudra modifier Button2Click
Amicalement tigris1
14 sept. 2006 à 11:04
12 sept. 2006 à 15:04
J'V pouvoir optimiser mon prog !!!
mais sa a pas été bien long C T rempli de copier/coller...
et pour les fonctions je faisai ça comme ça m'venai au plus simple...
mais J'V l'expliké plus en détail et je balance ça sur CS.
12 sept. 2006 à 14:28
La propriété Tag stocke une valeur entière. Peux-tu m'indiquer comment l'utiliser pour le code concerné?
Merci
12 sept. 2006 à 13:56
12 sept. 2006 à 09:09
Très bien vu! Merci pour la rectification.
Amicalement tigris1
12 sept. 2006 à 03:31
Ton approche est bonne mais la solution imparfaite.
Le (1) est inutile voire dangereux, car le TEdit que tu crées ne sera pas celui que tu vas détruire. Vu que ta variable Edit va contenir le dernier TEdit sélectionné par ta ligne Edit := TEdit(FindComponent('Edit' + IntToStr(nCount)));
Edit n'a nullement besoin d'être instancié avant l'appel de FindComponent. Il suffit juste de vérifier (comme tu le soulignes) le <> de nil avant de l'utiliser.
11 sept. 2006 à 23:03
On remarque que le code suivant est écrit 81 fois dans ton programme (sans les numéros du nom des composants)
Edit.ReadOnly := false;
Edit.Font.Color := clblack;
if (gry_aff[i, j] = true) then begin
Edit.Text := inttostr(grille[i, j]);
Edit.ReadOnly := true;
Edit.Font.Color := clred;
end;
La seule différence est que tu identifie chaque composant par son nom, avec une numérotation (puisqu'il y 81 TEdit dans ton interface).
Pour simplifier:
1 - J'ai défini un TEdit local pour la fonction concernée. Je fais un Create au début pour l'instancier et un Free à la fin pour le détruire.
2 - Je boucle sur la grille du jeu à l'aide des 2 boucles imbriquées. A l'intérieur de ces 2 boucles je fais un incrément d'un compteur (nCount) qui va prendre les valeurs de 1 à 81 (9 x 9)
3 - Je compose le nom du composant : 'Edit' + IntToStr(nCount) (de Edit1 à Edit81)
4 - Je cherche le composant correspondant à ce nom dans la Form à l'aide de la function FindComponent (qui est un membre de TForm)
5 - J'affecte le composant retourné par FindComponent au composant Edit local en en indiquant le type de composant retourné par FindComponent : Edit := TEdit(FindComponent('Edit' + IntToStr(nCount)));
6 - Je teste l'existence du composant (if Edit <> nil then begin) avant d'exécuter le reste du code, pour le cas ou un composant viendrait à manquer (erreur lors de la définition de l'interface, par exemple).
Cette approche peut être faite dans plusieurs endroit de ton programme. De plus FindComponent peut retourner tous les type de composants d'une Form.
Il y a d'autres améliorations possibles mais j'en citerai qu'une : dans la fonction testval il me semble qu'il s'agit des tests pour les zones 3x3 cases et pour la ligne et pour la colonne. Il est possible de simplifier le code par des boucles. Mais là je pense que la simplification doit être plus facilement accessible.
Pour améliorer ton aisance dans l'utilisation de Delphi tu devrais essayer d'optimiser le code de ton programme. Il n'en sera que plus lisible et plus facile à comprendre pour les autres.
J'espère avoir répondu et expliqué mon petit bout de code.
Amicalement tigris1
11 sept. 2006 à 21:42
OK je vé rajouté quelque explications en plus et je rechengerai sur CS...
mais je tien à dire qd mêm que ça fait pas longtemp que je fait du delphi, environ 2 ans...
et je connai pas encore tt d'ailleur G pas trop compris le petit bout de prog que tu ma exélament sugéré.
mon gros problème étai justement de gérer les différente cases sans à chak fois reprendre leur nom...
si tu peut me donnée plus d'explication dessus j'en serai ravi...
à+
11 sept. 2006 à 19:09
Très sérieusement, je pense que j'ai écrit plus rapidement ma vingtaine de lignes que tes 800 lignes quelles remplacent. De même pour écrire correctement la plupart de tes fonctions ou procédures, pour remplacer des cases interminables par des boucles, etc... De plus, dans les parties intéressantes du code, pas de commentaires !!!
Je pense qu'un site comme celui-ci est là pour montrer des choses un peu abouties quand même pour que d'autres puissent en profiter.
Le code écrite par un programmeur est une image de celui-ci....
Amicalement tigris1
11 sept. 2006 à 18:31
C clair que c'est plus cour.... lol
mais je les fait assez rapidement...
11 sept. 2006 à 14:53
Mille excuses!!! J'ai oublié d'abord de te féliciter pour les choses intéressantes de ton code et quelques idées nouvelles (chaque SuDoku posté sur ce site a son lot d'originalités). Peut-être que cela me donne envie de faire le mien, à l'occasion.
Amicalement tigris1
11 sept. 2006 à 14:47
Il me semble qu'il peut y avoir beaucoup de possibilités d'optimisation du code et une grande différence d'écriture entre le code de l'algorithme du jeu et le code de l'interface.
Comme exemple de ces améliorations, les plus de 800 lignes de la procédure config.grille peuvent être remplacées par le code ci-dessous d'une vingtaine de lignes (j'espère que l'éditeur du site ne colle pas le code tout à gauche!).
procedure Tform1.config_grille;
var
i, j : integer;
nCount : integer;
Edit : TEdit;
begin
Edit := TEdit.Create(Self);
nCount := 0;
for i := 1 to 9 do begin
for j := 1 to 9 do begin
//------- Pour récupérer le composant à partir de son nom
inc (nCount);
Edit := TEdit(FindComponent('Edit' + IntToStr(nCount)));
if Edit <> nil then begin
//------
Edit.ReadOnly := false;
Edit.Font.Color := clblack;
if (gry_aff[i, j] = true) then begin
Edit.Text := inttostr(grille[i, j]);
Edit.ReadOnly := true;
Edit.Font.Color := clred;
end;
end;
end;
end;
Edit.Free;
end;
Amicalement tigris1