예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
 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()
예제 #4
0
    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()
예제 #5
0
    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
예제 #7
0
 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)
예제 #9
0
    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
예제 #10
0
    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
예제 #11
0
    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
예제 #14
0
 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)
예제 #15
0
    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')
예제 #16
0
 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
예제 #17
0
    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
예제 #18
0
    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
예제 #19
0
    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'])
예제 #20
0
    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)
예제 #21
0
    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))
예제 #22
0
    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')
예제 #23
0
    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)
예제 #24
0
        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)
예제 #25
0
    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
예제 #26
0
    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
예제 #27
0
 def right(self):
     self.forces += Vector2D(0, -self._getTurnForce())
예제 #28
0
 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)
예제 #29
0
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(),
예제 #30
0
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,