EECS 110: Lec 16:
Projects
Aleksandar Kuzmanovic
Northwestern University
http://networks.cs.northwestern.edu/EECS110-s17/
The Rest of the Class…
the view from here…
review for Final Exam
Fri., 5/26 – project recitations by TAs (10am)
Fri., 5/26 – project recitations (Wilkinson Lab) (1-3pm)
Sun., 5/28 – Interim milestones due (11:59pm)
Wed., 5/24 –
project recitations (Wilkinson Lab) (9-12)
Wed., 5/31 – Final Exam
Tue., 5/30 –
Fri., 6/2 –
Final exam solutions (10am)
Sun., 6/4 –
Final projects due (11:59pm)
EECS 110 today…
Today in EECS 110
• All about the EECS 110 projects!
vPool
Text Clouds pyRobot
picobot
Final projects
open-ended
Final assignment
comprehensive
more choice…
Working solo or duo is OK
Pairs need to share the work equally and together
Option #1, vPool
Table
Cue ball
Billiard Ball (at least 2)
Cue (optional)
Hole (optional)
Option #1: virtual pool
VPython?
Easily installable for windows…
Not (really) installable for the Mac
www.vpython.org
A simple example
from visual import *
c = cylinder()
What's visual?
What's c?
Option #1: virtual pool
from visual import *
How many classes?
How many objects?
data members?
floor = box( pos=(0,0,0), length=4, height=0.5,
width=4, color=color.blue)
ball = sphere( pos=(0,4,0), radius=1, color=color.red)
ball.velocity = vector(0,-1,0)
dt = 0.01
while True:
rate(100)
ball.pos = ball.pos + ball.velocity*dt
if ball.y < ball.radius:
ball.velocity.y = -ball.velocity.y
else:
ball.velocity.y = ball.velocity.y - 9.8*dt
What's the
if/else
doing?
Option #1: virtual pool
Phunky Fisicks is welcome!
Collisions with walls?
Collisions with other pool balls?
Pockets?
Option #1: virtual pool
To start, just design your table, try to construct a scene which consists of
the following objects:
- table – made of walls, box objects
- holes (optional) – use sphere objects
- cueBall – another sphere
-cue (optional) – cylinder object
- billiard balls (at least 2) – sphere objects
- you also should take a look at label objects to
display game texts
After you place all the objects you should have something similar to …
Option #1: virtual pool
Option #1: virtual pool
Your main game loop should basically consist of:
while gameOver == False:
m = scene.mouse.getclick() #click event – cue hit
# get mouse position and give the cue ball a direction
# based on that
# perform movement of the cue ball as shown before
# handle collisions between different balls and
# between balls and walls
# check if game is over – when all balls have
# been put in
Option #1: virtual pool
Directing the cue ball:
temp = scene.mouse.project(normal=(0,1,0), point=(0,-side,0))
this gets a vector with the projection of the mouse on the pool table.
if temp: # temp is None if no intersection with pool table
cueBall.p = norm(temp – cueBall.pos)
The cue ball direction is now given by the vector that results from the difference of
the point where we clicked projected on the pool table and the actual position of the
cue ball
So clicking in front of the cue ball will make it go into that direction.
Option #1: virtual pool
Moving the cue ball:
dt = 0.5
t = 0.0
while dt > 0.1:
sleep(.01)
t = t + dt
dt = dt-dt/200.0
cueBall.pos = cueBall.pos + (cueBall.p/cueBall.mass)*dt
We basically start with a bigger movement increment (0.5), move the ball in the
direction we computed with the specific increment.
Each time decrease the increment to account for drop in velocity. Stop at some point
(0.1)
Option #1: virtual pool
Handling collisions:
With walls:
if not (side > cueBall.x > -side):
cueBall.p.x = -cueBall.p.x
if not (side > cueBall.z > -side):
cueBall.p.z = -cueBall.p.z
When hitting wall, change directions
Option #1: virtual pool
When is a ball in?
if math.sqrt(math.pow(abs(ball1.x-hole1.x),2) +
math.pow(abs(ball1.z-hole1.z),2)) <= hole1.radius*2:
ballin = 1
ball1.visible = 0
ball1.y = 50
Holes are just spheres so we determine intersection between ball and hole same way
as for different balls.
When ball is in we do a few things:
Signal that a ball has been put in (might be useful later)
Make the specific ball invisible
Move it out of the way
Option #1: virtual pool
Handling the game logic?
• Need a way to keep track of players taking turns.
• Suggestion: use a simple variable for that which changes after
every hit (take into account if balls have been sunk or not)
• Players need to be aware of the game flow, so show labels that display
which player has turn, when the game was won and by whom
• The game is finished when all the balls are in, that is when all the balls
are invisible. You can use that for check.
Project #2: text clouds
tag
cloud
Project #2: text clouds
text cloud
Summary of the words
in a body of text, sized
and painted according
to their frequency.
Demo:
http://blue.cs.northwestern.edu/~ionut/index.html on:
http://www.gutenberg.org/files/74/74-h/74-h.htm
http://www.gutenberg.org/files/76/76-h/76-h.htm
Text-cloud history
http://chir.ag/phernalia/preztags/
Project #2: text clouds
From text…
1. Start with entered webpage (URL)
2. Read in text
3. Create list of words out of text
4. "Clean" the words
5. "Stem" the words
6. Count the words
7. Return a string with frequencies
8. Add advanced features…
… to cloud
Text Clouds, an example
http://networks.cs.northwestern.edu/EECS110-s17/projects/
project2/page1.htm
ignore this
link for now
Spamming spammers spammed spam. Spam spam spam! I love spam! Page 2
['spamming', 'spammers', spammed', 'spam.', 'spam', 'spam', 'spam!',
'I', 'love', 'spam!', 'page', '2']
['spamming', 'spammers', spammed', 'spam', 'spam', 'spam', 'spam',
'love', 'spam', 'page', '2']
['spam', 'spam', spam', 'spam', 'spam', 'spam', 'spam',
'love', 'spam', 'page', '2']
Project #2: text clouds
An Approach
Develop the basic application the usual way (IDLE)
Use our code to read HTML, but don't bother
writing it yet…
Once you have things working, try writing
HTML/searching beyond depth 1/etc (NEXT SLIDE)
Once you have everything working, transfer your .py files
to your webspace. Set up the HTML wrapper files & go!
Personalize! The project has a number of references…
Project #2: searching beyond depth 1
An Approach (1/2)
def mtcURL(url):
toVisit[url] = 0 #toVisit is a dictionary
visited[url] = 1 #visited is a dictionary
returnText = ''
while len(toVisit) != 0:
[url, depth] = toVisit.popitem()
[textSite, listUrls] = getHTML(url)
Project #2: searching beyond depth 1
An Approach (2/2)
…
for urlItem in listUrls:
if visited.has_key(urlItem) == False \
and depth < DEPTH:
visited[urlItem] = 1
toVisit[urlItem] = depth + 1
wordList = textSite.split()
…
pyRobot
option #3
Pt A
2d Roomba simulator
Goal: get from Pt A to Pt B
Pt B
pyRobot
Pt A
option #3
IMPORTANT:
ROBOT CAN START
ANYWHERE!
Pt B
IMPORTANT:
GOAL CAN BE
ANYWHERE
Project #3:
while True:
SENSE
[x,y,thd], bump = self.getData()
pyRobot
Project #3:
while True:
SENSE
pyRobot
Robot control continuously runs three things:
PLAN
[x,y,thd], bump = self.getData()
if bump[0] == True or bump[1] == True:
print 'BUMP!',
print ' [Left bump sensor:', bump[0], ']
print ' [Right bump sensor:', bump[1], ']
robotTask = STOP
STOP is one of the robot's states. Every
40th of a second, the robot runs through
this loop, sets the robot's state and sets the
velocities accordingly. Don't sleep!
',
'
Project #3:
while True:
SENSE
pyRobot
Robot control continuously runs three things:
PLAN
ACT
[x,y,thd], bump = self.getData()
if bump[0] == True or bump[1] == True:
print('BUMP!’)
print(' [Left bump sensor:', bump[0], ']
print(' [Right bump sensor:', bump[1], ']
robotTask = STOP
STOP is one of the robot's states. Every
40th of a second, the robot runs through
this loop, sets the robot's state and sets the
velocities accordingly. Don't sleep!
‘)
’)
if robotTask == STOP:
self.setVels(0,0)
robotTask = KBD
Project #3:
BASIC ROBOT COMMANDS:
STOP:
self.setVels(0,0)
GO FORWARD:
self.setVels(FV,0)
GO BACKWARD:
self.setVels(-FV,0)
GO CLOCKWISE:
self.setVels(0,RV)
GO COUNTERCLOCKWISE:
self.setVels(0,-RV)
pyRobot
Project #3:
pyRobot
To make the robot go forward a set amount use
The max forward velocity: FV
Example...
TIME_ONE_CIRCLE_OVER = RADIUS*2 / FV
if state==DO_GO_LEFT_LITTLE:
#FIGURE OUT HOW TO TRAVEL
pause_stop = time.time() + TIME_ONE_CIRCLE_OVER
State = GOING_LEFT_LITTLE
if pause_stop > time.time() and state==GOING_LEFT_LITTLE:
self.setVels(0,0) #STOP!
elif state==GOING_LEFT_LITTLE:
self.setVels(FV,0) #KEEP GOING!
Project #3:
pyRobot
To rotate the robot use the Max Rotational Velocity: RV
Example...
TIME_ROTATE_90_DEGREES = 90.0 / RV
if state==DO_ROTATE_LEFT_DOWN: #c-cwise
#FIGURE OUT HOW LONG TO ROTATE
pause_stop = time.time() + TIME_ROTATE_90_DEGREES
State = ROTATING_LEFT_DOWN
if pause_stop > time.time() and state==ROTATING_LEFT_DOWN:
self.setVels(0,0) #STOP!
elif state==ROTATING_LEFT_DOWN:
self.setVels(0,-RV) #KEEP GOING!
Project #3:
One way to traverse the space is
GO DOWN UNTIL BUMP SOMETHING,
GO RIGHT A LITTLE
GO UP UNTIL BUMP SOMETHING
GO RIGHT A LITTLE
DO THIS UNTIL HIT CORNER THEN
REVERSE....
pyRobot
Maps
are set at the very bottom of the main.py file:
Required
We may test on any map with rectangular objects
Project #4: Picobot Returns!
Project 4: Picobot
Basic idea: implement Picobot (the
homework problem from Week 1)
Picobot is a finite-state machine!
Requirements:
Graphical output
Read Picobot program from a file*
Read maze description from a file
Track visited/unvisited squares
Prohibit illegal moves
Reading a Picobot program from a file
map3.txt contains solution to the HW0 problem
Syntax:
0 xxxx -> N 1
0 Nxxx -> S 2
0 xExx -> W 3
0 xxWx -> E 4
0 xxxS -> N 1
0 xEWx -> N 1
...
Reading a Picobot program from a file
Importing map3.txt into the program
f = open('map3.txt', 'r')
text = f.read()
L = text.split()
f.close()
for i in range(len(L)):
if L[i] == '->':
if L[i-1] == 'xxxx':
#ETC
Graphics Library
• Graphics22.py (recommended)
Graphics Library
• Graphics22.py (recommended)
• You can use others as well:
– E.g., vPython
Plotting a window
from graphics22 import *
def main():
win = GraphWin("MyWindow", 400, 400)
Plotting a yellow rectangle
from graphics22 import *
def main():
win = GraphWin("MyWindow", 400, 400)
p1 = Point(0,355)
p2 = Point(400,400)
rec1 = Rectangle(p1,p2)
rec1.setFill("yellow“)
rec1.setOutline("yellow")
rec1.draw(win)
Plotting an Exit button
…
#Exit button
p1 = Point(122,360)
p2 = Point(198,390)
square1 = Rectangle(p1,p2)
square1.setFill("gray")
square1.draw(win)
p = square1.getCenter()
t = Text(p, "Exit")
t.draw(win)
Accepting a mouse click
…
#loop
while True:
K = win.getMouse()
if K.getX() > 122 and \
K.getX() < 198 and \
K.getY() > 360 and \
K.getY() < 390:
win.close()
exit("The end“)
Accepting a mouse click
…
#loop
while True:
K = win.getMouse()
if K.getX() > 122 and \
K.getX() < 198 and \
K.getY() > 360 and \
K.getY() < 390:
win.close()
exit("The end“)
Example Functions
createOneRow( n )
createBoard(width, height)
done(X) #end of game: all visited in matrix X
next_state(Cstate,Icurr,Jcurr,X,STATE)
next_direction(Cstate,Icurr,Jcurr,X,DIRECTION)
main(nameOfFile)
What’s due?
Sun., 5/28 –
Interim milestones due (11:59 pm)
milestone.txt
– Name(s)
– Project chosen
– Description of User Interface
What is your approach & plan?
milestone.py
– Classes and functions with docstrings
– 60-80+ lines of working, tested code
What’s due?
Sun., 6/4 –
Final projects due (11:59 pm)
final.txt
final.py
– Name(s)
– Classes and functions with docstrings
– Project chosen
– Working, tested code
– Description of User Interface
How do we run / play your project?
What features did you implement?
What was your approach & plan?
A final milestone
This and next week
review for Final Exam
Fri., 5/26 – project recitations by TAs (10am)
Wed., 5/24 –
Fri., 5/26 –
project recitations (Wilkinson Lab) (1-3pm)
Interim milestones due (11:59pm)
Tue., 5/30 – project recitations (Wilkinson Lab) (9-12)
Wed., 5/31 – Final Exam
Sun., 5/28 –
Fri., 6/2 –
Final exam solutions (10am)
Sun., 6/4 –
Final projects due (11:59pm)
Be inventive – we will
reward that!
Ask TAs for help
Good luck with the
projects!
© Copyright 2025 Paperzz