Question
Jeux de script d'hiver 2008
- Grégory
- Auteur du sujet
- Hors Ligne
- Membre senior
-
- Messages : 49
- Remerciements reçus 0
j'ai résolu mon problème en utilisant Group-object vu que cette commande permet de compter en même temps que de regrouper
du coup plus besoin de me galérer
j'aurais pu faire plus simple sans passer par une hashtable d'autant plus que je me sers pas de la couleur par la suite mais j'avais envie de tester les hashtable.
du coup je passe par une hashtable pour repasser par un tableau ensuite alors que j'aurais pu passer par le tableau directement
voici donc le code
A vos critiques messieurs !!
[code:1]
$tabcarte = (\"un\",\"deux\",\"trois\",\"quatre\",\"cinq\",\"six\",\"sept\",\"huit\",\"neuf\",\"dix\",\"valet\",\"dame\",\"roi\"«»)
$tabcouleur = (\"coeur\",\"carreau\",\"pique\",\"trèfle\"«»)
clear
$i=0
$tab=@{}
do{
do{
switch($i){
0{$num=\"première\"}
1{$num=\"seconde\"}
2{$num=\"troisième\"}
3{$num=\"quatrième\"}
4{$num=\"cinquième\"}
}
do{
$carte=read-host \"Veuillez entrer le nom de la $num carte \"
$var=$tabcarte|where{$_ -eq $carte}
}
until ($carte -eq $var)
do{
$couleur=read-host \"Veuillez entrer la couleur de la $num carte \"
$var=$tabcouleur|where{$_ -eq $couleur}
}
until ($couleur -eq $var)
$var=$main|where{$_ -eq $carte +\" de \"+ $couleur}
if($var -ne $carte+\" de \"+ $couleur)
{
$main+=@($carte+\" de \" + $couleur)
$nocarte=\"carte\"+$i
$tab.$nocarte=@{nom=$carte;couleur=$couleur}
$i++
$test=$true
}
else
{
write-host \"\"
write-host \"Cette carte a déjà été tirée, veuillez en saisir une autre \" -foregroundcolor \"red\"
write-host \"\"
$test=$false
}
}
until($test -eq $true)
}
until($i -eq 5)
write-host \"\"
write-host \"Composition de votre main :\"
$main
for($I=0;$I -le 5;$I++)
{
$nocarte=\"carte\"+$i
$tab2+=@($tab.$nocarte.nom)
}
write-host \"\"
$tabcount=$tab2|group-object
$tabcount|foreach{
$count=$_.count
$nom=$_.name
switch($count){
2{write-host \"il y a 1 paire de $nom\"}
3{write-host \"il y a 3 paires possibles de $nom\"}
4{write-host \"il y a 6 paires possibles de $nom\"}
}
write-host \"\"
}[/code:1]
EDIT : le 8ème fait dans la foulée
[code:1]clear
$count=0
$rand = New-Object System.Random
$numrand=$rand.next(0,50)
while($test -ne $true){
do{
$nb=read-host \"Entrez votre chiffre \"
}
until ($nb -ge 0 -and $nb -le 50)
$count+=1
if($nb -gt $numrand)
{
write-host \"Votre chiffre est trop grand.\"
}
elseif($nb -lt $numrand)
{
write-host \"Votre chiffre est trop petit.\"
}
else
{
write-host \"\"
write-host \"Gagné !!!\"
$test=$true
}
}
write-host \"\"
write-host \"le nombre était :\" $numrand
write-host \"Nombre d'essai :\"$count [/code:1]<br><br>Message édité par: Nostra, à: 29/10/08 10:35
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
L'affichage des noms de carte et des couleurs n'aurait pas été inutile.
Pour la recherche dans les tableaux la méthode Contains de la classe System.Array optimiserai le traitement.
et ici
[code:1]
$main+=@($carte+\" de \" + $couleur)
[/code:1]
Il y a à mon avis un mélange entre les données et leur présentation...
Et enfin dans ce cas tu peux concaténer les 2 pipelines :
[code:1]
$tabcount=$tab2|group-object
$tabcount|foreach{
[/code:1]
Quant au switch on peut trés bien le regrouper dans une hastable ou un tableau.
C'est ce que j'ai fait.
Cela fait deux fois que je fais cet exercice et les 2 fois ma lecture des specs m'a joué des tours.
Enfin cela fait un exercice sur les structures de données, leur création est facilitée sous PS mais leur manipulation s'avére qq fois malaisé.
Donc voici le code autour d'un tableau de tableau, j'ai mixé un peu toutes les approches :
[code:1]
#Initialisation
#On utilise une valeur entiére comme nom de clé car random renvoi un entier
#On inverse la convention nom-valeur en valeur-nom, cela reste une hashtable ;«»-)
$Couleur=@{1=\"Coeur\";2=\"Pique\";3=\"Trèfle\";4=\"Carreau\"}
$BornesCouleur=@{Min=1;Max=4}
$TypeCarte=@{1=\"Un\";2=\"Deux\";3=\"Trois\";4=\"Quatre\";5=\"Cinq\";6=\"Six\";7=\"Sept\";8=\"Huit\";
9=\"Neuf\";10=\"Dix\";11=\"Valet\";12=\"Dame\";13=\"Roi\";14=\"As\"}
$BornesCarte=@{Min=1;Max=14}
$NbCartes=5
#Générateur aléatoire
$Rnd= New-Object System.Random
function Get-Carte
{ #Renvoi un tableau d'entier composé de 2 éléments générés automatiquement
return [int[]]$A=@(
#Génère le type de la carte
($Rnd.Next($BornesCarte.Min,$BornesCarte.Max)),
#Génère sa couleur
($Rnd.Next($BornesCouleur.Min,$BornesCouleur.Max))
)
}
function Get-Jeux
{ #On redistribue 5 cartes
$global:Jeux=new-object \"Array[]\" $NbCartes
#Jeux est un tableau de tableaux
#Jeux[1 [Carte,Couleur], 2 [Carte,Couleur],...]
#Si on utilise un tableau à 2 dimensions Jeux[5,2], l'énumérateur renvoi les valeurs en
#considérant $Jeux comme étant un tableau à une dimension $Jeux[10].
#Selon le choix de départ( carte,couleur) le nom de la carte est sur un indice pair
# et la couleur sur un indice impair...
#On rempli le tableau de cartes
for ($I=0;$I -lt $NbCartes;$I++)
{
do{
#On tire une nouvelle carte
$Current=Get-Carte
#Jusqu'à ce que la carte courante soit inexistante dans le jeux
} until ( ($global:Jeux -like $Current).Count -eq 0)
#On ajoute la nouvelle carte dans le jeux
$global:Jeux[$I]=$Current
}
}
function AfficheLaMain
{ #On affiche le nom de la carte et le nom de la couleur
# $_ est un tableaux à une dimension contenant 2 éléments [carte,couleur]
$global:Jeux| % {\"{0} de {1}\" -F $TypeCarte.($_[0]),$Couleur.($_[1])}
}
function NouveauJeux
{
Get-Jeux
AfficheLaMain
}
# ---- Main
NouveauJeux
#Affiche le contenu de la main, s'il existe des paires
$global:Jeux|`
# On regroupe sur la première colonne, i.e. le type de carte
group {$_[0]}|`
# On ne prend que les groupes de paires
Where {$_.Count -eq 2}|`
#On construit l'affichage
#Pour chaque groupe :
# Ajoute le nom de la carte ($_.Values)
foreach {
(\"Une paire de {0} : \" -F $TypeCarte.$($_.Values))+
#Ajoute le détail des 2 cartes constituant la paire ( $_.group)
($_.Group|% {\"{0} de {1}\" -F $TypeCarte.($_[0]),$Couleur.($_[1])})
}
[/code:1]
Il reste l'affichage lorsqu'il n'existe aucune carte.
Je copierais ensuite une version autour d'une hastable.
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Grégory
- Auteur du sujet
- Hors Ligne
- Membre senior
-
- Messages : 49
- Remerciements reçus 0
c'est vrai que l'affichage des noms et couleurs aurait pu être utile (ie: un ou as)
j'ai utilisé mon tableau $main pour me simplifier le test pour savoir si la carte a déjà été tiré.
j'étais parti pour faire le test sur la hashtable (et donc supprimer le tableau $main) mais je me suis galéré (et j'ai un peu abandonné devant la complexité il faut avouer
ça marchait de façon bancale, c'est pour ça que j'ai remis $main même si c'était plus lourd et il me sert pour afficher la main facilement au lieu de faire une boucle sur la hashtable
j'ai fait une V2 (mais je vais pas la poster ça prend de la place pour pas grand chose) où j'ai viré la hashtable et remis un second tableau, ça me gagne 7/8 lignes
Concernant ton code :
c'est vraiment très bien pensé ton tirage aléatoire de carte
et ça me donne une très bonne piste pour le Black Jack
Connexion ou Créer un compte pour participer à la conversation.
- Grégory
- Auteur du sujet
- Hors Ligne
- Membre senior
-
- Messages : 49
- Remerciements reçus 0
finalement je ne fais pas comme toi Laurent
(je suis assez fier de moi pour le coup
je crée mon jeu de 52 cartes dans une hashtable :
$jeux.carte0...
$jeux.carte1...
...
$jeux.carte51
puis je fais un random entre 0 et 51
et je sors la carte de la hashtable
Mais (ben oui faut bien un mais)j'ai un problème
je me sers de $histo pour faire un historique des random pour ne pas retirer la même carte
le problème c'est que ça n'a pas l'air de marcher avec une fonction
du coup mon historique est vierge à chaque fois que j'appelle ma fonction ...
une idée pour résoudre ce problème ?
[code:1]
$tabcarte = (\"as\",\"deux\",\"trois\",\"quatre\",\"cinq\",\"six\",\"sept\",\"huit\",\"neuf\",\"dix\",\"valet\",\"dame\",\"roi\"«»)
$tabcouleur = (\"coeur\",\"carreau\",\"pique\",\"trèfle\"«»)
$jeux=@{}
$rand = New-Object System.Random
clear
$I=0
$tabcarte|foreach{
$var=$_
$tabcouleur|foreach{
$nocarte=\"carte\"+$I
switch($var){
\"as\"{$val=11}
\"deux\"{$val=2}
\"trois\"{$val=3}
\"quatre\"{$val=4}
\"cinq\"{$val=5}
\"six\"{$val=6}
\"sept\"{$val=7}
\"huit\"{$val=8}
\"neuf\"{$val=9}
\"dix\"{$val=10}
\"valet\"{$val=10}
\"dame\"{$val=10}
\"roi\"{$val=10}
}
$jeux.$nocarte=@{nom=$var;couleur=$_;valeur=$val}
$I++
}
}
function get-carte{
do{
$var=$histo|where{$_ -eq $numrand}
$numrand=$rand.next(0,51)
if($var -ne $numrand)
{
$nocarte=\"carte\"+$numrand
write-host $jeux.$nocarte.nom \"de\" $jeux.$nocarte.couleur
$histo+=@($numrand)
$histo
$test=$true
}
}until($test -eq $true)
}
write-host \"\"
get-carte
[/code:1]
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
Oui ce n'est pas le plus trivial en PSj'ai utilisé mon tableau $main pour me simplifier le test pour savoir si la carte a déjà été tiré.
Nostra écrit:
Dommage que tu n'aies pas demandé de l'aide sur ce point, puisque tu ne sais pas si c'est vraiment complexe ou si ton approche de départ était erroné, par erreur ou par méconnaissance.mais je me suis galéré (et j'ai un peu abandonné devant la complexité il faut avouer)
C'est aussi ce type d'expérience qui permet d'approfondir un langage. Un exercice comme celui-ci peut se révéler très instructif à cet égard.
Nostra écrit:
Cela peut tjr servir à d'autres.j'ai fait une V2 (mais je vais pas la poster ça prend de la place pour pas grand chose)
Nostra écrit:
Tu as fait le même chose dans le 8ième exercice, dans mon cas la structure de donnée est construite autour du résultat de la fonction random.c'est vraiment très bien pensé ton tirage aléatoire de carte
La version autour d'une hashtable. Les données de bases sont identiques.
Ici je n'ai pas divisé le code en function, la création de la hashtable parait donc plus simple mais on garde la même approche que pour un tableau.
Les noms de carte et de couleurs sont insérés en tant que String et non plus en index des hashtables respectives.
Le code de recherche de doublon est plus long car l'opérateur contains n'est pas possible ici.
voir aussi : pshscripts.blogspot.com/2008/07/contains-hashtableps1.html
En revanche l'usage du type string pour la valeur des clés facilite les opérations d'affichage :
[code:1]
$Couleur=@{1=\"Coeur\";2=\"Pique\";3=\"Trèfle\";4=\"Carreau\"}
$BornesCouleur=@{Min=1;Max=4}
$TypeCarte=@{1=\"Un\";2=\"Deux\";3=\"Trois\";4=\"Quatre\";5=\"Cinq\";6=\"Six\";7=\"Sept\";8=\"Huit\";
9=\"Neuf\";10=\"Dix\";11=\"Valet\";12=\"Dame\";13=\"Roi\";14=\"As\"}
$BornesCarte=@{Min=1;Max=14}
$NbCartes=5
$Rnd = New-Object System.Random
$tab=@{}
#$Tab est une hashtable de hashtable
# $Tab.Carte1.Nom,$Tab.Carte1.Couleur, $Tab.Carte2.Nom ...
for ($I=1;$I -le $NbCartes;$I++)
{
do{
Write-debug \"carte$i\"
$Carte=@{
nom=$TypeCarte.($Rnd.Next($BornesCarte.Min,$BornesCarte.Max));
couleur=$Couleur.($Rnd.Next($BornesCouleur.Min,$BornesCouleur.Max))
}
#$_.Value contient une hastable de type @{Nom=x; Couleur=y}
} until ( ($tab.GetEnumerator() |? {($_.value.nom -eq $carte.nom) -and ($_.value.couleur -eq $carte.Couleur)}|measure).count -eq 0)
$tab.\"carte$i\"=$Carte
}
$tab.GetEnumerator()|Sort name|%{\"{0} de {1}\" -F $_.value.Nom,$_.value.Couleur}
#Affiche le contenu de la main, s'il existe des paires
$tab.GetEnumerator()|`
# On regroupe sur la première colonne, i.e. le type de carte
group {$_.value.Nom}|`
# On ne prend que les groupes de paires
Where {$_.Count -eq 2}|`
#On construit l'affichage
#Pour chaque groupe :
# Ajoute le nom de la carte ($_.Values)
foreach {(\"Une paire de {0} : \" -F $_.Name)+
#Ajoute le détail des 2 cartes constituant la paire ( $_.group)
($_.Group|% {\"{0} de {1}\" -F $_.Value.Nom,$_.Value.couleur})}
[/code:1]
Dans ce cas on ne peut pas construire la hastable ainsi :
Car le nom de chaque clé est unique dans une hastable.$Tab.\"Huit\".\"Tréfle\"
$Tab.\"As\".\"Coeur\"
Celle-ci reste possible :
[code:1]$Tab.\"Huit\"=@(\"Tréfle\",\"Carreau\")
$Tab.\"As\"=@(\"Tréfle\")
#
$Tab=@{}
#for ..
$Tab.($TypeCarte.($Rnd.Next($BornesCarte.Min,$BornesCarte.Max)))+=$Couleur.($Rnd.Next($BornesCouleur.Min,$BornesCouleur.Max))
[/code:1]
Mais ici c'est la présence du tableau, qui lui autorise les doublons, complique un peu les manipulations.
Une autre approche en ne tenant pas compte de la valeur de la clé, toujours à 0, car seul le nom de la clé nous intéresse :
Dans ce cas on facilite la gestion des doublons et le recherche des paires au prix d'un code un peu plus dense :#Ici seul le nom de la clé nous intéresse
$Tab.\"Huit\"=@{\"Tréfle\"=0;\"Carreau\"=0}
$Tab.\"As\"=@{\"Tréfle\"=0}
[code:1]
#initialisation identique
$tab=@{}
#$Tab est une hashtable de hashtable
# $Tab.Nom1.Couleur1,$Tab.Nom1.Couleur2,$Tab.Nom2.Couleur1...
for ($I=1;$I -le $NbCartes;$I++)
{
do
{ #la clé existe déjà dans la hashtable, on essaie à nouveau
trap [System.Management.Automation.RuntimeException] {$isExist=$true}
#On suppose que la création suivante réussira
$isExist=$false;
#Construction dynamique du nom de clé, les parenthéses sont nécessaire autour de $TypeCarte...
$Tab.($TypeCarte.($Rnd.Next($BornesCarte.Min,$BornesCarte.Max)))+=
#Ici seul le nom de la clé nous intéresse
@{$Couleur.($Rnd.Next($BornesCouleur.Min,$BornesCouleur.Max))=0}
}until (!$isExist)
}
#Pour chaque éléments de la hastable
$tab.GetEnumerator()|`
%{ #on affiche le nom de la carte
$Name=$_.Key;
#Et ce pour chaque paire, ou plus
($_.Value.GetEnumerator()|%{\"{0} de {1}\" -F $Name,$_.Key})}
#Affiche le contenu de la main, s'il existe des paires
$tab.GetEnumerator()|`
# On ne prend que les éléments,de type hastable, ayant + entrées
Where {$_.Value.Count -ge 2}|`
#Pour chaque éléments de la hastable
# Ajoute le nom de la carte
foreach {$Name=$_.Key; (\"Une paire de {0} : \" -F $Name)+
#Ajoute le détail des cartes constituant une paire
($_.Value.GetEnumerator()|%{\"{0} de {1}\" -F $Name,$_.Key})}
[/code:1]
Sur ces derniers exemples je n'ai pas testé de longues séries mais juste la construction.
Ensuite on peut factoriser le code d'affichage mais la relecture s'en ressentirai.
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
Plus il y a de solution mieux c'est.finalement je ne fais pas comme toi Laurent
(je suis assez fier de moi pour le coup)
Nostra écrit:
Sa portée est locale donc l'usage d'une variable globale est une solution.une idée pour résoudre ce problème ?
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Entraide pour les débutants
- Jeux de script d'hiver 2008