# List imports here:
import turtle
import random
import math
# List constants here (NO MAGIC NUMBERS!):
NUMBER_DARTS = 1000
LEFT_BOUND = -2
RIGHT_BOUND = 2
TOP_BOUND = -2
BOTTOM_BOUND = 2
PEN_SIZE = 3
SQUARE_WIDTH = 2
SQUARE_TOP = 1
SQUARE_LEFT = -1
DOT_SIZE = 5
# Draws square given turtle, width and top left XY position
# param grapher (Turtle)
# param width (int)
# param topLeftX (int)
# param topLeftY (int)
def drawSquare( grapher, width, topLeftX, topLeftY ):
grapher.penup()
grapher.setpos(topLeftX, topLeftY)
grapher.setheading(0)
grapher.pendown()
grapher.forward(width)
grapher.right(90)
grapher.forward(width)
grapher.right(90)
grapher.forward(width)
grapher.right(90)
grapher.forward(width)
grapher.penup()
# Draws line given turtle and endpoints
# param grapher (Turtle)
# param xStart (int)
# param yStart (int)
# param xEnd (int)
# param yEnd (int)
def drawLine( grapher, xStart, yStart, xEnd, yEnd ):
grapher.penup()
grapher.setpos(xStart, yStart)
grapher.setheading(0)
angle_rad = math.atan2(yEnd - yStart, xEnd - xStart)
angle = angle_rad * 180.0 / math.pi
dist = math.sqrt((yEnd - yStart) * (yEnd - yStart) + (xEnd - xStart) * (xEnd - xStart))
grapher.pendown()
grapher.left(angle)
grapher.forward(dist)
grapher.penup()
# Draws a dot with given x, y coordinates
# param grapher (Turtle)
# param x (double)
# param y (double)
# param color (string)
def drawDot( grapher, x, y, color ):
#grapher.pencolor(color)
grapher.penup()
grapher.setpos(x, y)
grapher.dot(DOT_SIZE, color)
grapher.penup()
# Sets up 4X4 area with x- and y-axis to simulate dartboard
# param board - window that will simulate board
# param grapher - turtle that will do drawing
def setUpDartboard( board, grapher ):
# set up 4X4 area and set pensize
board.setworldcoordinates(LEFT_BOUND, TOP_BOUND, RIGHT_BOUND, BOTTOM_BOUND)
grapher.pensize(PEN_SIZE)
# Draw board
drawSquare( grapher, SQUARE_WIDTH, SQUARE_LEFT, SQUARE_TOP )
# Draw x- and y-axes
drawLine( grapher, LEFT_BOUND, 0, RIGHT_BOUND, 0 )
drawLine( grapher, 0, TOP_BOUND, 0, BOTTOM_BOUND )
# (Predicate Function)
# Determines whether or not dart falls inside unit circle with center at 0,0
# param dart (Turtle)
# return True if in circle, False if not
def inCircle( x, y ):
if x*x + y*y <= 1:
return True
else:
return False
# Algorithm for Monte Carlo simulation
# param numberDarts (int)
# param grapher (Turtle)
# return approximation of pi (float)
def montePi( numberDarts, grapher ):
# Initialize inCircleCount counter (THIS IS AN ACCUMULATOR)
inCircleCount = 0
# Loop for numberDarts
for i in range(0, numberDarts):
# Get random coordinate and position dart
x = random.random() * 2 - 1
y = random.random() * 2 - 1
# Draw red dot AND INCREMENT COUNTER if in circle, blue dot if not
if inCircle(x, y) == True:
inCircleCount = inCircleCount + 1
drawDot(grapher, x, y, "red")
else:
drawDot(grapher, x, y, "blue")
# return approximation of pi
return float(inCircleCount) / numberDarts * 4
#Performs Monte Carlo simulation to generate approximation of Pi
def main():
# Get number of darts for simulation from user
# Note continuation character <\> so we don‘t go over 78 columns:
print("This is a program that simulates throwing darts at a dartboard\n" \
"in order to approximate pi: The ratio of darts in a unit circle\n"\
"to the total number of darts in a 2X2 square should be\n"\
"approximately equal to pi/4")
#Create window, turtle, set up window as dartboard
window = turtle.Screen()
t = turtle.Turtle()
setUpDartboard(window, t)
PI = montePi( NUMBER_DARTS, t )
# Include the following code in order to update animation periodically
# instead of for each throw:
window.tracer(500)
#Conduct simulation and print result
print "Pi is approximately equal to " + str(PI)
#Keep the window up until dismissed
window.exitonclick()
main()
如图: