1

I came across this question in the Cay Horstmann book:

Program the following simulation: Darts are thrown at random points onto the square with corners (1,1) and (−1,−1). If the dart lands inside the unit circle (that is, the circle with center (0,0) and radius 1), it is a hit. Otherwise it is a miss. Run this simulation and use it to determine an approximate value for π. Extra credit if you explain why this is a better method for estimating π than the Buffon needle program.

I do get why this is a better method for estimating π than the Buffon needle program, so that is fine. But I seem to have problems with my code.

Here is my current code:

import java.util.Scanner;

public class Dart {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("Enter number of tries: ");
        int n = in.nextInt();
        int miss = 0;
        int hit = 0;
        double x = Math.random() * 2 - 1;
        double y = Math.random() * 2 - 1;
        double func = x * x + y * y;
        for (int i = 0; i < n; i++) {
            if (func <= 1) {
                hit++;
            } else {
                miss++;
            }
        }
        System.out.println("Probability: " + hit / (hit + miss) * 4);
    }
}

When I enter any numbers, the Probability output always comes out as 1, but I think if the code is right it prints π because its: (the area of a circle with radius 1) over (a square with length 2) times 4.

I would appreciate an explanation why my code is wrong.

Emma Lee
  • 35
  • 4

2 Answers2

1

When you assign a variable, that variable isn't recalculated every time it's asked for--it's assigned once, and until it's reassigned, it'll always be the same value. So this:

          double x = Math.random() * 2 - 1;
          double y = Math.random() * 2 - 1;
    
          double func = x * x + y * y;

will set x and y to a random number between -1 and 1, and func to x * x + y * y... and then they'll stay that way, until the program ends, because you never reassign them.

So this:

          for (int i = 0; i < n; i++)
          {
        
              if (func <= 1)
                  hit++;
              else
                  miss++;
          }

will either always increment hit or increment miss, because func's value never changes.

What you want to do is move the definitions of x, y and func to inside the for loop, rather than outside--this will make them different every time, as you intended.

Also, integer division results in an integer, so you're going to need to convert miss and hit into doubles in the last line.

Putnam
  • 664
  • 1
  • 14
0

Try out the following

import java.util.Scanner;

public class Dart
{
    public static void main(String[]args)
    {
        Scanner in = new Scanner(System.in);

        System.out.println("Enter number of tries: ");
        int n = in.nextInt();

        double miss = 0;
        double hit = 0;

        double x = 0, y = 0, func = 0;

        for (int i = 0; i < n; i++)
        {
            x = Math.random() * 2 - 1;
            y = Math.random() * 2 - 1;

            func = x * x + y * y;

            if (func <= 1)
                hit++;
            else
                miss++;
        }

        System.out.println("Probability: " + ( (double) hit / (hit + miss) * 4 ));
    }
}

You made 2 mistakes first one you need to generate the random x and y within the loop so the values get regenerated and secondly you need to use doubles or floatsfor hit and miss or the better way ( thanks to @FedericoklezCullocafor ) you could cast them to doubles within the print because if you would use int down in the print you would make an integer division which returns always 0.

René
  • 79
  • 6