2011-06-25 6 views
0

J'essaie d'écrire un programme qui simule les jeux de dés. L'idée est de lancer cinq dés et d'obtenir le score le plus bas possible - trois ont une valeur de 0. Une fois les cinq dés lancés, le joueur/bot DOIT sélectionner au moins un dé (ou plus) parmi les cinq et lancer le reste. C'est ce qui me pose un problème. S'il n'y a pas de threes, alors le tableau "keeper" que je pousse les dés que le bot conserve devient vide, ce qui nécessite une boucle incorporée. Comme je ne connais pas vraiment le codage, je n'arrive vraiment pas à trouver un moyen de créer une boucle incorporée qui garantira qu'au moins un dé est désigné comme gardien. Pour votre santé mentale, je dirai que la version "beta" de ce programme que je vais présenter maintenant est destinée à faire ce qui suit: Créer un bot qui essaie d'obtenir le score le plus bas sur un round d'os. C'est à dire. Les dés sont roulés une fois. Puis il essaie de choisir le score le plus bas possible. S'il n'y a pas trois (l'équivalent de 0), il en choisit un. Le problème que j'essaie de résoudre est de créer une boucle incorporée qui assure qu'au moins un dé est sélectionné pour le tableau de gardien. Le code est principalement pour démontrer à quel point ma solution est laide et donner une idée pour une meilleure solution.Boucles incorporées dans Ruby

#rolls dice 
srand 
dice = [] 
5.times do 
    dice.push(rand(6)+1) 
end 
puts dice 
puts " " 

#initialize keeper and roll again arrays 
i = 0 
keeper = [] 
roll_again = [] 


#select any 3s from the dice roll and put them in keeper 
dice.each do |d| 
    if d == 3 
    keeper.push(d) 
    else 
    i +=1 #dummy operation to keep if statement functioning, tragically ugly code 
    end 
end 

#in the case that no threes were rolled, ones are selected 
if keeper.length == 0 
    dice.each do |f| 
    if f == 1 
     keeper.push(f) 
    else 
     i+= 1 
    end 
    end 
else 
    i += 1 
end 

puts "Keeper:" 
puts keeper 
puts "Roll Again:" 
puts roll_again 
+0

s'il n'y a pas trois ou les? – jtbandes

+0

À ce stade, cela n'a pas vraiment d'importance. J'aurais continué à dire: si le tableau est encore vide, sélectionnez deux, puis quatre, etc etc Mais sans boucles intégrées je pense que ce code aurait l'air terriblement moche. À moins qu'il n'y ait aucun moyen d'utiliser des boucles incorporées. Fondamentalement, pour répondre à votre question, le programme n'est pas actuellement écrit pour simuler une ronde dans son intégralité.Tant que le programme peut être testé chaque fois qu'il y en a trois ou un dans le tableau, c'est suffisant pour mon but - qui est seulement d'apprendre à coder. – Bodhidarma

+0

Et à quoi sert-il? Vous l'incrémentez mais ne semblez pas l'utiliser. – bassneck

Répondre

4

Pour un débutant, vous faites bien :-) Je vais vous montrer certaines choses qui peuvent vous aider à cet exercice, vous apprenez mieux en essayant différentes choses et d'essayer de les comprendre.

>> dice = [5,1,2,2,6,4] #=> [5, 1, 2, 2, 6, 4] 
>> if (threes = dice.select { |d| d == 3 }).empty? 
.. ones = dice.select { |d| d == 1 } 
.. end #=> [1] 
>> threes #=> [] 
>> ones #=> [1] 

Une autre chose que vous pouvez faire est un groupe le tableau dés:

>> dice.group_by { |d| d } #=> {5=>[5], 1=>[1], 2=>[2, 2], 6=>[6], 4=>[4]} 

De cette façon, vous pouvez voir instantanément si le tableau pour un nombre donné est vide ou non. Notez qu'il est facile de faire des différences de tableau dans Ruby, ce qui pourrait vous aider avec dés la suppression:

>> [3,1,3,5,1,7] - [3] #=> [1, 5, 1, 7] 

En fait intersection du tableau est aussi une bonne façon de voir si un certain élément fait partie d'un tableau:

>> ([3,1,3,5,1,7] & [3]).empty? #=> false 
>> ([4,1,2,5,1,7] & [3]).empty? #=> true 

Quelques autres conseils: Vous n'avez pas besoin d'instructions factices pour vos branches else, vous pouvez simplement les laisser de côté. Je recommande fortement de passer par les documents de Array et Enumerable, il y a beaucoup de méthodes utiles là-bas.

+0

J'écrivais juste une réponse avec une méthode "roll_dice" et un peu d'utilisation de .select pour sortir les trois ... mais je pense que la suggestion de Michael d'avoir un jeu dans la console avec les méthodes de l'API pour Array et Enumerable est une excellente suggestion. – Pavling

+0

Merci pour la réponse et l'encouragement. Les émoticônes font des kilomètres en guise de réconfort. Je ne comprends pas encore votre réponse, mais je vais y réfléchir lundi. Avec l'aide de ruby-doc.com, je suis sûr que ça éclaircira beaucoup sur le rubis et le codage en général et m'aidera sur le chemin. – Bodhidarma

1

Bien sûr, il existe plusieurs façons de le faire. Mais jetez un oeil: j'ai fait quelques modifications générales pour en faire un peu plus ... Rubis!

# A custom helper method 
class Array 
    def take_while_num # Modeled off take_while, but also pass in the length so far 
    arr = [] 
    each do |e| 
     # Call the block with this element and the current length, 
     # and stop if it returns false 
     if yield(e, arr.length) 
     arr << e 
     else 
     break 
     end 
    end 
    arr 
    end 
end 

dice = Array.new(5) { rand(6)+1 } # 5 random numbers 
puts "Original dice: #{dice.inspect}" 

# Sort the dice by value (3s are worth 0), then take all 3s 
# or if there are no 3s, take whatever is at the front 
keep = dice.sort_by {|d| d == 3 ? 0 : d }.take_while_num {|d, n| n.zero? or d == 3 } 
# Remove the ones we're keeping from the list of dice 
dice -= keep 

puts "Dice: #{dice.inspect}" 
puts "Keep: #{keep.inspect}" 

Un exemple:

Original dice: [3, 2, 4, 3, 1] 
Dice: [2, 4, 1] 
Keep: [3, 3] 
2

BTW, Michael Kohl a créé gem methodfinder. si:

$ sudo gem install methodfinder 

Maintenant, nous pouvons trouver la méthode dont nous avons besoin:

[2,3,2,3,4,3,2].find_method { |x| x.unknown(3) == [3,3,3] } 
=> grep 

J'écririez votre algorithme comme ceci:

def keep dice 
    threes = dice.grep(3) 
    threes.empty? ? [dice.min] : threes 
end 
+0

sudo: commande gem introuvable. – Bodhidarma

+0

@Bodhidarma, vous devez installer Ruby Gems. Voici mes instructions, comment installer RVM avec Ruby Gems and Rails: http://snippets.dzone.com/posts/show/13251 – Alexey