Skip to content
156 changes: 80 additions & 76 deletions Binary_Search_Tree/bst.py
Original file line number Diff line number Diff line change
@@ -1,89 +1,93 @@
class BST:

def __init__(self,val,left,right):
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right

def addHelper(self,root,data):

# case for reaching current leafs, base cases
if root.val < data and root.right == None:
root.right = BST(data,None,None)
return "insertion completed"
elif root.val > data and root.left == None:
root.left = BST(data,None,None)
return "insertion completed"

# else we continue tracing downwards
if root.val < data:
return self.add(root.right,data)
elif root.val > data:
return self.add(root.left,data)
def addHelper(self, root, data):
if data < root.val:
if root.left is None:
root.left = BST(data)
return "insertion completed"
else:
return self.addHelper(root.left, data)
elif data > root.val:
if root.right is None:
root.right = BST(data)
return "insertion completed"
else:
return self.addHelper(root.right, data)
else:
return "insertion failed: duplicate value"

def add(self,root,data):
if root == None:
return "insertion failed: empty root"
return self.addHelper(root,data)

def restructdata(self,root):
# base case: we reach a leaf
if root == None or (root.left == None and root.right == None):
root = None
return "restructure finished"

# need dummy nodes to compare target value to children value
v1 = float('-inf')
v2 = float('inf')
if root.left != None:
v1 = root.left.val
if root.right != None:
v2 = root.right.val

temp = root.val
if v1 > v2 or v2 == float('inf'):
root.val = root.left.val
root.left.val = temp
return self.restructdata(root.left)
else:
root.val = root.right.val
root.right.val = temp
return self.restructdata(root.right)


def removeHelper(self,root,data):
if root == None:
return "deletion failed: could not find value"

# adhering to typical bst properties
if root.val < data:
return self.removeHelper(root.right,data)
elif root.val > data:
return self.removeHelper(root.left,data)

def add(self, data, root=None):
if root is None:
root = self
return self.addHelper(root, data)

def _get_min(self, root):
current = root
while current.left is not None:
current = current.left
return current.val

def removeHelper(self, root, data):
if root is None:
return root, False

deleted = False
if data < root.val:
root.left, deleted = self.removeHelper(root.left, data)
elif data > root.val:
root.right, deleted = self.removeHelper(root.right, data)
else:
temp = root.val
v1 = float('-inf')
v2 = float('inf')
if root.left != None:
v1 = root.left.val
elif root.right != None:
v2 = root.right.val

if v1 > v2 or v2 == float('inf'):
root.val = root.left.val
root.left.val = temp
return self.restructdata(root.left)
else:
root.val = root.right.val
root.right.val = temp
return self.restructdata(root.right)

def remove(self,root,data):
if root == None:
deleted = True
# Case 1: Leaf node
if root.left is None and root.right is None:
return None, True
# Case 2: One child
if root.left is None:
return root.right, True
if root.right is None:
return root.left, True
# Case 3: Two children - replace with in-order successor
min_val = self._get_min(root.right)
root.val = min_val
root.right, _ = self.removeHelper(root.right, min_val)

return root, deleted

def remove(self, data, root=None):
if root is None:
root = self

if root == self and self.val == data and self.left is None and self.right is None:
return "deletion failed: deleting from an empty tree"
return self.removeHelper(root,data)

_, deleted = self.removeHelper(root, data)
if deleted:
return "deletion completed"
return "deletion failed: could not find value"

def search(self, data):
if data == self.val:
return True
elif data < self.val and self.left:
return self.left.search(data)
elif data > self.val and self.right:
return self.right.search(data)
return False

def inorder(self):
result = []
if self.left:
result.extend(self.left.inorder())
result.append(self.val)
if self.right:
result.extend(self.right.inorder())
return result




Expand Down
152 changes: 93 additions & 59 deletions Caterpillar_Game/Caterpillar.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,127 +10,161 @@
caterpillar.hideturtle()

leaf = t.Turtle()
leaf_shape = ((0,0),(14,2),(18,6),(20,20),(6,18),(2,14))
leaf_shape = ((0, 0), (14, 2), (18, 6), (20, 20), (6, 18), (2, 14))
t.register_shape('leaf', leaf_shape)
leaf.shape('leaf')
leaf.color('green')
leaf.penup()
leaf.hideturtle()
leaf.speed()

game_started = False
text_turtle = False
text_turtle = t.Turtle()
text_turtle.write('Press SPACE to start', align='center', font=('Arial', 18, 'bold'))
text_turtle.hideturtle()
text_turtle.penup()

score_turtle = t.Turtle()
score_turtle.hideturtle()
score_turtle.speed(0)

obstacle = t.Turtle()
obstacle.shape('circle') # You can choose any shape
obstacle.color('red') # Choose a distinct color for obstacles
obstacle.penup()
obstacle.hideturtle()
game_over_turtle = t.Turtle()
game_over_turtle.hideturtle()
game_over_turtle.penup()

num_obstacles = 5 # Number of obstacles
num_obstacles = 5
obstacles = []

for _ in range(num_obstacles):
new_obstacle = t.Turtle()
new_obstacle.shape('circle')
new_obstacle.color('red')
new_obstacle.penup()
new_obstacle.setposition(rd.randint(-200, 200), rd.randint(-200, 200))
new_obstacle.showturtle()
new_obstacle.hideturtle()
obstacles.append(new_obstacle)


def outside_window():
left_wall = -t.window_width()/2
right_Wall = t.window_width()/2
top_wall = t.window_height()/2
bottom_wall = -t.window_height()/2
(x,y) = caterpillar.pos()
outside = x < left_wall or x > right_Wall or y > top_wall or y < bottom_wall
return outside
left_wall = -t.window_width() / 2
right_wall = t.window_width() / 2
top_wall = t.window_height() / 2
bottom_wall = -t.window_height() / 2
x, y = caterpillar.pos()
return x < left_wall or x > right_wall or y > top_wall or y < bottom_wall

def game_over():
global game_started
game_started = False
caterpillar.color('yellow')
leaf.color('yellow')
t.penup()
t.hideturtle()
t.write('GAME OVER !', align='center', font=('Arial', 30, 'normal') )
t.onkey(start_game,'space')
game_over_turtle.clear()
game_over_turtle.goto(0, 0)
game_over_turtle.write('GAME OVER !', align='center', font=('Arial', 30, 'bold'))
text_turtle.goto(0, -50)
text_turtle.write('Press SPACE to restart', align='center', font=('Arial', 18, 'bold'))

def display_score(current_score):
score_turtle.clear()
score_turtle.penup()
x = (t.window_width()/2) - 70
y = (t.window_height()/2) - 70
score_turtle.setpos(x,y)
x = (t.window_width() / 2) - 70
y = (t.window_height() / 2) - 70
score_turtle.setpos(x, y)
score_turtle.write(str(current_score), align='right', font=('Arial', 40, 'bold'))

def place_leaf():
leaf.hideturtle()
leaf.setx(rd.randint(-200,200))
leaf.sety(rd.randint(-200,200))
leaf.setx(rd.randint(-200, 200))
leaf.sety(rd.randint(-200, 200))
leaf.showturtle()

def place_obstacles():
for obs in obstacles:
obs.hideturtle()
obs.setposition(rd.randint(-200, 200), rd.randint(-200, 200))
obs.showturtle()

caterpillar_speed = 2
caterpillar_length = 3
score = 0

def start_game():
global game_started
global game_started, caterpillar_speed, caterpillar_length, score
if game_started:
return
game_started = True

score = 0

text_turtle.clear()
game_over_turtle.clear()

score = 0
caterpillar_speed = 2
caterpillar_length = 3
caterpillar.shapesize(1,caterpillar_length,1)

caterpillar.goto(0, 0)
caterpillar.setheading(0)
caterpillar.color('black')
caterpillar.shapesize(1, caterpillar_length, 1)
caterpillar.showturtle()

leaf.color('green')
display_score(score)
place_leaf()
place_obstacles()

game_loop()

while True:
caterpillar.forward(caterpillar_speed)
for obstacle in obstacles:
if caterpillar.distance(leaf) < 20:
place_leaf()
caterpillar_length = caterpillar_length + 1
caterpillar.shapesize(1,caterpillar_length,1)
caterpillar_speed = caterpillar_speed + 1
score = score + 10
display_score(score)
game_over()
break
if outside_window():
def game_loop():
global game_started, caterpillar_speed, caterpillar_length, score
if not game_started:
return

caterpillar.forward(caterpillar_speed)

# Check leaf collision
if caterpillar.distance(leaf) < 20:
place_leaf()
caterpillar_length += 1
caterpillar.shapesize(1, caterpillar_length, 1)
caterpillar_speed += 0.5
score += 10
display_score(score)

# Check obstacle collision
for obstacle in obstacles:
if caterpillar.distance(obstacle) < 20:
game_over()
break

return

# Check boundary collision
if outside_window():
game_over()
return

t.ontimer(game_loop, 50)

def move_up():
if caterpillar.heading() != 270:
caterpillar.setheading(90)

def move_down():
if caterpillar.heading() != 90:
caterpillar.setheading(270)

def move_left():
if caterpillar.heading() != 0:
caterpillar.setheading(180)

def move_right():
if caterpillar.heading() != 180:
caterpillar.setheading(0)

def restart_game():
start_game()

t.onkey(start_game,'space')
t.onkey(restart_game,'Up')
t.onkey(move_up,'Up')
t.onkey(move_right,'Right')
t.onkey(move_down,'Down')
t.onkey(move_left,'Left')

text_turtle.goto(0, 0)
text_turtle.write('Press SPACE to start', align='center', font=('Arial', 18, 'bold'))

t.onkey(start_game, 'space')
t.onkey(move_up, 'Up')
t.onkey(move_right, 'Right')
t.onkey(move_down, 'Down')
t.onkey(move_left, 'Left')
t.listen()
t.mainloop()

if __name__ == '__main__':
t.mainloop()

Loading