NivekR
Messages postés87Date d'inscriptionmercredi 1 octobre 2008StatutMembreDernière intervention28 avril 2009
-
9 avril 2009 à 20:53
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 2016
-
10 avril 2009 à 17:27
Bonsoir à tous et à toute,
Voilà, je suis en 1ère année de DEUST Informatique à Orsay et je dois créer une application (celle que l'on veut) avec DELPHI.
Je me suis donc lancé dans la création d'un programme regroupant plusieurs jeux de hasard.
Pour le moment je planche sur le 421 et le poker.
Pour commencer, je suis sous VISTA Pro et je programme sous DELPHI 6.
Et voilà mes deux soucis du moment :
- Pour le 421, la commande 'random()', me donne bien des nombres aléatoires dans l'intervalle que je veux, mais toujours dans un même ordre.
Je m'explique, je clique sur le bouton 'Lancé n°1', il me sort 3 chiffres au hasard, je quitte l'application, je reviens et je clique de nouveau sur le bouton, et les 3 mêmes chiffres réapparaissent. Et cela à chaque fois...
En gros, ce sont les même séries de chiffres qui se suivent dans un même ordre.
Comment éviter cela???
C'est le seul soucis que j'ai sur ce jeu
- Pour le poker, c'est plus délicat (enfin je crois)
Comment peut-on éviter les doublons?
Je m'explique, dans un jeu de carte il n'y a pas 2 cartes ayant même valeur ET même couleur mais la commande 'random()' s'en fiche...
Comment éviter cela?
N'hésitez pas à me poser des questions pour de plus amples informations.
Je vous remercie d'avance.
Bonne soirée.
Cordialement,
Kevin.
PS : Si vous ne voyez pas trop de quoi je parle, je peux vous envoyer l'exécutable pour que vous fassiez le test.
Si vous désirez voir les lignes de commande, je ne peux le faire sur le forum car il y a beaucoup de lignes :S (En comptant toutes les lignes, j'en ai 275
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 9 avril 2009 à 21:27
Utilise randomize dans le OnCreate de ta fiche pour initialiser le générateur de nombres aléatoires. Et tu verras ça marchera directement beaucoup plus aléatoirement :)
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 9 avril 2009 à 21:31
Et pour ta seconde question, il faudra utiliser un tri sélectif :
1. Tu fais une liste d'éléments contenant toutes les cartes du jeu.
2. Tu en tires une au hasard dans la liste.
3. Tu la retire de la liste (on ne la tirera plus).
4. Recommencer à partir de l'étape 2 jusqu'à la fin de la liste.
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 9 avril 2009 à 21:40
Ben tu peux par exemple utiliser une TList (et à la place des pointeurs, mettre des nombres, utiliser la fonction Ptr pour convertir en pointeur), puis quand tu veux supprimer un élément de la liste du fais List.Delete(Index), puis List.Pack pour supprimer les nils. List.Count donne le nombre d'éléments, donc pour boucler sur la liste, for I := 0 to List.Count - 1 do ...
Cordialement, Bacterius !
Vous n’avez pas trouvé la réponse que vous recherchez ?
procedure TSecondJeu.Tirage2Click(Sender: TObject);
begin
Valeur[0]:='As';
Valeur[1]:='Deux';
Valeur[2]:='Trois';
Valeur[3]:='Quatre';
Valeur[4]:='Cinq';
Valeur[5]:='Six';
Valeur[6]:='Sept';
Valeur[7]:='Huit';
Valeur[8]:='Neuf';
Valeur[9]:='Dix';
Valeur[10]:='Valet';
Valeur[11]:='Dame';
Valeur[12]:='Roi';
if Garder1.Checked=true
then edVal1.Enabled:=false
else edVal1.Text:=Valeur[random(13)];
if Garder2.Checked=true
then edVal2.Enabled:=false
else edVal2.Text:=Valeur[random(13)];
if Garder3.Checked=true
then edVal3.Enabled:=false
else edVal3.Text:=Valeur[random(13)];
if Garder4.Checked=true
then edVal4.Enabled:=false
else edVal4.Text:=Valeur[random(13)];
if Garder5.Checked=true
then edVal5.Enabled:=false
else edVal5.Text:=Valeur[random(13)];
Couleur[0]:='Coeur';
Couleur[1]:='Carreau';
Couleur[2]:='Trèfle';
Couleur[3]:='Pique';
if Garder1.Checked=true
then edCoul1.Enabled:=false
else edCoul1.Text:=Couleur[random(4)];
if Garder2.Checked=true
then edCoul2.Enabled:=false
else edCoul2.Text:=Couleur[random(4)];
if Garder3.Checked=true
then edCoul3.Enabled:=false
else edCoul3.Text:=Couleur[random(4)];
if Garder4.Checked=true
then edCoul4.Enabled:=false
else edCoul4.Text:=Couleur[random(4)];
if Garder5.Checked=true
then edCoul5.Enabled:=false
else edCoul5.Text:=Couleur[random(4)];
Tirage2.Enabled:=false;
end;"
Le 2nd, avec un seul :
Seul une carte est tirée, mais la suite du code ressemblera au premier :)
"var
Form1: TForm1;
Carte : Array [0..51] of String;
procedure TForm1.Button1Click(Sender: TObject);
begin
Carte[0]:='As de Carreau';
Carte[1]:='Deux de Carreau';
Carte[2]:='Trois de Carreau';
Carte[3]:='Quatre de Carreau';
Carte[4]:='Cinq de Carreau';
Carte[5]:='Six de Carreau';
Carte[6]:='Sept de Carreau';
Carte[7]:='Huit de Carreau';
Carte[8]:='Neuf de Carreau';
Carte[9]:='Dix de Carreau';
Carte[10]:='Valet de Carreau';
Carte[11]:='Dame de Carreau';
Carte[12]:='Roi de Carreau';
Carte[13]:='As de Coeur';
Carte[14]:='Deux de Coeur';
Carte[15]:='Trois de Coeur';
Carte[16]:='Quatre de Coeur';
Carte[17]:='Cinq Coeur';
Carte[18]:='Six de Coeur';
Carte[19]:='Sept de Coeur';
Carte[20]:='Huit de Coeur';
Carte[21]:='Neuf de Coeur';
Carte[22]:='Dix de Coeur';
Carte[23]:='Valet de Coeur';
Carte[24]:='Dame de Coeur';
Carte[25]:='Roi de Coeur';
Carte[26]:='As de Pique';
Carte[27]:='Deux de Pique';
Carte[28]:='Trois de Pique';
Carte[29]:='Quatre de Pique';
Carte[30]:='Cinq de Pique';
Carte[31]:='Six de Pique';
Carte[32]:='Sept de Pique';
Carte[33]:='Huit de Pique';
Carte[34]:='Neuf de Pique';
Carte[35]:='Dix de Pique';
Carte[36]:='Valet de Pique';
Carte[37]:='Dame de Pique';
Carte[38]:='Roi de Pique';
Carte[39]:='As de Trefle';
Carte[40]:='Deux de Trefle';
Carte[41]:='Trois de Trefle';
Carte[42]:='Quatre de Trefle';
Carte[43]:='Cinq de Trefle';
Carte[44]:='Six de Trefle';
Carte[45]:='Sept de Trefle';
Carte[46]:='Huit de Trefle';
Carte[47]:='Neuf de Trefle';
Carte[48]:='Dix de Trefle';
Carte[49]:='Valet de Trefle';
Carte[50]:='Dame de Trefle';
Carte[51]:='Roi de Trefle';
Edit1.Text:=Carte[random(52)];"
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 9 avril 2009 à 21:57
Ben regarde ce que je te propose, moi, une technique que tu pourrais utiliser (pas trop difficile à mettre en oeuvre !) :
procedure Shuffle(List: TList);
Var
I: Integer;
begin
{ Il faut avoir appellé randomize avant ! }
for I := 0 to List.Count - 1 do
List.Exchange(random(List.Count), random(List.Count));
{ On effectue une sorte de mélange ... }
end;
function Tirage(var Position: Integer; List: TList): TCarte;
begin
if Position => List.Count then Exit;
Result := TCarte(List.Items[Position]);
Inc(Position);
end;
Position est une valeur que tu dois initialiser au début.
Et TCarte est enregistré ainsi :
type
TCarte=record
Groupe: Byte; {1 pour trefle, 2 pour carreau, etc ... }
Couleur: Byte; { 1 pour noir, 2 pour rouge par exemple }
Nom: Byte; { 1 pour 1, 2 pour 2, 11 pour valet, 12 pour reine, etc ... }
end;
Le principe ici est de mélanger la liste, puis de tirer les cartes 1 par 1 (en gardant une variable pour se souvenir de la position actuelle du tirage).
Pour nouveau tirage, appeller Shuffle, puis tirer les cartes avec Tirage :)
Dis-moi ce que tu penses de cette méthode ?
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 9 avril 2009 à 22:30
Imagine une liste de nombres (pour l'explication, on ne parlera pas de cartes). Pour obtenir une liste aléatoire, je te propose de mélanger la liste. D'abord, tu remplis ta liste avec des nombres aléatoires, puis tu appelles Shuffle.
Puis, tu remplis une ListBox de tous les nombres de la liste, un par un (ils seront mélangés).
Voilà en fait le principe. Tu as peut-être oublié de remplir la liste avant ?
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 9 avril 2009 à 22:37
Ah non non en fait je parles de la TList (ce n'est pas un composant mais une classe).
Tu fais comme ça (mais il faudra déclarer en local) :
procedure TestList;
var
List: TList;
begin
List := TList.Create;
List.Add(Ptr(7));
ShowMessage(IntToStr(Longword(List.Items[0])));
List.Free;
end;
Ici, on crée la liste, on ajoute le nombre 7 dans le premier élément de la liste, on affiche un message contenant le premier nombre de la liste (normalement 7), puis on libère la liste.
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202237 10 avril 2009 à 02:31
voici comment utiliser random :
aprés avoir initialisé Randomise dans le create de la fiche ou l'initialization de l'unité,
il faut utiliser un comme comme ceci :
var
OldRandom : integer;
function UnicRand(const R: integer): integer;
begin
Result := Random(R);
while Result = OldRandom do
Result := Random(R);
end;
pour les boolean dans les conditions il n'est pas necessaire de faire ceci :
if Booleen = true then
ou
if Booleen = false then
mais faire :
if Booleen then
et
if not Booleen then
pour les tableaux tu peux les initialiser dans la declaration (const ou var) :
var
Couleur : array[0..3] of string = ('pic', 'coeur', 'trefle', 'carreau');
pour ensuite appeler un valeur aleatoirement choisie de ce tableau fait :
V := Couleur[ UnicRandom( Length(Couleur) ) ];
Length(couleur) renverra 4, qui est le nombre d'element dans le tableau (de 0 a 3)
Random renvoyant des nombres entre 0 et X-1 nous aurons bien les chiffres aleatoire de 0 a 3 a chaque fois.
de plus, il n'y aura jamais deux couleur identique a la suite grace a la fonction UnicRandom.
donc impossible de tomber sur une suite : 0 2 0 3 3 0 2 0 1 1 1 3 0 1
JulioDelphi
Messages postés2226Date d'inscriptiondimanche 5 octobre 2003StatutMembreDernière intervention18 novembre 201014 10 avril 2009 à 08:00
Je ne suis pas d'accord avec ton random pour lancer un dé ni tirer une carte :
1) Tu peux lancer 2/3/4... dés et faire 2 fois de suite le même chiffre, c'est normal et largement possible.
2) Si il n'utilise que ce random pour tirer des cartes, si il en tire au moins 3, il peut se retrouver avec 2 cartes identiques
ps : je parle de ce random :
var
OldRandom : integer;
function UnicRand(const R: integer): integer;
begin
Result := Random(R);
while Result = OldRandom do
Result := Random(R);
end;
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 10 avril 2009 à 14:40
Moi je trouve que ma solution est pas trop mal, mélanger les cartes et les tirer 1 par 1. C'est comme ça qu'on fait au poker et si on a pas changé c'est que ça marche ?
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 10 avril 2009 à 16:13
Salut,
Pour un tirage aléatoire sans doublon, je fais comme ça :
{Cette procédure mélange aléatoirement n'importe quel
tableau. Ici, ce sont des chaînes, mais la procedure
serait la même pour un tableau de n'importe quel autre Type.
Il suffirait de changer « var Tab : array of MonType »}
procedure GetRandomArray(var Tab : array of string);
var RandomIndex, LastIndex : Integer;
TempVal : Variant;
begin
LastIndex := length(Tab);
while LastIndex>1 do begin
RandomIndex := Random(LastIndex);
TempVal := Tab[RandomIndex];
Tab[RandomIndex] := Tab[LastIndex-1];
Tab[LastIndex-1] := TempVal;
Dec(LastIndex);
end;
end;
{Exemple d'utilisation.}
procedure TForm1.Button1Click(Sender: TObject);
var i : Integer;
Tab : array of String;
begin
SetLength(Tab, 5);
for i := 0 to High(Tab) do Tab[i] := IntToStr(i);// -->[0,1,2,3,4]
GetRandomArray(Tab); //-->[1,3,2,4,0], par exemple.
for i := 0 to High(Tab) do Memo1.Lines.Add(Tab[i]);//Vérification.
end;
On pourrait ainsi mélanger aléatoirement sans doublon n'importe quel type, pas forcément ordinal.
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 10 avril 2009 à 16:19
Tiens?!
On dirait que ça beugue...
Nouvel essai:
{Cette procédure mélange aléatoirement n'importe quel
tableau. Ici, ce sont des chaînes, mais la procedure
serait la même pour un tableau de n'importe quel autre Type.
Il suffirait de changer « var Tab : array of MonType »}
procedure GetRandomArray(var Tab : array of string);
var RandomIndex, LastIndex : Integer;
TempVal : Variant;
begin
LastIndex := length(Tab);
while LastIndex>1 do begin
RandomIndex := Random(LastIndex);
TempVal := Tab[RandomIndex];
Tab[RandomIndex] := Tab[LastIndex-1];
Tab[LastIndex-1] := TempVal;
Dec(LastIndex);
end;
end;
{Exemple d'utilisation.}
procedure TForm1.Button2Click(Sender: TObject);
var i : Integer;
Tab : array of String;
begin
//Randomize;
SetLength(Tab, 5);
for i := 0 to High(Tab) do Tab[i] := IntToStr(i);// -->[0,1,2,3,4]
GetRandomArray(Tab); //-->[1,3,2,4,0], par exemple.
for i := 0 to High(Tab) do Memo1.Lines.Add(Tab[i]);//Vérification.
end;
On pourrait mélanger aléatoirement sans doublon n'importe quel type, pas forcément ordinal.
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 10 avril 2009 à 16:26
Oh c'est l'idée que je proposais il y a 5 posts dites-donc ! Mélanger le tableau puis tirer comme d'habitude (0 .. Count - 1) ...
Parfois j'ai l'impression que mon avatar n'est pas assez visible ... ^^