Exemplo n.º 1
0
	def get_color(self, b):
		test.record()
		outputs = [b.outputs[0,0] + 0, b.outputs[0,1] + 0]
		for i in range(2):
			outputs[i] = (outputs[i] - self.min[i]) * self.scaling[i]
		color = [outputs[0], outputs[1], outputs[1] - outputs[0]]
		for i, x in enumerate(color):
			if math.isnan(x):
				color[i] = 1
		color = [int(50 + i * 205) for i in color]
		color = [min(i, 255) for i in color]
		color = [max(i, 0) for i in color]
		test.record("palette")
		return color
		#except ValueError as e:
		#	print "Met a ValueError while getting color"
		#	test.record("palette")
		#	return (255, 255, 255)
		
Exemplo n.º 2
0
	def repel(self, other = None, circle = None, radius = -1, corners = 0):
		prefix = "bee:update:physics:project:push:repel_loop:repel"
		'''
		returns the minimum displacement, if any, 
		required to push the other convex out.

		 bool circle:  - tells you whether it's a circle or a polygon
		  int radius:  - tells you the radius for collision
		               - if negative, use the object's own radius
		       other:  - does... nothing?
		bool corners:  - tells you whether or not to spend extra time and
		                 push using corners too.
		'''

		'''the basic way that this works is you
		look at each potential separating axis
		find the shadow of both guys on each one
		and push the guy out out as quickly as possible.'''
		





		test.add_sticky(prefix+":normals")
		'''set the normals to consider'''
		my_ns = [k for k in self.shadowDict]
		other_ns = []

		if radius < 0 and circle:
			radius = circle.radius

		if circle:
			if corners:
				for p in self.points:
					if self.use[p]:
						disp = (circle.xy - p).astype(float)
						dist = linalg.norm(disp)
						if dist == 0:
							continue
						disp /= dist
						other_ns.append(disp)
		else:
			other_ns = [k for k in other.shadowDict]
		
		ns_to_consider = my_ns + other_ns
		#ns_to_consider = no_parallels2(my_ns + other_ns, vector_slope)
		test.remove_sticky(prefix+":normals")









		test.add_sticky(prefix+":displacements")
		'''find all possible displacements'''
		disps = []
		for n in ns_to_consider:
			if n in self.shadowDict:
				my_sh = self.shadowDict[n]
			else:
				my_sh = find_shadows([n], self.points)[n]

			my_l, my_r = my_sh

			if circle:
				center_sh = find_shadows(([n]), [circle.xy])[n]
				other_sh = (center_sh[0] - radius, center_sh[0] + radius)
			else:
				if n in other_sh:
					other_sh = self.shadowDict[n]
				else:
					other_sh = find_shadows([n], other.points)[n]

			other_l, other_r = other_sh

			if my_r <= other_l or my_l >= other_r:
				test.remove_sticky(prefix+":displacements")
				return matrix([0,0])
			else:
				move_it_left = my_l - other_r
				move_it_right = my_r - other_l
				if move_it_right < abs(move_it_left):
					disps.append((n, move_it_right))
				else:
					disps.append((n, move_it_left))

		test.remove_sticky(prefix+":displacements")

		'''pick the shortest displacement'''
		disps = filter(lambda (normal, distance): abs(distance) != float('infinity'), disps)
		if disps:
			for n,m in disps:
				push = m * n
				#test.lines.append(((circle.xy[0,0], circle.xy[0,1]), ((circle.xy + push)[0,0], (circle.xy + push)[0,1])))
			best_n, best_move = min(disps, key = lambda (n, m): abs(m))
			#best_n = best_n / linalg.norm(best_n)
			push = best_move * best_n
			#test.lines.append(((circle.xy[0,0], circle.xy[0,1]), ((circle.xy + push)[0,0], (circle.xy + push)[0,1])))

			direction = best_n*rotation
			#if (best_n*vdir.T)[0,0] > 0:
			circle.vxy = (circle.vxy * direction.T)[0,0] * direction
			test.record(prefix+":shortest")
			return best_move * best_n
		else:
			"no collision 2"
			x = matrix([0,0])
			test.record(prefix+":no collision")
			return x
Exemplo n.º 3
0
    def update(self, dt, key_states, key_presses, allow_randomize=1):
        '''physics, thinking, moving'''
        try:
            self.lifetime += 1
        except:
            print "temporary transition error"

        if self.skipupdate:
            self.skipupdate = 0
            return

        '''This is where you cruise without physics and without thinking'''
        if not self.slow:
            self.dt = dt
            self.xy += self.vxy * self.dt
            return
        test.add_sticky('bee:update')
        test.add_sticky("bee:update:start")

        self.prevpos = self.xy * 1
        fullname = self.name + str(self.ancestry)

        super(Bee, self).update(dt, key_states, key_presses)

        test.remove_sticky("bee:update:start")
        test.add_sticky("bee:update:health,birth,eating")
        self.timesincelastshot += dt

        # for b in self.bullets:
        #    b.update(dt, key_states, key_presses)

        if not self.room.stasis:
            self.update_health(dt)
            self.considergivingbirth()

        self.friends *= 0.9
        self.friendsrelpos *= 0.9
        for p in self.objectsinview:
            if p.kind == "bullet":
                p.hit_bee(self)
            elif p.name != self.name and settings[SWARMING_PEER_PRESSURE] and p.kind == "bee":
                othervel = p.vxy - self.vxy
                self.friendsrelpos = p.xy - self.xy
                self.vxy += settings[SWARMING_PEER_PRESSURE] * othervel
            elif p.kind == "player" and not self.room.stasis:
                self.eat_player()

        self.timesincelastthought += dt

        test.remove_sticky("bee:update:health,birth,eating")

        test.add_sticky("bee:update:thinking")
        if self.timesincelastthought > self.responsetime:
            test.add_sticky("bee:update:thinking:inputs")
            test.add_sticky("bee:update:thinking:inputs:collection")
            test.record()
            self.timesincelastthought -= self.responsetime

            infoz = None
            LIDAR = 1
            POINTCHECK = 2
            TILES = 3
            vision_mode = LIDAR
            if vision_mode == LIDAR:
                c = int(self.xy[0, 0] / bw)
                r = int(self.xy[0, 1] / bw)
                infoz = self.room.visiondirectory[
                    c % graphics.world_tw][r % graphics.world_th]
                self.wallproximities = infoz
                test.record("bee:update:thinking:inputs:vision")
            elif vision_mode == POINTCHECK:
                test.record()
                a = int(self.xy[0, 0])
                b = int(self.xy[0, 1])
                infoz = [self.room.pointcheck(
                    (a + eye_x, b + eye_y)) for eye_x, eye_y in self.eyepoints]
                test.record("bee:update:thinking:inputs:pointchecks")
            else:
                infoz = []
                test.record()
                a = int(self.xy[0, 0])
                b = int(self.xy[0, 1])
                points_to_check = ((a + eye_x, b + eye_y)
                                   for eye_x, eye_y in self.eyepoints)
                self.see_bullet = False
                for i, (x, y) in enumerate(points_to_check):
                    c = int(x / bw)
                    r = int(y / bh)
                    objects = self.room.object_directory[
                        c % graphics.world_tw][r % graphics.world_th]
                    g = i % 2
                    if g == 0:
                        infoz.append(
                            any(other.kind == "bullet" for other in objects))
                        if infoz[-1]:
                            self.see_bullet = True
                    else:
                        infoz.append(self.room.pointcheck((x, y)))
                        # walls
                test.record("bee:update:thinking:inputs:tiles")

            # go = time.time()
            # t = [math.sin(go), math.sin(go/2.3), math.sin(go)%1.5]
            test.remove_sticky("bee:update:thinking:inputs:collection")
            test.add_sticky("bee:update:thinking:inputs:actually wraparound")
            # center = matrix([graphics.world_w/2, graphics.world_h/2])

            if STALK_CAMERA:
                self.stalkcamera()
            disp_to_p = self.player.xy - self.xy

            if settings[WRAPAROUND_TRACKING]:
                disp_to_p += graphics.world_center
                disp_to_p[0, 0] %= graphics.world_w
                disp_to_p[0, 1] %= graphics.world_h
                disp_to_p -= graphics.world_center

            test.remove_sticky(
                "bee:update:thinking:inputs:actually wraparound")
            test.add_sticky("bee:update:thinking:inputs:player offset")
            player_sight_scale = 0.02
            disp_to_p *= player_sight_scale
            dist = linalg.norm(disp_to_p)

            sharpness = 1
            radius = 2

            if dist > 0:
                disp_to_p *= settings[SENSITIVITY_TO_PLAYER] / \
                    (dist * (1 + 2 ** (sharpness * (dist - radius))))

            # tweaked_disp *= self.sensitivity

            # dispx, dispy = tuple(array(disp_to_p)[0])
            # BE REALLY CAREFUL WHEN DIVIDING THIS BY STUFF THEY ARE INTEGERS
            test.remove_sticky("bee:update:thinking:inputs:player offset")
            test.add_sticky(
                "bee:update:thinking:inputs:packaging and nodetags")

            disps = [disp_to_p[0, 0], disp_to_p[0, 1]]

            # dvx = self.player.vxy[0, 0] - self.vxy[0, 0]
            # dvy = self.player.vxy[0, 1] - self.vxy[0, 1]

            inputs = disps + [1 - distance for distance in infoz] + [self.health / settings[
                MAX_HEALTH]] + [expit(self.vxy[0, 0]), expit(self.vxy[0, 1])]  # 1

            # self.brain.nodetags[(0, 0)] = "verbatim", "player x"
            # self.brain.nodetags[(0, 1)] = "verbatim", "player y"
            # i = 2
            # for vector in self.eyepoints:
            #     self.brain.nodetags[(0,i)] = "vector", vector
            #     i+=1
            # self.brain.nodetags[(0,i)] = "verbatim", "health"
            # i+=1
            # self.brain.nodetags[(0,i)] = "verbatim", "x velocity"
            # i+=1
            # self.brain.nodetags[(0,i)] = "verbatim", "y velocity"
            # i+=1

            test.remove_sticky(
                "bee:update:thinking:inputs:packaging and nodetags")
            # inputs += [self.friends[0, 0], self.friends[0, 1],
            # self.friendsrelpos[0, 0], self.friendsrelpos[0, 1]] # 4

            test.remove_sticky("bee:update:thinking:inputs")

            test.add_sticky("bee:update:thinking:compute")
            # Note: output is now a matrix!

            # print inputs
            # self.brain.set_inputs(matrix(inputs))
            self.brain.compute(inputs)
            outputs = matrix([0.0, 0.0])
            self.brain.get_outputs(outputs)

            self.outputs = outputs[:, :] + 0

            # self.outputs = outputs = self.brain.compute(inputs)
            test.remove_sticky("bee:update:thinking:compute")
            test.add_sticky("bee:update:thinking:outputs")
            self.up = 2 * outputs[0, 0] - 1
            # down = outputs[1]
            self.leftright = 2 * outputs[0, 1] - 1
            # print linalg.norm(self.vxy)

            self.color = self.room.painter.get_color(self)

            '''self.color = [outputs[0]*3, (outputs[1] - 0.75)*4, (self.leftright + 0.7) / 2]
                                                self.color = [int(i*255) for i in self.color]
                                                self.color = [max(a, 0) for a in self.color]
                                                self.color = [min(a,255) for a in self.color]'''

            '''
            if outputs[2] > 0 and self.timesincelastshot > 1000:
                self.timesincelastshot = 0
                direction = matrix([outputs[3],outputs[4]])
                direction = disp_to_p
                direction /= linalg.norm(direction)
                b = bullet.Bullet(self, self.player, self.room, direction * outputs[2] * 2)
                b.xy = self.xy + matrix([0, 0])
                self.room.bullets.append(b)
                self.health -= 0.05'''
            test.remove_sticky("bee:update:thinking:outputs")
        test.remove_sticky("bee:update:thinking")

        test.add_sticky("bee:update:physics")

        test.add_sticky("bee:update:physics:basicmovement")
        if settings[CREATURE_MODE] == 0:
            '''bees'''
            self.vxy += gravity * dt
            self.dvxy = self.up * jumpvel * dt + \
                self.leftright * yogroundacc * dt
            self.vxy += dt * self.dvxy
            self.vxy *= speed_decay**dt
        else:
            '''fleas'''
            self.vxy += 2 * gravity * dt

            if self.grounded:
                self.vxy[0, 0] = self.leftright * 0.3
                if self.up > 0.5:
                    self.dvy = self.up * jumpvel * 20000
                    self.vxy += self.dvy
                    self.health -= settings[COST_OF_JUMP]
            else:
                self.vxy[0, 0] += self.leftright * 0.01

            self.vxy *= speed_decay**dt

        # if abs(self.vxy[0, 0]) > maxvelx:
        #    print self.vxy, "has too much horizontal"
        #    self.vxy[0, 0] *= maxvelx / abs(self.vxy[0, 0])

        # if linalg.norm(self.vxy) > maxvel:
        #    self.vxy /= linalg.norm(self.vxy)
        #    self.vxy *= maxvel

        # collision testing and further modification of position and velocity
        self.grounded = 0
        # num_deflections = 0
        del self.normals[:]
        test.remove_sticky("bee:update:physics:basicmovement")
        self.project()  # This will consume dt

        test.add_sticky("bee:update:physics:worldwrap")

        # stay in the box
        self.xy[0, 0] = self.xy[0, 0] % graphics.world_w
        self.xy[0, 1] = self.xy[0, 1] % graphics.world_h

        test.remove_sticky("bee:update:physics:worldwrap")

        test.add_sticky("bee:update:physics:teleport")
        # maybe teleport back
        if allow_randomize and self.room.pointcheck((int(self.xy[0, 0]), int(self.xy[0, 1]))):
            if (self.lastnonwall[0, 0] < 0):
                self.randomize_position()
            else:
                self.xy = self.lastnonwall * 1
                self.health -= 0.1
                self.vxy *= -1
        else:
            self.lastnonwall = self.xy * 1
        # if linalg.norm(self.prevpos - self.xy) < 200:
        #    test.lines.append( ( (int(self.prevpos[0, 0]), int(self.prevpos[0, 1]) ), (int(self.xy[0, 0]), int(self.xy[0, 1]) ) ) )

        c = int(self.xy[0, 0] / bw)
        r = int(self.xy[0, 1] / bh)
        if self.room.tiles[c][r].name == "bounce":
            self.vxy[0, 1] += -0.001 * dt

        test.remove_sticky("bee:update:physics:teleport")

        test.remove_sticky("bee:update:physics")
        self.age()

        test.remove_sticky('bee:update')
Exemplo n.º 4
0
def look2(room, my_x, my_y, vx, vy, dt=1.0, bw=graphics.bw, bh=graphics.bh):
    '''returns ALL tiles that cover the path, even by just an edge or point.'''
    # Trivial case where either vx or vy is zero
    if vx == 0 or vy == 0:
        for x, y in collision.find_tiles_rect(my_x, my_y, vx, vy, dt, bw, bh):
            # Life
            if 0 <= x < graphics.world_w / bw and 0 <= y < graphics.world_h / bh and room.object_directory[x][y]:
                return (x, y), room.object_directory[x][y]
            # Wall
            elif 0 <= x < graphics.world_w / bw and 0 <= y < graphics.world_h / bh and room.tiles[x][y].name != 'empty':
                return (x, y), -1
        else:
            return 0

    # If the above if statement is false we may assume vx != 0 and vy != 0

    # Find the starting position
    x = int(math.floor(my_x / bw))
    y = int(math.floor(my_y / bh))

    coordlist = []  # Include everthing touching the starting point.

    xstep = int(math.copysign(1, vx))
    ystep = int(math.copysign(1, vy))

    newtiles = []
    # and 0 <= my_x <= graphics.world_w and 0 <= my_y <= graphics.world_h:
    while dt >= 0 and len(newtiles) < 100:
        # my_x %= graphics.world_w
        # my_y %= graphics.world_h
        # Set x to next
        if xstep > 0:
            x_to_next = (x + 1) * bw - my_x
        else:
            x_to_next = x * bw - my_x
        # With current setting this is never going to happen, so this really is
        # optional.
        if vx == 0:
            t_next_x = float('infinity')
            print "Hey, vx isn't supposed to be zero"
        else:
            t_next_x = x_to_next / vx

        if ystep > 0:
            y_to_next = (y + 1) * bw - my_y
        else:
            y_to_next = y * bw - my_y
        # With current setting this is never going to happen, so this really is
        # optional.
        if vy == 0:
            t_next_y = float('infinity')
            print "Hey, vy isn't supposed to be zero"
        else:
            t_next_y = y_to_next / vy

        if t_next_x < 0 or t_next_y < 0:
            print "hmm, interesting", t_next_x, t_next_y

        # Comparing time
        if t_next_x < t_next_y:
            x += xstep
            dt -= t_next_x
            my_x += vx * t_next_x  # This might sometimes create a nan.
            my_y += vy * t_next_x
        # elif t_next_x > t_next_y:
        else:
            y += ystep
            dt -= t_next_y
            my_y += vy * t_next_y
            my_x += vx * t_next_y
        # Life
        x0 = x % (graphics.world_w / bw)
        y0 = y % (graphics.world_h / bh)
        x0 = int(x0)
        y0 = int(y0)
        if (x0, y0) in newtiles:
            print "hey, this tile is already here"
            break
        newtiles.append((x0, y0))
        #test.tiles.append((x0, y0))
        if room.object_directory[x0][y0]:
            return (x0, y0), room.object_directory[x0][y0]
        # Wall
        elif room.tiles[x0][y0].name != 'empty':
            if len(newtiles) > 1:
                return (x0, y0), -1
    return 0
    test.record('blah')
Exemplo n.º 5
0
def handle_player_input(key_presses, key_ups, key_states, gameobjects):
    time_gap = False
    try:
        r = gameobjects["room"]
        p = gameobjects["player"]
        c = gameobjects["camera"]
        world = gameobjects["world"]
        h = gameobjects["hive"]
        screen = gameobjects["screen"]
    except:
        raise Exception("Missing gameobjects. Have following keys:", [key for key in gameobjects])

    clicks.get_more_clicks()
    global time_to_quit
    # Handle player input
    if key_ups[pygame.K_e]:
        if r.bees:
            # for x in r.bees + r.food + [p] + r.bullets:
            #   x.draw(world)
            # c.draw()
            # pygame.display.flip()
            """this is for picking the closest bee"""
            """minbee = r.bees[0]
            for b in r.bees:
                if linalg.norm(b.xy - p.xy) < linalg.norm(minbee.xy - p.xy):
                    minbee = b"""

            minbee = random.choice(r.bees)
            messages.say("Loading", down=1)
            pygame.display.flip()
            minbee.visualize_intelligence(world, c)
            p.displaycolor = [255, 255, 255]
            pygame.draw.circle(world, [0, 0, 0], array(p.xy.astype(int))[0], int(p.forcefield))
            pygame.draw.circle(world, [255, 255, 255], array(p.xy.astype(int))[0], int(p.forcefield), 1)
            p.draw(world)
            # c.xy = minbee.xy * 1
            # c.updatesight()
            c.draw()
            pygame.display.flip()
            minbee.sample_path(world)
            c.draw()
            pygame.display.flip()
            waitForKey(pygame.K_w)
            time_gap = True

    if time_to_quit:
        game_progress.save_game(r)
        return

    test.record()
    world.blit(r.background, (0, 0))
    test.record("blitting background")

    togglers = {pygame.K_r: SHOW_EYES, pygame.K_h: SHOW_HELP, pygame.K_t: GENERATE_RANDOM_MAP, pygame.K_n: SHOW_NAMES}

    for key, variable in togglers.iteritems():
        if key_ups[key]:
            settings[variable] = not settings[variable]

    if key_ups[pygame.K_m]:
        print framecount
        r.madness += 1
        r.madness %= 5
        for b in r.bees:
            b.madness = r.madness

    if key_ups[pygame.K_a]:
        if key_states[pygame.K_UP]:
            p.shoot("up")
        else:
            p.shoot()

    if key_ups[pygame.K_x]:
        r.stasis = not r.stasis

    if key_ups[pygame.K_z]:
        print pygame.mouse.get_pos()

    # gameobjects["info_panel"].handle_event(pygame.mouse.get_pos(), "mouseover")

    """All mouse click stuff"""
    if clicks.mouseups[0]:
        event_taken = False
        if gameobjects["info_panel"].rect.collidepoint(pygame.mouse.get_pos()):
            mx, my = pygame.mouse.get_pos()
            x, y = mx - gameobjects["info_panel"].rect.x, my - gameobjects["info_panel"].rect.y

            event_taken = gameobjects["info_panel"].handle_event((x, y), "click")

        if not event_taken:
            for b in r.bees:
                b.skipupdate = True
            options = [
                "Move to another map",
                "Random 60 x 25",
                "Random 35 x 35",
                "Random 60 x 60",
                "Examine bee",
                "Save bees",
                "Extinction",
                "Load bees",
                "Delete bees",
                "Tweak variables",
                "Modify map",
                "View Shortcuts",
                "quit",
            ]
            choice = getChoiceUnbounded("select option", options, allowcancel=1)

            if choice != "cancel":
                if choice == "quit":
                    time_to_quit = True

                elif choice in ["Move to another map", "Random 60 x 25", "Random 35 x 35", "Random 60 x 60"]:
                    level = choice
                    if choice == "Move to another map":
                        level = enteredlevel()
                    if level == "quit":
                        time_to_quit = True

                    if level != "cancel":
                        print "MAGIC LEVEL MOVE WHOA"
                        gameobjects2 = {}
                        gameobjects2["room"] = r
                        gameobjects2["player"] = p
                        gameobjects2["hive"] = h
                        gameobjects2["camera"] = c
                        gameobjects2["world"] = world
                        gameobjects2["screen"] = screen

                        move_to_level(level, gameobjects2)

                        try:
                            r = gameobjects2["room"]
                            p = gameobjects2["player"]
                            c = gameobjects2["camera"]
                            world = gameobjects2["world"]
                            h = gameobjects2["hive"]
                            screen = gameobjects2["screen"]
                        except:
                            raise Exception("Missing gameobjects. Have following keys:", [key for key in gameobjects])

                elif choice == "Extinction":
                    if getChoiceUnbounded("Kill all bees?", ["no", "yes"], allowcancel=1) == "yes":
                        for b in r.bees:
                            b.health = -20
                        for b in r.bees + r.deadbees:
                            b.dead = 2
                        t.data = []

                elif choice == "Examine bee":
                    """this thing lets you examine the closest bee to you"""
                    if r.bees:
                        minbee = r.bees[0]
                        for b in r.bees:
                            if linalg.norm(b.xy - p.xy) < linalg.norm(minbee.xy - p.xy):
                                minbee = b
                        for x in r.bees + r.food + [p] + r.bullets:
                            x.draw(world)
                        c.draw()
                        pygame.display.flip()

                        while not time_to_quit:  # quit should work fine here
                            choice = getChoiceUnbounded(
                                "Examining nearest bee...what feature?",
                                ["Neural Network", "Movement"],
                                allowcancel=True,
                            )

                            if choice == "Neural Network":
                                command = minbee.show_brain(world)
                                if command:
                                    return

                            elif choice == "Movement":
                                c.draw()
                                messages.say("Loading", down=1)
                                pygame.display.flip()
                                minbee.visualize_intelligence(world, c)
                                minbee.sample_path(world)
                                c.draw()
                                pygame.display.flip()

                            elif choice == "cancel":
                                done = 1
                                break

                            elif choice == "quit":
                                time_to_quit = True

                elif choice == "Save bees":
                    beemap = {}
                    beenames = []

                    for b in r.bees:
                        label = b.firstname + " " + b.name
                        beemap[label] = b
                        beenames.append(label)

                    choice = getChoiceUnbounded("Pick a bee", beenames, allowcancel=True)

                    if choice == "quit":
                        time_to_quit = True

                    elif choice != "cancel":
                        b = beemap[choice]
                        # messages.colorBackground()
                        # messages.say("Pick a new name for the bee", down = 4)
                        rename = b.name
                        """loop is for error checks"""
                        while not time_to_quit:
                            rename = getString(string=b.name, message="Pick a new name for the bee")

                            # quit
                            if rename == -1:
                                break
                            # cancel
                            elif rename == 0:
                                break
                            elif any(specimen[0] == rename for specimen in h.specimens):
                                messages.colorBackground()
                                messages.say("Name taken. Pick a new name for the bee", down=4)
                                continue
                            else:
                                b.name = rename
                                break
                        h.save_bee(b)
                        h.savedata()

                elif choice == "Load bees":
                    loadedbeenames = []
                    for b in h.specimens:
                        loadedbeenames.append(b[0])

                    loadedbeenames.append("done")
                    loadedbeenames = loadedbeenames[-1::-1]
                    i = 0
                    while not time_to_quit:
                        name = getChoiceUnbounded("Loaded " + str(i) + " bees", loadedbeenames, allowcancel=True)
                        if name in ["done", "quit", "cancel"]:
                            break
                        else:
                            i += 1
                            b = h.make_bee(name, r, p)
                            r.bees.append(b)
                            b.flash = 50
                            b.xy[0, 0] = p.xy[0, 0]

                elif choice == "Delete bees":
                    i = 0
                    message = "Choose a bee to delete"
                    while not time_to_quit:
                        indexfromname = {}
                        loadedbeenames = []
                        for index, b in enumerate(h.specimens):
                            name = b[0]
                            loadedbeenames.append(name)
                            indexfromname[name] = index
                        loadedbeenames.append("done")
                        loadedbeenames = loadedbeenames[-1::-1]

                        if i:
                            message = "Deleted " + str(i) + " bees"
                        name = getChoiceUnbounded(message, loadedbeenames, allowcancel=True)
                        if name in ["quit", "done", "cancel"]:
                            break
                        else:
                            confirm = getChoiceUnbounded("Delete %s?" % name, ["no", "yes"], allowcancel=True)
                            if confirm != "yes":
                                continue
                            i += 1
                            indextoremove = indexfromname[name]
                            h.specimens = h.specimens[:indextoremove] + h.specimens[(indextoremove + 1) :]

                elif choice == "Tweak variables":
                    families = game_settings.families

                    """picking kinds of variables"""
                    while not time_to_quit:
                        family = getChoiceUnbounded("What kind of variable?", families.keys(), allowcancel=1)
                        if family == "cancel":
                            break

                        """picking variable"""
                        while not time_to_quit:
                            """takes "name: value" string to "name"."""
                            label_to_key = {key + ": " + str(settings[key]): key for key in families[family]}

                            """this is a bunch of informative labels"""
                            options = [x for x in sorted(label_to_key.keys())]

                            toChange = getChoiceUnbounded("Pick a variable to modify", options, allowcancel=1)

                            if toChange == "cancel":
                                break
                            toChange = label_to_key[toChange]
                            if toChange in want_bools:
                                settings[toChange] = not settings[toChange]
                                continue
                            elif toChange in want_ints and toChange in max_val and toChange in min_val:
                                settings[toChange] += 1
                                if settings[toChange] > max_val[toChange]:
                                    settings[toChange] = min_val[toChange]
                                continue
                            else:
                                """we have the name of the variable we want to change now"""

                                usedindex = 0
                                for i, entry in enumerate(options):
                                    if entry == toChange:
                                        usedindex = i

                                # messages.colorBackground()
                                # messages.say("Pick a new value", down = 4)

                                allowed_keys = range(pygame.K_0, pygame.K_9 + 1)
                                allowed_keys += [pygame.K_PERIOD]
                                allowed_keys += [pygame.K_e]
                                allowed_keys += [pygame.K_MINUS]

                                """loop is for error checking"""
                                while not time_to_quit:
                                    # message = messages.smallfont.render("Set new value for '%s'" % toChange, 1, [255, 255, 255])
                                    # pygame.display.get_surface().blit(message, (600, 15 * (usedindex + 3)))
                                    m = "Set new value for '%s'" % toChange
                                    position = pygame.Rect(0, 0, 290, 30)
                                    # position.x = 600 #Leaning right
                                    position.centerx = graphics.screen_w / 2
                                    # position.y = 15 * (usedindex + 4.3)
                                    # Leaning up
                                    position.centery = graphics.screen_h / 2
                                    out = getString(allowed_keys, str(settings[toChange]), textpos=position, message=m)
                                    # out = getString(allowed_keys, str(settings[toChange]))

                                    # quit
                                    if out == -1:
                                        break

                                    # cancel
                                    elif out == 0:
                                        break

                                    try:
                                        val = 0
                                        if "." in out:
                                            val = float(out)
                                        else:
                                            val = int(out)

                                        problems = problem_with_setting(toChange, val)
                                        if problems:
                                            messages.colorBackground()
                                            messages.say(problems, down=4)
                                            continue

                                        settings[toChange] = val
                                        break

                                    except:
                                        messages.colorBackground()
                                        messages.say("Error. Pick a new value", down=4)

                                save_settings()

                                # for key, value in settings.iteritems():
                                #   print key + ":", str(value)
                        if family == "quit" or time_to_quit:
                            time_to_quit = True
                            break

                elif choice == "Modify map":
                    messages.colorBackground()
                    messages.say("This is where I would modify the map", 500)

                elif choice == "View Shortcuts":
                    messages.colorBackground()
                    messagecount = 2
                    if settings[SHOW_EYES]:
                        messagecount = messages.say("[r]: Hide eyes", down=messagecount)
                    else:
                        messagecount = messages.say("[r]: Show eyes", down=messagecount)

                    if r.madness:
                        messagecount = messages.say("[m]: Don't draw trails", down=messagecount)
                    else:
                        messagecount = messages.say("[m]: Draw trails", down=messagecount)

                    if settings[GENERATE_RANDOM_MAP]:
                        messagecount = messages.say("[t]: Don't randomize maps when loading", down=messagecount)
                    else:
                        messagecount = messages.say("[t]: Randomize maps when loading", down=messagecount)

                    if r.stasis:
                        messagecount = messages.say("[a]: Resume deaths and births", down=messagecount)
                    else:
                        messagecount = messages.say("[a]: Pause deaths and births", down=messagecount)

                    messagecount = messages.say("[e]: Examine a random bee", down=messagecount)

                    messagecount = messages.say("Click anywhere to continue", down=messagecount)
                    waitForEnter(hidemessage=1)

            if time_to_quit:
                print "Saving game very rapidly, whee"
                game_progress.save_game(r)
                return

            screen.fill(graphics.background)
            # This is to trick the computer into thinking no time has passed
            time_gap = True
    gameobjects["player"] = p
    gameobjects["room"] = r
    gameobjects["world"] = world
    gameobjects["camera"] = c
    gameobjects["screen"] = screen
    gameobjects["hive"] = h
    return time_gap