Average an array help

  • Thread starter Thread starter J
  • Start date Start date
J

J

Kind of new at programming/vb.net. I'm doing this junky die roller
program.


Heres's what is supposed to happen:
Roll 2 6-sided dies. Add rolls together put total in
rolls(d6total).
Display the number of 2 or 12 rolled, then display those numbers
and average rolls. I didn't know how to do it exactly, but I came up
with this.

The obvious problem for me appears in loop (there may be other
problems but they're not obvious to me). See below


I used this in another sub to fill rolls array, based on a click
event:

ReDim Preserve rolls(UBound(rolls) + 1)' adds one to rolls
dimension

'get number for rolls
d6 = CInt(Int((6 * Rnd()) + 1))
d5 = CInt(Int((6 * Rnd())) + 1)
d6Total = d5 + d6 'totals roll

rolls(UBound(rolls)) = d6Total 'should keep record of rolls

Private Sub btnSum_Click

Dim i As Integer = 1
Dim temp, temp1 As Integer ' keeps running total of rolls
Dim twelves, ones As Integer ' counts each 12 or 2 in rolls
lstRollDis.Items.Clear()

'I expect the first pass through the loop will assign temp to roll(i).
Then 'checks to see if a 12 or 2 is rolled then adds one to the total
if yes.
'Since I want to average this array, Assign the value of temp to the
running 'value of temp1. I think the value of i is causing out of
bounds errors. I can't 'figure this out. It seems to make sense to me.

For Each i In rolls
temp = rolls(i)
If temp = 12 Then
twelves += 1
End If
If temp = 2 Then
ones += 1
End If
i += 1
temp1 += temp
Next
With lstRollAverage.Items
.Clear()
.Add("Average roll " & Math.Round((temp1 / (i - 1)), 1) & " out
of " & (i - 1))
'I used (i-1) because loop pickups roll(0)as "0"
.Add("You rolled " & twelves & " cars")
.Add("You rolled " & ones & " snakes")
.Add("and cowered " & cowers & " times")
End With
end sub


Thanks for help, pointers, or suggestions.
 
For Each i In rolls
temp = rolls(i)

If temp = 12 Then
twelves += 1
End If
If temp = 2 Then
ones += 1
End If

Use ElseIf here instead of two separate If... EndIf blocks

This is meaningless with a For Each loop.
temp1 += temp
Next
With lstRollAverage.Items
.Clear()
.Add("Average roll " & Math.Round((temp1 / (i - 1)), 1) & " out
of " & (i - 1))

This is the problem. Once you exit the For Each loop, i becomes 0/Nothing,
even though you were incrementing it. So, you have to change to either:

For i = 0 to ubound(rolls)
....
Next

OR

Dim Cnt as Integer=0
For Each i In rolls
....
Cnt+=1
Next
Then use Cnt to get the average.
 
J said:
I'm doing this junky die roller program.

Hi "J"... I assume it's homework of some type?
Heres's what is supposed to happen:
Roll 2 6-sided dies. Add rolls together put total in
rolls(d6total).
Display the number of 2 or 12 rolled, then display those numbers
and average rolls. I didn't know how to do it exactly, but I came up
with this.

I can't quite understand the "specs" ... were you told to actually save the
rolls in order to compute the average or did you decide that's the way to do
it? I ask because I think these numbers can be updated each time you roll
without storing them in an array.
I used this in another sub to fill rolls array, based on a click
event:

ReDim Preserve rolls(UBound(rolls) + 1)' adds one to rolls
dimension

'get number for rolls
d6 = CInt(Int((6 * Rnd()) + 1))
d5 = CInt(Int((6 * Rnd())) + 1)
d6Total = d5 + d6 'totals roll

rolls(UBound(rolls)) = d6Total 'should keep record of rolls

I regularly suggest that "reduce the interface" until you have the basic
functionality operating. Try writing all the parts and then add click
events and such. They get in your way when you are trying to write
algorithms. I know this isn't the "source" of your main question but it
looks peculiar already. Is this a subroutine or code from a click event
handler? What are d6, d5 and d6Total? Note that your parens are different
on the random number formula.

If you aren't keeping all the values then this alone would store the
total... I'd check your random number formula though.
rolls(UBound(rolls)) = CInt(Int((6 * Rnd())) + 1) + CInt(Int((6 *
Rnd())) + 1)

Private Sub btnSum_Click

Again I suggest you skip the click event for now... at least create a
subroutine that averages the number and just call the thing from your button
click.
'I expect the first pass through the loop will assign temp to roll(i).

It's assigning roll(i) to temp I believe.
I think the value of i is causing out of bounds errors.

I think you want to check your syntax here... it looks like a for next loop
but you are using For Each (and later incrementing variable i.)
For Each i In rolls
temp = rolls(i)
If temp = 12 Then
twelves += 1
End If
If temp = 2 Then
ones += 1
End If

If temp did equal 12 then there is no reason to check if temp equals 2. Not
a big deal but and else clause should eliminate the extra test.
With lstRollAverage.Items
.Clear()
.Add("Average roll " & Math.Round((temp1 / (i - 1)), 1) & " out
of " & (i - 1))
'I used (i-1) because loop pickups roll(0)as "0"
.Add("You rolled " & twelves & " cars")
.Add("You rolled " & ones & " snakes")
.Add("and cowered " & cowers & " times")

I think I'm lost here I don't see you counting "cowers" and I still don't
get if you want the average of just the 2's and 12's or the average of all
rolls...

Tom
 
Hi Tom,

Thanks for taking the time. I tried to clarify some points below.

Tom Leylan said:
Hi "J"... I assume it's homework of some type?

Heh, no. I'm looking for stuff to write programs with and this just
does calculations for a wargame. I call it junky because, well, it is.
Almost no one, including me, would use :) Its easier to memorize the
thing.
I can't quite understand the "specs" ... were you told to actually save the
rolls in order to compute the average or did you decide that's the way to do
it?

Yes, both. If there's another way to save the rolls and average
them, I'll do that. But the main purpose of this program is to
practice and use some basic things to learn about them.
I ask because I think these numbers can be updated each time you roll
without storing them in an array.

I wasn't sure how much to report about this program. I could paste
the whole thing but I thought I'd just included important parts and
areas that seem to error.

Here's what it simulates. A table of attack strength vs die roll.
User inputs strength(attack) then rolls 2d6. Cross references the
strength with the die rolls. I wanted to hold a record of the sum of
each roll and 12s and 2s rolled. Then display the average die roll and
the number of 12s and 2s.
I know this isn't the "source" of your main question but it
looks peculiar already.

LOL. Remember, I hacked my way through this. I'm just starting out.
Is this a subroutine or code from a click event
handler? What are d6, d5 and d6Total? Note that your parens are different
on the random number formula.

Yes. I don't know the most efficient way of getting two random
numbers. I realize now that it is probably confusing with variable
name. I get two random numbers with different variables because I also
need to know if doubles were rolled. I check, but didn't include, the
part about d6=d5, that's what cower refers to at the bottom of this
message. see below.

d6Total = d5 + d6 or two random numbers added together. Then
rolls(d6total)
I put the total in rolls array.
If you aren't keeping all the values then this alone would store the
total... I'd check your random number formula though.
Rnd())) + 1)

I got that random number formula from the help. I don't know any
other way.
OK, much cleaner than what I've got. I can only do that if increase
the size of the array, as I did earlier.

Again I suggest you skip the click event for now... at least create a
subroutine that averages the number and just call the thing from your button
click.

I was thinking I would add this for clarity but I don't think I was
very clear. Sorry. I wanted to make it as simple to read as possible.
It's assigning roll(i) to temp I believe.


I think you want to check your syntax here... it looks like a for next loop
but you are using For Each (and later incrementing variable i.)

OK, I'm struggling with the loops. I couldn't find any reference for
what I wanted to do so I just kept trying different things.
If temp did equal 12 then there is no reason to check if temp equals 2. Not
a big deal but and else clause should eliminate the extra test.

OK, right.
I think I'm lost here I don't see you counting "cowers" and I still don't
get if you want the average of just the 2's and 12's or the average of all
rolls...

I should have removed cowers. I removed that part since it seems to
be working ok. Cowers basically counts the number of times d5=d6.
I wanted to do both: average and total the 12 and 2s.
 
J said:
Heh, no. I'm looking for stuff to write programs with and this just
does calculations for a wargame.

Sounds like fun. You want to turn the junky thing into a cool thing?
Consider creating a "dice" class. It will give you the practice you are
looking for, you will be creating OOP-code instead of procedural code (may
as well get started doing that now) and it will work well for this game or
any other.
If there's another way to save the rolls and average them,

If all you wanted to do was average some rolls I'd bet you could keep a
running total of the number of rolls and their values. You wouldn't have to
keep every roll since the average would be known immediately.
User inputs strength(attack) then rolls 2d6. Cross references the
strength with the die rolls. I wanted to hold a record of the sum of
each roll and 12s and 2s rolled. Then display the average die roll and
the number of 12s and 2s.

That's even better. Consider creating a simple class that rolls a die.
That's your first mini-project. Then create another class that contains two
Dice objects and handles the special calculations you need for your game.
By doing it that way you will have Dice which you can use all over the
place.
Yes. I don't know the most efficient way of getting two random
numbers. I realize now that it is probably confusing with variable
name. I get two random numbers with different variables because I also
need to know if doubles were rolled. I check, but didn't include, the
part about d6=d5, that's what cower refers to at the bottom of this
message. see below.

This will be much easier when you get the classes built. They are very
small so it won't be hard but it means the "rolling" code is hidden away,
you just issue something like:

d1.Roll()
d2.Roll()
d6Total = d5 + d6 or two random numbers added together. Then
rolls(d6total)
I put the total in rolls array.

This will all happen in your WarGameDice class. Again, the details will be
hidden away so your WarGame simply communicates with the WarGameDice object
so you would have something like:

wgd.Total
wgd.Average

or whatever else you needed the thing to tell you like:

wgd.Cowers

I think if you feel up to the challenge (and it isn't hard) to make it
object-oriented you will get quite a bit of help in this newsgroup.

Tom
 
Tom Leylan said:
I think if you feel up to the challenge (and it isn't hard) to make it
object-oriented you will get quite a bit of help in this newsgroup.


Thanks Tom. I'm going to try that.
 
Back
Top