SUDOKU

tigris1 Messages postés 57 Date d'inscription dimanche 27 mars 2005 Statut Membre Dernière intervention 15 janvier 2009 - 11 sept. 2006 à 14:47
belthebut Messages postés 7 Date d'inscription vendredi 25 février 2005 Statut Membre Dernière intervention 20 septembre 2006 - 20 sept. 2006 à 11:27
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/39515-sudoku

belthebut Messages postés 7 Date d'inscription vendredi 25 février 2005 Statut Membre Dernière intervention 20 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...
Utilisateur anonyme
18 sept. 2006 à 17:17
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és 7 Date d'inscription vendredi 25 février 2005 Statut Membre Dernière intervention 20 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és 7 Date d'inscription vendredi 25 février 2005 Statut Membre Dernière intervention 20 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és 57 Date d'inscription dimanche 27 mars 2005 Statut Membre Dernière intervention 15 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és 7 Date d'inscription vendredi 25 février 2005 Statut Membre Dernière intervention 20 septembre 2006
14 sept. 2006 à 11:04
merci à tigris et à nono...
belthebut Messages postés 7 Date d'inscription vendredi 25 février 2005 Statut Membre Dernière intervention 20 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és 57 Date d'inscription dimanche 27 mars 2005 Statut Membre Dernière intervention 15 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és 17 Date d'inscription mercredi 24 avril 2002 Statut Membre Derniè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és 57 Date d'inscription dimanche 27 mars 2005 Statut Membre Dernière intervention 15 janvier 2009
12 sept. 2006 à 09:09
Hello Nono40!

Très bien vu! Merci pour la rectification.

Amicalement tigris1
cs_Nono40 Messages postés 962 Date d'inscription mercredi 3 avril 2002 Statut Membre Dernière intervention 12 septembre 2006 2
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és 57 Date d'inscription dimanche 27 mars 2005 Statut Membre Dernière intervention 15 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és 7 Date d'inscription vendredi 25 février 2005 Statut Membre Dernière intervention 20 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és 57 Date d'inscription dimanche 27 mars 2005 Statut Membre Dernière intervention 15 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és 7 Date d'inscription vendredi 25 février 2005 Statut Membre Dernière intervention 20 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és 57 Date d'inscription dimanche 27 mars 2005 Statut Membre Dernière intervention 15 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és 57 Date d'inscription dimanche 27 mars 2005 Statut Membre Dernière intervention 15 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;

Amicalement tigris1
Rejoignez-nous