def fromPoints(cls, point1: Union[Vector2D, tuple], point2: Union[Vector2D, tuple]): """Create a line from points with a limited domain. Create a line from two vectors or tuples. The domain will be limited to the two points including. Args: a: `Vector2D | tuple` Point A of the line b: `Vector2D | tuple` Point B of the line Returns: `linline` A linear line with a limited domain. """ if (type(point1) == tuple): point1 = Vector2D.fromTuple(point1) if (type(point2) == tuple): point2 = Vector2D.fromTuple(point2) r = point2 - point1 n = r.toNormalVector() a = round(n.x, 3) b = round(n.y, 3) c = n @ point1 limit = [point1.x, point2.x] if b != 0 else [point1.y, point2.y] return cls(a, b, c, limit=limit)
def fromFullPoints(cls, points: List[List[Vector2D]], checkpoints: List[List[Vector2D]], startingPoint=Vector2D(0, 0), window=(1920, 1080), monocar: bool = True) -> circuit: lines = [] checkpoint = [] margin = Vector2D(50, 50) allpoints = [item for sublist in points for item in sublist] max_x = max([p.x for p in allpoints]) max_y = max([p.y for p in allpoints]) scale = min((window[0] - 2 * margin.x) / max_x, (window[1] - 2 * margin.y) / max_y) startPoint = startingPoint * scale + margin #Create a list of lines from the points for k, lane in enumerate(points): lines.append([]) for i in range(len(lane)): j = (i + 1) % len(lane) lines[k].append( linline.fromPoints(lane[i] * scale + margin, lane[j] * scale + margin)) for line in checkpoints: l = linline.fromPoints(line[0] * scale + margin, line[1] * scale + margin) l.color = (255, 215, 0) checkpoint.append(l) return cls(lines, checkpoint, startingPoint=startPoint, monocar=monocar)
def reset(self): self.currentCheckpoint = 0 self.forces = Vector2D(0, 0) self.acceleration = Vector2D(0, 0) self.dead = False self.velocity = Vector2D(-1 * 10**-3, 0) self.position = self.startPosition.copy()
def __init__(self, cars, circ, window, load=False, car_scale=1.48) -> None: self.window = Vector2D.fromTuple(window) self.circuit = circ self.carX = self.circuit.startingPoint.x self.carY = self.circuit.startingPoint.y self.carList = [ Agent(self.carX, self.carY, window=self.window, scale=car_scale) for _ in range(cars) ] self.oldCarList = [] self.show = False self.showA = True self.carCount = cars self.fitnessSum = 0 self.gen = 1 self.autoGen = 1 self.bestCar = 0 self.oldBestAgent = self.carList[self.bestCar] self.bestCarPosition = Vector2D(0, 0) self.oldBestCount = 0 self.maxStep = 1000 self.load = load self.row = None self.blindSpots = [] self.blindIndex = [] self.addBlindSpot()
def getEndPoints(self) -> Tuple[Vector2D]: if self.b == 0: pointA = Vector2D(self.calcX(self.limit[0]), self.limit[0]) pointB = Vector2D(self.calcX(self.limit[1]), self.limit[1]) else: pointA = Vector2D(self.limit[0], self.calcY(self.limit[0])) pointB = Vector2D(self.limit[1], self.calcY(self.limit[1])) return (pointA, pointB)
def brake(self, forces): if self.reverse2 == False and (self.velocity.x > 2 or self.velocity.x < -2): forces += Vector2D(-150, 0) elif self.reverse2 == True and (self.velocity.x > 2 or self.velocity.x < -2): forces += Vector2D(150, 0) else: self.velocity.limit(0) self.reverse2 = False
def __init__(self, a: float, b: float, c: float, limit=[-math.inf, math.inf], color=(255, 255, 255)) -> None: self.a = a self.b = b self.c = c self.r = Vector2D(b, -a) self.n = Vector2D(a, b) self.limit = limit self.color = color
def update(self, dt, key, key_handler): forces = Vector2D(0, 0) # self.intersection(lines) if self.velocity.x != 0: c = 100 sigmoid = lambda x: 1 / (1 + math.e**-(x - c)) sidewayForce = sigmoid(abs(self.velocity)) * 400 else: sidewayForce = 0 if key_handler[key.UP]: self.forward(forces) if key_handler[key.DOWN]: self.backward(forces) if key_handler[key.LEFT]: self.left(forces, sidewayForce) if key_handler[key.RIGHT]: self.right(forces, sidewayForce) if key_handler[key.SPACE]: self.brake(forces) velocityPrevious = self.velocity.copy() self.acceleration = forces.rotate( self.carRotation.rotation()) / self.mass self.acceleration.limit(100) self.velocity += self.acceleration * dt self.velocity.limit(200) if self.velocity.x != 0: self.carRotation = self.velocity.copy() self.carRotation.normalize() if self.reverse == True: if (self.velocity.x < 0 and velocityPrevious.x >= 0) or ( self.velocity.x >= 0 and velocityPrevious.x < 0): self.reverse2 = True else: if (self.velocity.x < 0 and velocityPrevious.x >= 0) or ( self.velocity.x >= 0 and velocityPrevious.x < 0): self.reverse2 = False if self.reverse2 == False: self.position += self.carRotation * abs(self.velocity) * dt self.rotation = self.carRotation.rotation() else: self.carRotation.rotate(180) self.velocity.limit(100) self.position += self.carRotation * -abs(self.velocity) * dt self.rotation = self.carRotation.rotation() self.middle = self.position + Vector2D(25, 15).rotate(self.rotation)
def __init__(self, window, goal, best=False) -> None: self.pos = Vector2D(100, 100) self.vel = Vector2D(0, 0) self.acc = Vector2D(0, 0) self.goal = goal self.brain = Brain(1000) self.fitness = 0 self.window = window self.bestDot = best self.dead = False self.finished = False
def __init__(self, dots, window) -> None: self.window = Vector2D.fromTuple(window) self.goal = self.window self.dotList = [ Dot(window=self.window, goal=(self.goal - Vector2D(10, 10))) for _ in range(dots) ] self.fitnessSum = 0 self.gen = 1 self.bestDot = 0 self.minStep = 1000
def __init__(self, x: int, y: int, scale: float = 1.48): self.mass = 1 self.forces = Vector2D(0, 0) self.carRotation = Vector2D(-1, 0) self.acceleration = Vector2D(0, 0) self.velocity = self.carRotation * 10**-3 self.startPosition = Vector2D(x, y) self.position = Vector2D(x, y) self.sprites = { "alive": pyglet.resource.image('img/car.png'), "best": pyglet.resource.image('img/carBest.png'), "dead": pyglet.resource.image('img/carCrash.png') } for k, v in self.sprites.items(): sprite = v sprite.anchor_x = v.width / 2 sprite.anchor_y = v.height / 2 self.sprites[k] = sprite self.scale = scale self.image_dimensions = (self.sprites['alive'].width * scale, self.sprites['alive'].height * scale) self.eyesList = [[0, 5000], [5000, 5000], [5000, 0], [5000, -5000], [0, -5000], [-5000, 0]] self.hitboxVectors = [ Vector2D(-self.image_dimensions[0] / 2, -self.image_dimensions[1] / 2), Vector2D(-self.image_dimensions[0] / 2, self.image_dimensions[1] / 2), Vector2D(self.image_dimensions[0] / 2, self.image_dimensions[1] / 2), Vector2D(self.image_dimensions[0] / 2, -self.image_dimensions[1] / 2), ] self.dead = False self.middle = Vector2D(self.image_dimensions[0] // 2, self.image_dimensions[1] // 2) self.lines = [] self.currentCheckpoint = 0 #GA self.bestCar = False self.fitness = 0 self.currentLap = 0
def __init__(self, x: int, y: int): self.position = Vector2D(x, y) self.acceleration = Vector2D(0, 0) self.velocity = Vector2D(0, 0) self.mass = 1 self.rotation = 0 self.carRotation = Vector2D(0, 0) self.reverse = False self.reverse2 = False self.eyesList = [[0, 200], [200, 200], [200, 0], [200, -200], [0, -200], [-200, 0]] self.hitboxVectors = [[3, 3], [35, 3], [35, 25], [3, 25]] self.dead = False self.lines = [] self.middle = Vector2D(0, 0)
def generateHitbox(self): hitbox = [] hitboxVectors = [Vector2D(i[0], i[1]) for i in self.hitboxVectors] previousPoint = self.position + Vector2D(5, 5) lineColor = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (0, 255, 255)] for i in range(len(hitboxVectors)): j = (i + 1) % len(hitboxVectors) nextPoint = self.position + hitboxVectors[j].rotate(self.rotation) l = linline.fromPoints(previousPoint, nextPoint) l.color = lineColor[i] hitbox.append(l) previousPoint = nextPoint return hitbox
def fromSkeletonPoints(cls, points, startingPoint=Vector2D(0, 0), name=None): vertices, checkpoints, newStartingPoint = cls.generate( points, width=100, startingPoint=startingPoint) return cls(vertices, checkpoints, newStartingPoint, circ_name=name)
def __init__(self, vertices: List[List[linline]], checkpoints: List[linline], skeletonLines: List[linline] = None, startingPoint=Vector2D(0, 0), monocar: bool = True, circ_name=None) -> None: self.innerLines = vertices[0] self.outerLines = vertices[1] self.vertices = [item for sublist in vertices for item in sublist] if checkpoints is None: self.checkpoints = self.generateCheckpoints(10) else: self.checkpoints = checkpoints self.checkpointNumber = len(self.checkpoints) self.currentCheckpoint = 0 self.skeletonLines = skeletonLines self.startingPoint = startingPoint self.monocar = monocar if circ_name is not None: self.background = pyglet.image.load(f'{circ_name}-Circuit.png') self.backgroundTopper = pyglet.image.load( f'{circ_name}-Topper.png') else: self.background = pyglet.image.load(f'SigmaFalls-Topper.png') self.backgroundTopper = pyglet.image.load(f'SigmaFalls-Topper.png')
def mutate(self): mutationRate = 0.01 #Chance that vector gets changed for i in range(len(self.instructions)): rand = random.random() if (rand < mutationRate): self.instructions[i] = Vector2D.fromAngle( random.random() * 2 * math.pi) #Set direction to random angle
def generateLines(self): lines = [] eyePoints = [Vector2D(i[0],i[1]) for i in self.eyesList] for line in eyePoints: secondPosition = self.middle + line.rotate(self.carRotation.rotation()) lines.append(linline.fromPoints(self.middle, secondPosition)) self.lines = lines return lines
def __init__(self, cars, carX, carY, window) -> None: self.window = Vector2D.fromTuple(window) self.goal = self.window self.carX = carX self.carY = carY self.carList = [ Agent(carX, carY, window=self.window, goal=(self.goal - Vector2D(10, 10))) for _ in range(cars) ] self.show = False self.showA = True self.fitnessSum = 0 self.gen = 1 self.bestCar = 0 self.minStep = 1000
def fromJSON(cls, filename, window=[1920, 1080], method="Skeleton"): with open(filename, "r") as f: circuitDict = json.load(f) #Feature detection hasSkeleton = 'skeleton' in circuitDict.keys() hasCheckpoints = 'checkpoints' in circuitDict.keys() #Assign startingPoint to local variable startingPoint = Vector2D(circuitDict['startingPoint'][0], circuitDict['startingPoint'][1]) #Convert lists of coordinates to Vector2D skeleton = [Vector2D(i[0], i[1]) for i in circuitDict['skeleton']] if hasSkeleton else None if hasSkeleton and method == "Skeleton": return cls.fromSkeletonPoints(skeleton, startingPoint=startingPoint, name=circuitDict['name']) else: innerPoints = [Vector2D(i[0], i[1]) for i in circuitDict['inner']] outerPoints = [Vector2D(i[0], i[1]) for i in circuitDict['outer']] if hasCheckpoints and hasSkeleton: checkpoints = [[ Vector2D(i[0][0], i[0][1]), Vector2D(i[1][0], i[1][1]) ] for i in circuitDict['checkpoints']] return cls.fromFullPoints([innerPoints, outerPoints], checkpoints=checkpoints, skeletonPoints=skeleton, startingPoint=startingPoint, window=window, name=circuitDict['name']) if hasCheckpoints: checkpoints = [[ Vector2D(i[0][0], i[0][1]), Vector2D(i[1][0], i[1][1]) ] for i in circuitDict['checkpoints']] return cls.fromFullPoints([innerPoints, outerPoints], checkpoints=checkpoints, startingPoint=startingPoint, window=window, name=circuitDict['name']) else: return cls.fromFullPoints([innerPoints, outerPoints], startingPoint=startingPoint, skeletonPoints=skeleton, window=window, name=circuitDict['name'])
def update(self, dt, key, key_handler): self.forces = Vector2D(0, 0) if key_handler[key.UP]: self.forward() if key_handler[key.DOWN]: self.backward() if key_handler[key.LEFT]: self.left() if key_handler[key.RIGHT]: self.right() self._calculatePhysics(dt)
def fromPoints(cls, a: Union[Vector2D, tuple], b: Union[Vector2D, tuple]) -> linline: """Create a line from points with a limited domain. Create a line from two vectors or tuples. The domain will be limited to the two points including. Args: a: `Vector2D | tuple` Point A of the line b: `Vector2D | tuple` Point B of the line Returns: `linline` A linear line with a limited domain. """ if (type(a) == tuple): a = Vector2D.fromTuple(a) if (type(b) == tuple): b = Vector2D.fromTuple(b) if (not a.y == b.y) and (not a.x == b.x): rc = (b.y - a.y) / (b.x - a.x) p = a.y - rc * a.x elif (a.y == b.y): rc = 0 p = a.y else: rc = 1e10 p = -a.x * 1e10 limit = [a.x, b.x] line = cls(rc, p, sorted(limit)) line.vertical = [a.y, b.y] return line limit = [a.x, b.x] return cls(rc, p, sorted(limit))
def __init__(self, vertices: List[List[linline]], checkpoints: List[linline], startingPoint=Vector2D(0, 0), monocar: bool = True) -> None: self.innerLines = vertices[0] self.outerLines = vertices[1] self.vertices = [item for sublist in vertices for item in sublist] self.checkpoints = checkpoints self.currentCheckpoint = 0 self.startingPoint = startingPoint self.monocar = monocar self.background = pyglet.image.load('sigmaFalls.png')
def updateWithInstruction(self, dt, instruction): self.forces = Vector2D(0,0) if(instruction == 0): self.forward() elif(instruction == 1): self.backward() elif(instruction == 2): self.left() elif(instruction == 3): self.right() elif None: pass else: print("Notice: UpdateWithInstruction() can only handle ints from 0 to 3") self._calculatePhysics(dt)
def appendToCheckpoint(lengthUntilNextCheckpoint, checkpoints, line, currentLengthOfLine, ratioOfLengthToNextCheckpoint): beginOfCurrentLine, _ = line.getEndPoints() newCheckpoint = beginOfCurrentLine + line.r.normalize( in_place=False) * ratioOfLengthToNextCheckpoint checkpoints[0].append(newCheckpoint) perpindicular = linline.fromVector(line.n, newCheckpoint) distance = math.inf secondNewCheckpoint = Vector2D(0, 0) for outerLine in self.innerLines: intersection = perpindicular.intersect(outerLine) if intersection is not None: if abs(newCheckpoint - intersection) < distance: distance = abs(newCheckpoint - intersection) secondNewCheckpoint = intersection checkpoints[1].append(secondNewCheckpoint)
def _calculatePhysics(self, dt): #Calculate acceleration based on forces and limit it to 100 pixels per second per second self.acceleration = self.forces.rotate(self.carRotation.rotation()) / self.mass self.acceleration.limit(200) #Calculate velocity based on accelation and limit it to 200 pixels per second self.velocity += self.acceleration * dt self.velocity.limit(200) #Determine if we are driving backwards or forwards backwards = (self.velocity @ self.carRotation < 0) self.position += self.velocity * dt if not backwards: self.carRotation = self.velocity.copy() else: self.carRotation = -self.velocity.copy() self.middle = self.position + Vector2D.fromTuple(self.image_dimensions).rotate(self.carRotation.rotation()) * self.scale * 0.5
def intersect(self, other: linline) -> Vector2D: """Calculate the point on which the two lines intersect The two lines intersect on one point. Intersect() calculates that point and give back a vector. Args: other: a linline; the line that intersects Returns:\n `Vector2D` A vector if a match is found \n `None` None if no match is found """ if (self.rc - other.rc) != 0: new_x = (other.b - self.b) / (self.rc - other.rc) if self.limit[0] <= new_x <= self.limit[1] and other.limit[ 0] <= new_x <= other.limit[1]: return Vector2D(new_x, self.calc(new_x)) else: return None else: return None
def right(self): self.forces += Vector2D(0, -self._getTurnForce())
def fromVector(cls, direction, location=Vector2D(0, 0)): rc = direction.y / direction.x b = direction.x * location.y - direction.y * location.x return cls(rc, b)
from classes.geneticAlgoritmNN.world import World from classes.circuit import circuit from classes.Vector import Vector2D ### MAIN LOOP window = pyglet.window.Window(resizable=True, fullscreen=True) inner_points = [[18, 3], [8, 3], [5, 4], [3, 6], [2, 9], [2, 12], [3, 14], [4, 14], [6, 12], [7, 8], [8, 7], [12, 6], [16, 6], [19, 9], [20, 11], [16, 13], [13, 12], [12, 14], [13, 15], [17, 16], [20, 15], [22, 13], [23, 8], [21, 5]] outer_points = [[18, 0], [8, 0], [2, 3], [0, 9], [0, 14], [2, 16], [5, 16], [8, 12], [9, 9], [12, 8], [15, 8], [17, 10], [16, 11], [12, 10], [11, 11], [10, 13], [10, 15], [12, 17], [17, 17], [20, 16], [23, 14], [25, 8], [23, 4]] inner = [Vector2D(i[0], i[1]) for i in inner_points] outer = [Vector2D(i[0], i[1]) for i in outer_points] #checkpoints = [[[10,-1],[10,4]],[[4,1],[6,4]],[[0,6],[3,7]],[[-1,13],[3,12]],[[3.5,13.5],[3.5,16.5]],[[4,13],[7,15]],[[6,9],[10,11]],[[11,5],[12,9]],[[15,10],[18,7]],[[15,10],[14,13]],[[9,14],[13,13]],[[15,17],[16,15]],[[21,12],[24,15]],[[22,8],[25,6]],[[19,5],[20,1]],[[15,-1],[15,4]]] checkpoints = [[[10, -1], [10, 4]], [[4, 1], [6, 4]], [[13, 5], [13, 9]], [[15, -1], [15, 4]]] circuit_checkpoints = [] for i, checkpoint in enumerate(checkpoints): circuit_checkpoints.append([]) for point in checkpoint: circuit_checkpoints[i].append(Vector2D(point[0], point[1])) circ = circuit.fromFullPoints([inner, outer], circuit_checkpoints, Vector2D(12, 1), window=window.get_size(),
from pyglet import clock ### MAIN LOOP window = pyglet.window.Window(resizable=True, fullscreen=True) checkpoints = [[[10, -1], [10, 4]], [[4, 1], [6, 4]], [[13, 5], [13, 9]], [[15, -1], [15, 4]]] blindSpots = [[490, 80], [220, 210], [75, 545], [100, 850], [245, 930], [375, 850], [465, 730], [485, 485], [715, 410], [925, 415], [1130, 645], [945, 750], [720, 645], [635, 860], [735, 975], [1000, 985], [1180, 935], [1330, 820], [1425, 500], [1300, 280], [1070, 90]] indexSpot = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0 ] blindSpotPoints = [Vector2D(i[0], i[1]) for i in blindSpots] circuit_checkpoints = [] for i, checkpoint in enumerate(checkpoints): circuit_checkpoints.append([]) for point in checkpoint: circuit_checkpoints[i].append(Vector2D(point[0], point[1])) dir_path = os.path.dirname(os.path.realpath(__file__)) path = dir_path + '/' + 'circuits/BONK_CIRCUIT_GACHECKPOINTS.json' circ = circuit.fromJSON(path, window=window.get_size(), method="fromFullPoints") world = World(50, circ.startingPoint.x, circ.startingPoint.y,