Generate "scattered" items, that do not overlap - python

This is a question that i had to solve, but have been banging my head against a wall for the past 5 days. There must be something really simple that i am missing, or misunderstanding, as the logic seems 100% correct in my head, but it just won't work.
I need to draw "scattered" houses, that do not over lap, 100 of them.
I have to use turtle to draw them, so i have X and Y coordinates.
And X and Y list for verification purposes, to see if a house is already in that place.
What i am doing is drawing a "house" (square with a triangle on top) on the randomized coordinates,
I loop while the number of houses is less than 100.
On each loop i randomize the x and y coordinates, from where i start drawing each house with turtle.
I check if the value is already in the X and Y verification lists, and also if my new X and Y are +/- the size of the house (treating it as a square)
import turtle
import time
import random
t = turtle.Turtle()
turtle.screensize(1920,1000)
x_verif = []
y_verif = []
t.speed(0)
collision = None
def square():
for s in range(0, 4):
t.forward(90)
t.left(90)
def triangle():
for s in range(0, 2):
t.left(-60)
t.forward(52)
def house():
square()
t.left(90)
t.forward(90)
triangle()
def scatter():
print("a")
house()
x1 = random.randint(-850, 850)
y1 = random.randint(-380, 380)
count = 0
while count < 100:
print("a2")
i = 0
u = 0
collision = False
for tries in range (0, 2):
print("a3")
x_verif.append(x1)
y_verif.append(y1)
while u < 100:
print("a4")
print(x_verif, y_verif, x1, y1)
while i < len(x_verif):
x1 = random.randint(-850, 850)
y1 = random.randint(-380, 380)
print(x1, y1)
if x1 not in x_verif and (x1 > x_verif[i]+91 or x1 < x_verif[i]-91):
if y1 not in y_verif and (y1 > y_verif[i]+142 or y1 < y_verif[i]-142):
collision = False
else:
collision = True
if collision == False:
t.penup()
t.hideturtle()
t.setx(x1)
t.sety(y1)
t.pendown()
house()
x_verif.append(x1)
y_verif.append(y1)
count += 1
i+= 1
u += 1
scatter()
Sorry for the ugly code, and the simplicity behind it. I would love to use list comprehensions for this, but i do not know where my logic fails at the moment. This is like my 100th try, as of this version it only draws the initial house and i think it loops infinitely somewhere....
My problem lies in looping through the whole lists for every new value. Do i need to loop through them every time, or is there some IF condition that I can use? Edit: It keeps on looping through random values, but none of them are accepted by the two IF statements that i'm using.
On a side note: With my current code they also change direction of drawing every time... No idea why is that happening....
Edit: I am very thankful for all the solutions! I'm struggling with the note at the beginning of the question. It says that it should only take a couple more lines to do the last one, compared to the first one..... Are they joking?

This turned out to be a trickier problem than I assumed from the description. My approach was to treat, and store, a house as two polygons, a square and a triangle. I randomly test draw (pen up) a house and compare all the points in its polygons to see if they are inside existing house polygons, and vice versa. If no overlap, draw the house for real. The solution is not efficient, but it allows tight packing of houses than a simple diameter-based approach.
The point in triangle routine is based on one from GeeksForGeeks.org
I have one slight fudge factor in my code that still needs to be polished out. But overall it seems to achieve the objective:
from turtle import Screen, Turtle
from random import randint
HOUSES = 100
HOUSE_SIZE = 90
WINDOW_WIDTH, WINDOW_HEIGHT = 1920, 1000
# assumes roof is an isosceles triangle
ROOF_SIDE = HOUSE_SIZE * 3**0.5 / 3
ROOF_HEIGHT = ROOF_SIDE // 2
FONT_SIZE = HOUSE_SIZE // 3
FONT = ('Arial', FONT_SIZE, 'normal')
def square(turtle, identity=None):
turtle.begin_poly()
for _ in range(3):
turtle.forward(HOUSE_SIZE)
turtle.right(90)
turtle.end_poly()
turtle.forward(HOUSE_SIZE/2 - FONT_SIZE/2) # visually finish square
if identity: # label each house with a number
turtle.penup()
turtle.right(90)
turtle.forward(HOUSE_SIZE/2)
turtle.write(identity, align='center', font=FONT)
turtle.backward(HOUSE_SIZE/2)
turtle.left(90)
turtle.pendown()
turtle.forward(HOUSE_SIZE/2 + FONT_SIZE/2) # visually finish square
turtle.right(90) # return to original orientation
return turtle.get_poly()
def triangle(turtle):
turtle.begin_poly()
turtle.forward(HOUSE_SIZE)
turtle.left(150)
turtle.forward(ROOF_SIDE)
turtle.end_poly()
turtle.left(60)
turtle.forward(ROOF_SIDE) # visually finish triangle
turtle.right(210) # return to original orientation
return turtle.get_poly()
def house(turtle, identity=None):
return (square(turtle, identity), triangle(turtle))
def area_of_triangle(p1, p2, p3):
x1, y1 = p1
x2, y2 = p2
x3, y3 = p3
return abs((x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2))) // 2
def is_inside_triangle(point, triangle):
p1, p2, p3 = triangle
a = area_of_triangle(p1, p2, p3)
b = area_of_triangle(point, p2, p3)
c = area_of_triangle(p1, point, p3)
d = area_of_triangle(p1, p2, point)
return abs(a - (b + c + d)) < 5 # 5 == fudge factor, sigh
def is_inside_square(point, square):
x, y = point
p1, p2, p3, p4 = square
_, y1 = p1
x2, _ = p2
_, y3 = p3
x4, _ = p4
return x4 <= x <= x2 and y3 <= y <= y1
def scatter(turtle):
houses = []
count = 0
while count < HOUSES:
x = randint(-WINDOW_WIDTH/2, WINDOW_WIDTH/2 - HOUSE_SIZE)
y = randint(HOUSE_SIZE - WINDOW_HEIGHT/2, WINDOW_HEIGHT/2 - ROOF_HEIGHT)
turtle.penup()
turtle.goto(x, y)
proposed_square, proposed_triangle = house(turtle) # test draw invisible house
turtle.pendown()
collision = False
for point in proposed_square + proposed_triangle: # does proposed house collide with houses?
for square, triangle in houses:
if is_inside_square(point, square) or is_inside_triangle(point, triangle):
collision = True
break
if collision:
break
for square, triangle in houses: # do houses collide with proposed house?
for point in square + triangle:
if is_inside_square(point, proposed_square) or is_inside_triangle(point, proposed_triangle):
collision = True
break
if collision:
break
if not collision:
count += 1
houses.append(house(turtle, identity=count)) # actually draw new house
print(count)
screen = Screen()
screen.screensize(WINDOW_WIDTH, WINDOW_HEIGHT)
screen.tracer(False)
turtle = Turtle()
turtle.hideturtle()
scatter(turtle)
screen.tracer(True)
screen.exitonclick()
This problem is simplified somewhat by the consistent orientation of houses. If the houses were randomly oriented, compass-wise, the square overlap calculations would be more complex.
The solution could be made more efficient by doing triangle overlap with triangle, square overlap with triangle, etc. tests instead of simply "point inside". We could also push the collision logic down into the square() and triangle() routines to throw an error as soon as there's a collsion, rather than completing a house and then testing.
Given the size of the screen area, size of a house, the number of houses, and the random scattering, I believe it may be possible for an idividual run of the program to stall trying to place a house where there may not be available space:

Defo no the best way to do it but
import turtle
import time
import random
t = turtle.Turtle()
turtle.screensize(1920,1000)
x_verif = []
y_verif = []
t.speed(0)
collision = None
def square():
for s in range(0, 4):
t.forward(90)
t.left(90)
def triangle():
for s in range(0, 2):
t.left(-60)
t.forward(52)
def house():
square()
t.left(90)
t.forward(90)
triangle()
t.left(30) #returning to 90 degrres
def scatter():
beenAt = [] #this will hold every place that there is a house
for i in range(100):
t.penup()
loop = True
while loop == True:
area = random.randint(-850, 850)
for i in range(91): #looping for the size of the house
if area+i in beenAt: #if the number chosen plus i is in beenAt stop because we cant use that place
break
if i == 90: #if at the finial part of our loop then draw house
t.goto(area, 0)
t.pendown()
for i in range(area, area + 91):
beenAt.append(i) #add to been at list every place we have drawn
house()
loop = False
scatter()

Related

Find_overlapping & Collision and with Zelle graphics (python) - would like some feedback pls

I am looking for a different way to create collision detection using Zelle Graphics and find_overlapping. I believe the overlapping shows where the bounding box of an object has come in contact with the bounding box of another object (the tuple)? I was hoping for some feedback on this code. Presently, the object goes through the rectangle before it breaks, but I think the idea has merit. This is just a test and need much more fine tuning.
from graphics import *
win = GraphWin("game loop", 500, 500, autoflush=False)
win.master.attributes('-topmost', True)
x=20
y=20
dx=20
play=0
cir1=Circle(Point(x,y),10)
cir1.setFill("red")
cir1.draw(win)
x1=300
x2=310
y1=0
y2=50
rect1=Rectangle(Point(x1,y1),Point(x2,y2))
rect1.setFill("blue")
rect1.draw(win)
xwidth=win.getWidth()
while play==0:
for i in range(100):
xposition = cir1.getCenter().getX()
test1=win.find_overlapping(x1,y1,x2,y2)
print("This is the length of test1:",len(test1))
print(test1)
if xposition+1>=xwidth or xposition-1<=0:
dx=-dx
cir1.move(dx, 0)
update(15)
if len(test1)==2:
print("overlap")
play=1
break
print("game over")
win.mainloop()
I see few problems:
you first check collision, next you move to new position, and next you check if to stop game - but you should stop game after checking collision without moving to new position. OR you should first move to new position, next check collision and check if to stop game.
you move dx = 20 but wall has width only 10 and it can jump it - you should use smaller dx and use bigger value in update()
you check if wall overlaps any other objects but if you will have many walls then it would be simpler to check if circle overlaps any other objects.
when circle overlap then you would have to move it back - if you move right then you should set circle's right border in place of rectangle' left border.
Minimal working example with changes 1, 2, 3 but without 4 because it would need more changes.
from graphics import *
win = GraphWin("game loop", 500, 500, autoflush=False)
win.master.attributes('-topmost', True)
x = 200
y = 20
dx = -5
play = True
cirle = Circle(Point(x, y), 10)
cirle.setFill("red")
cirle.draw(win)
x1 = 300
x2 = 310
y1 = 0
y2 = 50
rect1 = Rectangle(Point(x1, y1), Point(x2, y2))
rect1.setFill("blue")
rect1.draw(win)
xwidth = win.getWidth()
while play:
for i in range(100):
# move circle to new position
cirle.move(dx, 0)
# get circle's new position
p1 = cirle.getP1()
p2 = cirle.getP2()
# check circle's collision in new position
overlaps = win.find_overlapping(p1.x, p1.y, p2.x, p2.y)
print("test:", len(overlaps), overlaps)
if len(overlaps) > 1:
print("overlap")
play = False
break
# check circle's collision with window's boders
if p2.x >= xwidth or p1.x <= 0:
dx = -dx
update(50)
print("game over")
#win.mainloop() # no need if you use `update()`

A start to tiling the screen with triangles

At the moment, I'm trying to get started trying to tile the python turtle graphics screen with equilateral triangles of random colors. I've made a function which is successfully able to make a triangle starting at say coordinates v_1 = (x, y). Once it's made the triangle, I want the turtle to head to one of the other triangle vertices that are not equal to v_1 and start a new triangle there. I'd like to do all of this in a while loop. However, when I run my code, it seems that the turtle always goes back to the initial position of the first equilateral triangle and makes a new one on top of it. I'm not sure what I'm doing wrong. Here's my code:
from turtle import Turtle, colormode, done
from random import randint
colormode(255)
def make_left_triangle(bob: Turtle, x: float, y: float) -> None:
"""Makes an equilaterial triangle at coordinates (x, y) with the turtle bob moving left."""
r: int = randint(0, 255)
g: int = randint(0, 255)
b: int = randint(0, 255)
rand_n: int = randint(1, 2)
i: int = 0
bob.penup()
bob.goto(x, y)
bob.pendown()
bob.fillcolor(r, g, b)
bob.begin_fill()
while i < 3:
bob.forward(200)
bob.left(120)
i += 1
bob.end_fill()
while rand_n < 3:
bob.forward(200)
bob.left(120)
rand_n += 1
def main() -> None:
bob: Turtle = Turtle()
i: int = 0
rand_n: int = randint(25, 50)
x_coord: float = 0
y_coord: float = 0
while i < rand_n:
make_left_triangle(bob, x_coord, y_coord)
x_coord = bob.pos()[0]
y_coord = bob.pos()[1]
i += 1
done()
if __name__ == "__main__":
main()
Any help on what's going wrong would be greatly appreciated! Thanks
The problem is that the orientation of the bob is preserved between different calls to make_left_triangle. For example, if you draw a triangle ABC:
C
/ \
/ \
A-----B
and then move to vertex C you also turn in the direction of CA. So the next time you'll draw a new triangle CAB, which will be drawn over the initial ABC. You need to reset the orientation of the bob at the start of each make_left_triangle call.

How do I generate monteCarlopi function in a given circle/square?

Write a function monteCarloPi(n, radius) that takes two arguments, the number of simulations n and the radius of the circle, and returns a float, which is the estimated value for pi. This radius should be the same radius that you used to draw your inscribed circle in the previous problem. Generate a set of random points, and test to see if that value is inside the circle or outside the circle. Use turtle to draw a dot at each location. This can be done using the function turtle.dot(size, color). Find the ratio of the points inside the circle to the number of points in the simulation. The latter number is an estimate for the area of the square. Multiple the ratio by four to get your estimate for pi.
This is what I have and I have no idea why it only draws one dot. Can anybody help me? I am a beginner /:
import turtle as t
import random
def monteCarloPi(n, radius):
'''
Takes two arguments, the number of simulations n and the radius of the circle, and returns a float, which is the estimated value for pi.
'''
t.dot() # Origin (0, 0)
t.pu()
t.goto(0, -radius)
t.pd()
t.circle(radius)
t.pu()
t.goto(-radius ,-radius)
t.pd()
for square in range(4):
t.fd(radius * 2)
t.lt(90)
points_in_circle = 0
points_in_square = 0
x = random.uniform(-radius, radius)
y = random.uniform(-radius, radius)
for dots in range(n):
t.pu()
t.goto(x, y)
t.dot()
origin = x ** 2 + y ** 2
if origin <=1 :
points_in_circle += 1
else:
points_in_square +=1
pi = 4 * (points_in_circle / points_in_square)
return pi
I see a number of potential problems with your code. The last two lines shown aren't indented correctly, they should be after the loop, not in it.
This equation origin = x ** 2 + y ** 2 seems incorrect and might need to instead be origin = (x ** 2 + y ** 2) ** 0.5
These two statements:
x = random.uniform(-radius, radius)
y = random.uniform(-radius, radius)
need to be at the top of the loop, not before the loop, otherwise you're plotting the same point n times, instead of n points. This calculation seems wrong:
pi = 4 * (points_in_circle / points_in_square)
reread the instructions you provided above. You should be dividing by n not points_in_square. This doesn't seem correct:
if origin <=1 :
as we're not working with a unit circle, so I'd expect:
if origin <= radius:
The reworked code based on my above observations:
from turtle import Screen, Turtle
from random import uniform
def monteCarloPi(n, radius):
'''
Takes two arguments, the number of simulations n and the radius of the circle,
and returns a float, which is the estimated value for pi.
'''
turtle.dot() # Origin (0, 0)
turtle.penup()
turtle.sety(-radius)
turtle.pendown()
turtle.circle(radius)
turtle.penup()
turtle.setx(-radius)
turtle.pendown()
for _ in range(4):
turtle.forward(radius * 2)
turtle.left(90)
turtle.penup()
turtle.hideturtle()
points_in_circle = 0
for _ in range(n):
x = uniform(-radius, radius)
y = uniform(-radius, radius)
turtle.goto(x, y)
turtle.dot()
origin = (x ** 2 + y ** 2) ** 0.5
if origin <= radius:
points_in_circle += 1
pi = 4 * points_in_circle / n
return pi
screen = Screen()
turtle = Turtle()
turtle.speed('fastest') # because I have no patience
print(monteCarloPi(100, 100))
screen.exitonclick()

Click-Circle game - clicking outside and inside the circle

I am trying to code a game that has a red circle in which the user is supposed to click up to 7 times in the window. If the user clicks outside the circle, the circle will change its position to where the user clicked. And the game should end when the user has clicked 3 times inside the circle (does not have to be in a row) or when the user has clicked 7 times in total.
I have coded and done quite most of it I think, its just I cant seem to make it work as I want to.
from graphics import *
def draw_circle(win, c=None):
x = random.randint(0,500)
y = random.randint(0,500)
if var is None:
centa = Point(x,y)
var = Circle(centa,50)
var.setFill(color_rgb(200,0,0))
var.draw(win)
else:
p1 = c.p1
x_dif = (p1.x - x) * -1
y_dif = (p1.y - y) * -1
var.move(x_dif, y_dif)
return (var, x, y)
def main():
win= GraphWin("game",800,800)
score = 0
var,x,y = draw_circle(win)
while score <= 7:
mouseClick2=win.getMouse()
if mouseClick2.y >= y-50 and mouseClick2.y <= y +50 and
mouseClick2.x >= x-50 and mouseClick2.x <= x+50:
score=score + random.randint(0,5)
var,x,y = draw_circle(win, c)
print ("Success!")
print (("the score is, {0}").format(score))
thanks for the help in advance!
I see a couple problems.
your if mouseClick2.y >= y-50... conditional is spread out on two lines, but you don't have a line continuation character.
You never call main().
You don't import random.
You call draw_circle in the while loop with an argument of c, but there is no variable by that name in the global scope. You probably meant to pass in var.
c in draw_circle ostensibly refers to the circle object you want to manipulate, but half the time you manipulate var instead of c.
you assign a value to cvar in the loop, but never use it.
Your else block in draw_circle calculates the movement delta by subtracting the cursor coordinates from c.p1. But c.p1 is the upper-left corner of the circle, not the center of the circle. So your hit detection is off by fifty pixels.
import random
from graphics import *
def draw_circle(win, c=None):
x = random.randint(0,500)
y = random.randint(0,500)
if c is None:
centa = Point(x,y)
c = Circle(centa,50)
c.setFill(color_rgb(200,0,0))
c.draw(win)
else:
center_x = c.p1.x + 50
center_y = c.p1.y + 50
x_dif = (center_x - x) * -1
y_dif = (center_y - y) * -1
c.move(x_dif, y_dif)
return (c, x, y)
def main():
win= GraphWin("game",800,800)
score = 0
var,x,y = draw_circle(win)
while score <= 7:
mouseClick2=win.getMouse()
if mouseClick2.y >= y-50 and mouseClick2.y <= y +50 and \
mouseClick2.x >= x-50 and mouseClick2.x <= x+50:
score=score + random.randint(0,5)
var,x,y = draw_circle(win, var)
print ("Success!")
print (("the score is, {0}").format(score))
main()
Additional possible improvements:
Your hit detection checks whether the cursor is in a 50x50 rectangle centered on the circle. You could instead check whether the cursor is inside the circle if you measured the distance between the cursor and the center, and checked whether it was less than the radius.
var and c could stand to have more descriptive names.
mouseClick2 doesn't make much sense as a name, considering there's no mouseClick1.
The movement delta arithmetic could be simplified: (a-b) * -1 is the same as (b-a).
If you only use a variable's value once, you can sometimes avoid creating the variable at all if you nest expressions.
it might be nice to define constants, such as for the circle's radius, instead of having magic numbers in your code.
You can save five characters by using += to increment the score.
import math
import random
from graphics import *
RADIUS = 50
def draw_circle(win, circle=None):
x = random.randint(0,500)
y = random.randint(0,500)
if circle is None:
circle = Circle(Point(x,y),RADIUS)
circle.setFill(color_rgb(200,0,0))
circle.draw(win)
else:
circle.move(
x - circle.p1.x - RADIUS,
y - circle.p1.y - RADIUS
)
return (circle, x, y)
def main():
win= GraphWin("game",800,800)
score = 0
circle,x,y = draw_circle(win)
while score <= 7:
cursor = win.getMouse()
if math.hypot(cursor.x - x, cursor.y - y) <= RADIUS:
score += random.randint(0,5)
circle,x,y = draw_circle(win, circle)
print ("Success!")
print (("the score is, {0}").format(score))
main()
I'm not really a python guy, but I see that your hitbox is wrong. If there are any other issues then comment it/them to me.
Solving hitbox to be circle:
What you have already written is good to have thing but you should check if click was in circle not square. Pythagoras triangle is solution for this.
Check:
if (math.sqrt(delta_x **2 + delta_y **2) <= circle_radius)
where delta_x and delta_y is center coordinate minus mouse position

Randomly orientated lines drawn off a random point in python

I'm trying to create python program that has several vertical lines which act as boundaries where randomly generated points or "dots" (as referred to in the code) which draw a straight line at a random degree. If the straight line intersects with one of the vertical "boundaries" I want to make it change colour. I have a picture of what I am trying to achieve which will probably explain my situation a bit clearer. The code I post below has drawn the "vertical boundaries" and has the points randomly generated within the region, however that is where I am stuck.
What I am aiming to achieve:
Example of program
My current Code:
setup(750,750)
screen_size = 750
max_coord = (screen_size - 30) / 2
### change the number of dots you have via that variable
num_dots = 500
bgcolor('yellow')
dot_size=5
reset() # Create an empty window
pi = Turtle()
hideturtle()
def parallel_lines(number):
pi.pensize(2)
pi.pencolor('black')
width = pi.window_width()
height = pi.window_height()
pi.setheading(90)
pi.penup()
pi.setposition(width/-2, height/-2)
for i in range(1, number +2):
pi.pendown()
pi.forward(height)
pi.penup()
pi.setposition(width/-2+i*(width/(number+1)),height/-2)
parallel_lines(7)
## centre turtle back in the middle of the page
goto(0,0)
### list to hold the dots
x_coords = []
y_coords = []
### Draw the dots via randomint
penup()
color("blue")
for dot_num in range(num_dots):
dot_pos_x = randint (-max_coord, max_coord)
dot_pos_y = randint (-max_coord, max_coord)
goto(dot_pos_x, dot_pos_y)
dot(dot_size)
x_coords.append(dot_pos_x)
y_coords.append(dot_pos_y)
done()
Thank you in advance for anyone that can help.
Here's an implementation of the program the OP describes. If there is a line intersection, it uses Python 3 turtle's undo feature to remove the line and redraw it in the alternate color:
from turtle import Turtle, Screen
from random import randint, randrange
SCREEN_SIZE = 750
PLANK_COUNT = 8
PINHEAD_SIZE = 5
FLOOR_COLOR = "yellow"
DEFAULT_COLOR = "blue"
CROSSING_COLOR = "red"
screen = Screen()
screen.setup(SCREEN_SIZE, SCREEN_SIZE)
screen.bgcolor(FLOOR_COLOR)
# configure numbers to replicate Lazzarini's setup
NUMBER_PINS = 3408
PIN_LENGTH = 78.125
PLANK_WIDTH = screen.window_width() / PLANK_COUNT
def parallel_lines(turtle, width, height):
turtle.penup()
turtle.setheading(90)
turtle.sety(height / -2)
x_coordinates = []
for i in range(PLANK_COUNT + 1):
x = i * PLANK_WIDTH - width / 2
turtle.setx(x)
turtle.pendown()
turtle.forward(height)
turtle.penup()
turtle.left(180)
x_coordinates.append(x)
return x_coordinates
pi = Turtle(visible=False)
pi.speed("fastest")
x_coordinates = parallel_lines(pi, screen.window_width(), screen.window_height())
def crosses(x0, x1, coordinates):
for coordinate in coordinates:
if x0 <= coordinate <= x1 or x1 <= coordinate <= x0:
return True
return False
previous_crossings = crossings = 0
max_coord = screen.window_width() / 2
for pin in range(NUMBER_PINS):
x0, y0 = randint(-max_coord, max_coord), randint(-max_coord, max_coord)
pi.color(DEFAULT_COLOR)
pi.goto(x0, y0)
pi.dot(PINHEAD_SIZE)
pi.setheading(randrange(360))
pi.pendown()
pi.forward(PIN_LENGTH)
if crosses(x0, pi.xcor(), x_coordinates):
pi.undo()
pi.color(CROSSING_COLOR)
pi.dot(PINHEAD_SIZE)
pi.forward(PIN_LENGTH)
crossings += 1
pi.penup()
if previous_crossings != crossings:
estimate = (2 * PIN_LENGTH * pin) / (PLANK_WIDTH * crossings)
print(estimate)
previous_crossings = crossings
screen.exitonclick()
Now for the rest of the story. What the OP didn't mention is that this is a drawing of planks in a floor, and we're dropping pins onto it, keeping track of how many cross lines in the flooring, as a means of estimating the value of PI (π)!
Read about Buffon's needle for details. The gist is the probability of a pin crossing a line is a function of PI so we can turn the equation around, drop actual (or virtual) pins, to estimate PI.
The program outputs the running estimate for PI (π), based on pins dropped so far, to the console:
...
3.121212121212121
3.1215970961887476
3.1370772946859904
3.134418324291742
3.131768953068592
3.1381381381381384
3.1384892086330933
3.1358467983243568
3.1451612903225805
3.1454979129397733
3.1458333333333335
3.1491384432560903
3.1465005931198102
3.1438721136767316
3.144208037825059
3.144542772861357
3.1419316843345113

Categories