def __init__(self, x0, y0, x1, y1): self.x0 = x0 self.y0 = y0 self.y1 = y1 self.x1 = x1 self.vector0 = Vector(x0, y0) self.vector1 = Vector(x1, y1) self.is_target = True
class WanderBot(Bot): """Robot that wanders randomly""" steps = [Vector(1, 0), Vector(0, 1), Vector(-1, 0), Vector(0, -1)] # Class attribute def __init__(self, position): """Setup wandering robot with initial position `position`""" # Call the constructor of Bot super().__init__(position) # WanderBot-specific initialization def update(self): """Take one random step""" self.position += random.choice(self.steps)
def compute_next_state(self, curr_state, cmd, time=Time(1)): new_angle = (curr_state.angle + self.coerce_range(cmd.angle - curr_state.angle, -15, 15)) new_power = (curr_state.power + self.coerce_range(cmd.power - curr_state.power, -1, 1)) thrust = (Vector(0.0, 1.0) * new_power).rotate(new_angle) thrust_acceleration = Acceleration(thrust) acceleration = GRAVITY + thrust_acceleration new_particle = curr_state.particle.accelerate(acceleration, time) new_fuel = curr_state.fuel - new_power return State(new_fuel, new_power, new_angle, new_particle)
def evaluate_hit_ground(self, current_state, next_state): Lander.find_landing_zone() # Calculate the landing status (next state) # 0, for landing in landing zone # 1, for crashing on the ground # 2, for flying landing_status, self.hit_mark = Vector.is_line_crossing_other( current_state.position, next_state.position, Lander.GROUND, Lander.LANDING_ZONE_MARK) if landing_status == 0: # landing in landing zone self.status = FlyState.Landed return True elif landing_status == 1: self.status = FlyState.Crashed return True return False
def compute_next_state(cls, current_state, cmd): next_state_angle = cmd.angle next_state_power = cmd.power thrust = Vector(0.0, 1.0).scale(next_state_power).rotate(next_state_angle) next_state_acceleration = current_state.acceleration.add(thrust).add( GRAVITY) next_state_speed = current_state.speed.add( current_state.acceleration).round_up() next_state_position = current_state.position.add( current_state.speed).round_up() next_state_fuel = current_state.fuel - next_state_power return State(fuel=next_state_fuel, power=next_state_power, angle=next_state_angle, speed=next_state_speed, position=next_state_position, acceleration=next_state_acceleration)
def simulate(self, init_position, fuel, ground_points): """From each chromosome in population we create object of Lander class and compute trajectory """ x, y = init_position[0], init_position[1] lander_init_state = State(fuel, 0, 0, Particle(Point(x, y), Speed(Vector(0, 0)))) ground_line = ground_inputs_to_line(ground_points) self.ground_points = ground_line self.simulations = [] for member in self.population: commands = [] previous_gene = CMD_TUPLE(0, 0) for gene in member.genes: angle = previous_gene.angle + coerce_range( gene.angle - previous_gene.angle, -15, 15) power = previous_gene.power + coerce_range( gene.power - previous_gene.power, -15, 15) commands.append(ControlCommands(angle, power)) previous_gene = gene new_lander = Lander(lander_init_state, commands, ground_line) self.simulations.append(new_lander) self.all_simulations.append(deepcopy(self.simulations))
import bots import random import time width = 60 height = 30 current_bots = [] # Make some wander bots for i in range(5): P = Point(random.randint(0, width - 1), random.randint(0, height - 1)) current_bots.append(bots.WanderBot(position=P)) # Make some patrol bots patrol_directions = [Vector(1, 0), Vector(0, 1), Vector(1, 1)] for i in range(10): P = Point(random.randint(0, width - 1), random.randint(0, height - 1)) D = random.choice(patrol_directions) current_bots.append(bots.PatrolBot(position=P, direction=D, nstep=8)) # Make two destruct bots current_bots.append(bots.DestructBot(position=Point(4, 4), lifetime=5)) current_bots.append(bots.DestructBot(position=Point(4, 10), lifetime=15)) # Symbols for the different kinds of bots botsymbols = { bots.PatrolBot: "P", bots.DestructBot: "D", bots.WanderBot: "W", bots.Bot: "*"
def __init__(self, x0, y0): self.x0 = x0 self.y0 = y0 self.vector0 = Vector(x0, y0) self.is_target = True
import math from plane import Vector from enum import Enum GRAVITY = Vector(0.0, -3.71) MAX_X = 6999 MIN_X = 0 def get_distance(x0, y0, x1, y1): distance = math.sqrt((x1 - x0)**2 + (y1 - y0)**2) return distance def get_distance_landing( ground_list, landing_zone_index, # 4 landing_index, # 2 x1, y1): if landing_index > landing_zone_index + 1: surface_distance = 0.0 for i in range(landing_zone_index + 1, landing_index): x0_ = ground_list[i].x y0_ = ground_list[i].y x1_ = ground_list[i + 1].x y1_ = ground_list[i + 1].y segment_distance = get_distance(x0=x0_, y0=y0_, x1=x1_, y1=y1_) surface_distance += segment_distance x0 = ground_list[landing_index].x
def init(): input1 = [ 6, # number of ground points "0 1500", "1000 2000", "2000 500", "3500 500", "5000 1500", "6999 1000", "5000 2500", # INIT_X INIT_Y "0 0", # INIT_DX INIT_DY "0" ] # INIT_ANGLE input2 = [ 15, # number of ground points "0 2500", "100 200", "500 150", "1000 2000", "2000 2000", "2010 1500", "2200 800", "2500 200", "6899 300", "6999 2500", "4100 2600", "4200 1500", "3500 1300", "3100 1600", "3400 3400", "6500 1300", # INIT_X INIT_Y #16 "-50 0", # INIT_DX INIT_DY #17 "0" ] # INIT_ANGLE #18 input3 = [ 15, # number of ground points "0 2500", "100 200", "500 150", "1000 2000", "2000 2000", "2010 1500", "2200 800", "2500 200", "6899 300", "6999 2500", "4100 2600", "4200 1000", "3500 800", "3100 1100", "3400 2900", "6500 1300", # INIT_X INIT_Y #16 "0 0", # INIT_DX INIT_DY #17 "0" ] # INIT_ANGLE #18 input_data_list = list([input1, input2, input3]) input_data = input_data_list[MAP_SELECTION] num_ground_points = input_data[0] ground_points = input_data[1:1 + num_ground_points] init_pos = input_data[1 + num_ground_points] init_speed = input_data[2 + num_ground_points] init_angle = input_data[3 + num_ground_points] # parse into point object ground_points = ground_inputs_to_line(ground_points) init_pos = Vector(*map(int, init_pos.split())) init_speed = Vector(*map(int, init_speed.split())) init_angle = int(init_angle) init_state = State(fuel=1000, power=0, angle=init_angle, speed=Vector(init_speed.x, init_speed.y), position=Vector(init_pos.x, init_pos.y), acceleration=Vector(0, 0)) population = Population(mutation_rate=MUTATION_RATE, pop_size=POPULATION_SIZE, ground_points=ground_points, init_state=init_state, max_lifecycle=MAX_LIFECYCLE) population.display_current_population_simulation() return population
def ground_inputs_to_line(ground_points): points = [] for point in ground_points: points.append(Vector(*map(int, point.split()))) return points
from plane import Vector from motion import Time, Acceleration import enum GRAVITY = Acceleration(Vector(0.0, -3.711)) MAX_X = 6999 MIN_X = 0 class ControlCommands(): """Commands for controlling Mars lander - power : 0, 1, 2, 3, 4 - angle : -90, -75, ... , 0, +15, +30, ..., +75, +90 """ def __init__(self, angle, power): self.angle = angle self.power = power class State(): """Current state of Mars lander - fuel: integer - power : 0, 1, 2, 3, 4 - angle : -90, -75, ... , 0, +15, +30, ..., +75, +90 - particle: instance of Particle class """ def __init__(self, fuel, power, angle, particle): self.fuel = fuel self.power = power self.angle = angle self.particle = particle