コード例 #1
0
ファイル: Wall.py プロジェクト: neich/BattleField
    def Respawn(self):
        # Respawn a defeated wall (or restore an attacked wall)

        self.__climbedAttacker = {"Battalion": None, "SoldierPosition": Point3D()}
        self.__attachedSiegeTower = {"SiegeTower": None, "Position": Point3D()}

        self.__climberStairs = []

        self.__tilesManager.RecalculateTiles()
コード例 #2
0
ファイル: Wall.py プロジェクト: neich/BattleField
    def Reset(self):
        Construction.Construction.Reset(self)

        # Remove climbers and siege towers
        self.__climbedAttacker["Battalion"] = None
        self.__climbedAttacker["SoldierPosition"] = Point3D()
        self.__attachedSiegeTower["SiegeTower"] = None
        self.__attachedSiegeTower["Position"] = Point3D()

        # Clear the list of climbers, but not delete them
        self.__climberStairs = []

        self.__tilesManager.Reset()
コード例 #3
0
ファイル: GroundCell.py プロジェクト: neich/BattleField
    def GetBoundingBox(self):

        quad = self.GetBoundingQuad()
        if (self.HasBattalion()):
            bbox = self.GetBattalion().GetBounding()
            height = bbox.height
        else:
            height = 0.0

        bbox = BoundingBox(minP=Point3D(quad.minPoint.x, quad.minPoint.y,
                                        self.__groundHeight),
                           maxP=Point3D(quad.maxPoint.x, quad.maxPoint.y,
                                        self.__groundHeight + height))
        return bbox
コード例 #4
0
    def AppendBattalion(self, battalion, offset=0):
        # Appends a battalion that requires size space at next avaiable position
        # Returns false if there isn't enough space to place the battalion
        # Parameter offset is used to place the next battalion at offset distance

        # Calculate next avaiable placement
        if (len(self._battalions) == 0):
            pend = self._line.p1.Copy()
        else:
            pend = Point2D().SetFrom3D(self._battalions[len(self._battalions) -
                                                        1].position.Copy())

        dv = self.__GetVector2D()
        dv.Normalize()
        pend.Move(dv, (self._gridCellSize) + offset)

        # Check if new placement has reached the end of defending line
        dist1 = pend.Distance(self._line.p1)
        dist2 = pend.Distance(self._line.p2)
        endreached = (dist2 < self._gridCellSize) or (dist1 >
                                                      self.__GetLength())
        if (endreached):
            if (len(self._battalions) > 0):
                return False
            else:
                # If there are not enough space to deploy the battalion, but the defense line is empty, means that it is too short, but it is enough large to fit an unit
                # This can happens if offset is too big
                if (len(self._battalions) == 0):
                    pend = self._line.GetMidPoint()

        self._battalions.append(
            DefendingBattalion(battalion, Point3D(pend.x, pend.y,
                                                  self._height)))
        self._battalionsMap[battalion.GetLabel()] = len(self._battalions) - 1
        return True
コード例 #5
0
    def GetRandomPosition(self):
        # Get a random point of current battalion. Index is used only for climbing soldiers

        if (self.__placementType == Placement.BATTLEFIELD):
            return self.__battlefieldCell.GetRandomCellPosition()
        elif (self.__placementType == Placement.DEFENDINGLINE):
            return self.__defendingLine[
                "Construction"].GetRandomBattalionCellPosition(
                    self.__defendingLine["DefendingLine"], self.__battalion)
        elif (self.__placementType == Placement.CLIMBING):

            # Since the random position on battlefield and defending lines are calculated on the battalion placement, we are going to calculate a bounding around the soldier and
            # calculate the point on it. To avoid working with a cube (the soldier is moving in all 3 dimensions), we get random positions on the three axis

            bounding = self.__battalion.GetBounding()
            #random.seed()
            rx = random.uniform(0, bounding.length * 2.0)
            ry = random.uniform(0, bounding.width * 2.0)
            rz = random.uniform(0, bounding.height * 2.0)

            pos = self.__climbing["Position"].Copy()
            # Lets do simplify more and don't consider the wall rotation. This is not accurate, but is much faster than vector operations
            pos.x = (pos.x - bounding.length) + rx
            pos.y = (pos.y - bounding.width) + ry
            pos.z = (pos.z - bounding.height) + rz

            return pos

        return Point3D()
コード例 #6
0
    def ShootToConstruction(self, target, frompos, targetpos):
        # Shoots to a construction target. Usually by a cannon
        # The targetpos parameter is where attacker points. But the precision factor can modify it
        # In addition, the final shooting point can hit any other construction part (see NOTE bellow)
        # Returns a dictionary with hit result -> {"Hit": True/False, "Intersection": Point3D()}

        ret = {"Hit": False, "Intersection": Point3D()}

        # Aiming consideration: We are going to calculate a shoot in a direction sampled by a cosinus distribution
        # From the aiming point of view, the shooter points to a far point, and if accuracy factor is 100%, it should hit the target.
        # So, the sphere used to sample the cosinus distribution should has the target distance as radius.
        # Then, we can use the accuracy factor to get a percentage of shooting distance. With this consideration, bad accuracy factors means
        # sampling on small spheres, so the shoot can fail
        dist = frompos.Distance(targetpos)
        accuracy = dist * self.__accuracyFactor / 100.0

        direction = Vector3D()
        direction.CreateFrom2Points(frompos, targetpos)
        sph = Sphere(position=frompos, radius=accuracy)
        v = sph.GetRayCosine(direction)

        # Check hit on the castle
        # NOTE : The intersection test over whole castle geometry has a high cost. The process is simplified considering only target.
        #        If shoot doesn't hits target, the shoot fails

        ray = Ray(origin=frompos, direction=v, energy=self.__attack)
        hitpoint = target.RecieveImpact(ray)

        if (hitpoint != None):
            ret["Hit"] = True
            ret["Intersection"] = hitpoint

        return ret
コード例 #7
0
ファイル: Trench.py プロジェクト: neich/BattleField
    def __init__(self, battlefield, cells):
        self.__battlefield = battlefield
        self.__battlefieldCells = cells

        self.__closestConstruction = None
        self.__distanceClosestConstruction = -1

        # Calculate the bounding box
        # Set the cells as trench cells
        self.__boundingBox = BoundingQuad()
        if (self.__battlefieldCells):
            height = 0
            for c in self.__battlefieldCells:
                self.__boundingBox.InsertPoint(c.center)
                c.SetTrench(
                    self,
                    Battles.Utils.Settings.SETTINGS.Get_F(
                        'Battlefield', 'Trench', 'DefenseIncrease'),
                    Battles.Utils.Settings.SETTINGS.Get_F(
                        'Battlefield', 'Trench', 'MovementPenalty'))
                height += c.GetAltitude()
            self.__center = Point3D().SetFrom2D(self.__boundingBox.GetCenter())
            self.__center.z = height / len(self.__battlefieldCells)

        self.__useless = False

        self.__visitedBattalions = []
コード例 #8
0
    def ProjectPosition(self, pos):
        # Projects given position onto the defending line to get a centered good position

        pos2d = Point2D().SetFrom3D(pos)
        prj = self._line.ProjectPoint(pos2d)
        prj3d = Point3D().SetFrom2D(prj)
        prj3d.z = pos.z

        return prj3d
コード例 #9
0
    def SetDefendingLine(self, construction, defendingline):
        self.__placementType = Placement.DEFENDINGLINE
        self.__defendingLine["Construction"] = construction
        self.__defendingLine["DefendingLine"] = defendingline

        self.__battlefieldCell = None
        self.__climbing["Wall"] = None
        self.__climbing["Position"] = Point3D()
        self.__climbing["Stair"] = None
コード例 #10
0
    def SetBattlefieldCell(self, cell):
        self.__placementType = Placement.BATTLEFIELD
        self.__battlefieldCell = cell

        self.__defendingLine["Construction"] = None
        self.__defendingLine["DefendingLine"] = -1
        self.__climbing["Wall"] = None
        self.__climbing["Position"] = Point3D()
        self.__climbing["Stair"] = None
コード例 #11
0
    def __init__(self, battalion):
        self.__battalion = battalion
        self.__battlefieldCell = None
        self.__defendingLine = {"Construction": None, "DefendingLine": -1}
        self.__climbing = {"Wall": None, "Position": Point3D(), "Stair": None}
        self.__placementType = Placement.UNKNOWN

        self.__badCells = []
        self.__visitedCells = []
コード例 #12
0
ファイル: GroundCell.py プロジェクト: neich/BattleField
    def GetRandomCellPosition(self):
        # Returns an uniform random cell position (well, not exactly an uniform distribution, but near to it)

        pos = self.center
        size = self.GetCellSize()

        #seed()
        x = uniform(pos.x - (size / 2), pos.x + (size / 2))
        y = uniform(pos.y - (size / 2), pos.y + (size / 2))

        return Point3D(x, y, pos.z)
コード例 #13
0
ファイル: Wall.py プロジェクト: neich/BattleField
    def RayHitTest(self, ray):

        # Do the check in 2D -> easy and cheap (TODO: Do it (well) in 3D)
        ray2d = Ray2D().SetFrom3D(ray)
        seglist = self.GetIntersectableSegments()
        for seg in seglist:
            if ray2d.HitSegment3(seg):
                ray.SetHitPoint(Point3D().SetFrom2D(ray2d.GetHitPoint()))
                return True
        return False

        """# Checks if given ray intersects with wall
コード例 #14
0
ファイル: Wall.py プロジェクト: neich/BattleField
    def __init__(self):
        Construction.Construction.__init__(self)
        self._thickness = Battles.Utils.Settings.SETTINGS.Get_F('Castle', 'Wall', 'Thickness')
        self._height = Battles.Utils.Settings.SETTINGS.Get_F('Castle', 'Wall', 'InnerHeight')
        self._defenseIncrease = Battles.Utils.Settings.SETTINGS.Get_I('Castle', 'Wall', 'DefenseIncrease')
        self.__slope = None
        self.__joins = [None, None]
        self.__walkway = {
            "altitude": (self._height - Battles.Utils.Settings.SETTINGS.Get_F('Castle', 'Wall', 'MerlonHeight')),
            "width": Battles.Utils.Settings.SETTINGS.Get_F('Castle', 'Wall', 'WalkwayWidth')}

        self._defendingLines = BattalionConstruction.BattalionConstruction(height=self.__walkway["altitude"],
                                                                           cellsize=Battles.Utils.Settings.SETTINGS.Get_F(
                                                                               'Castle', 'Wall',
                                                                               'BattalionGridCellSize'))

        self.__tilesManager = TilesManager.TilesManager(self)

        self._label = 'Wall_' + str(Wall.wallCounter)
        Wall.wallCounter += 1

        self.__rectangle3D = [Point3D(), Point3D(), Point3D(), Point3D()]
        self.__boundingRectangle3D = BoundingBox()
        self.__normalVector = Vector3D()

        self.__heightCanvasObjs = []

        self.__climberStairs = []

        self.__climbedAttacker = {"Battalion": None, "SoldierPosition": Point3D()}
        self.__attachedSiegeTower = {"SiegeTower": None, "Position": Point3D()}
コード例 #15
0
ファイル: Wall.py プロジェクト: neich/BattleField
    def SetPosition(self, p1, p2, reshape=True):
        # Sets the wall position with 2 points. If reshape is true, the wall 2D shape is recalculated

        if p1.Distance(p2) < 5:
            print "WARNING: Too short wall creation"
            # return False

        del self._axis2D[:]
        self._axis2D.append(Segment2D(p1, p2))

        # Generate the wall shape
        if reshape:
            self.JoinShape(None)

        # Recalculates the battalion grid (creates an empty battalion grid)
        # Note that battalion grid is created over wall axis. The wall shape is not taken into account
        self._defendingLines.SetDefendingLine(0, self._axis2D[0])

        # Recalculates the tiles
        self.__tilesManager.RecalculateTiles()

        # Recalculates the 3D rectangle and bounds (used to check shoot hits on wall)
        # Calculate the exterior wall 3D rectangle
        self.__rectangle3D[0] = Point3D(self.GetStartPosition().x, self.GetStartPosition().y, 0.0)
        # self.__rectangle3D[1] = Point3D(self.GetStartPosition().x, self.GetStartPosition().y, self.__walkway["altitude"])
        # self.__rectangle3D[2] = Point3D(self.GetEndPosition().x, self.GetEndPosition().y, self.__walkway["altitude"])
        self.__rectangle3D[1] = Point3D(self.GetStartPosition().x, self.GetStartPosition().y, self._height)
        self.__rectangle3D[2] = Point3D(self.GetEndPosition().x, self.GetEndPosition().y, self._height)
        self.__rectangle3D[3] = Point3D(self.GetEndPosition().x, self.GetEndPosition().y, 0.0)

        # Calculate the rectangle bounding
        self.__boundingRectangle3D = BoundingBox()
        for p in self.__rectangle3D:
            self.__boundingRectangle3D.InsertPoint(p)

        # Calculate the exterior normal vector
        self.CalculateNormalVector()

        return True
コード例 #16
0
ファイル: Infantry.py プロジェクト: neich/BattleField
    def tick(self, tick):
        battalion = tick.target
        selfarmy = tick.blackboard.get('selfarmy', tick.tree.id, None)
        againstarmy = tick.blackboard.get('againstarmy', tick.tree.id, None)
        movedList = tick.blackboard.get('movedList', tick.tree.id, None)
        # Moves troops (usually in battlefield)
        # The moved troops are stored into movedList (used for drawing update reasons)
        #print "Army Move!!!", self.GetCommand().GetType()
        cell = tick.blackboard.get('cell', tick.tree.id, None)
        # Move troops on the battlefield
        # =============================================================================
        w = cell.GetClosestWall()
        tilesmanager = w.GetTileManager()
        
        # Force the battalion to go to closest gateway (if there are any) instead of climbing

        # Bet sure that battalion is in front of a gateway
        gatewayindex = tilesmanager.GetCloseGateway(cell.center, Battles.Utils.Settings.SETTINGS.Get_F('Army', 'Infantry', 'SearchRadiusGoToRumble'))
        if gatewayindex != None:
            
            # Convert all battalion units into "free" climbers and let them to start climbing all together    
            ntroops = battalion.GetNumber()                        
            while ntroops > 0:
                newbattalion = selfarmy.ExtractSoldier(battalion)
                
                # Project a random position on the gateway. Be aware about climbers placed just at the tile edges (they should be placed in other tile columns due
                # precision facts)
                gp = tilesmanager.GetRandomGatewayPosition(gatewayindex = gatewayindex, marginleft = 0.0, marginright = Battles.Utils.Settings.SETTINGS.Get_F('Army', 'Infantry', 'Bounding/Length') / 2.0)
                if not gp:
                    print "ERROR: None random gateway position obtained -> Wrong gateway index"
                    return b3.FAILURE
                
                gpos = Point3D().SetFrom2D(gp)
                gpos.z = cell.GetAltitude()
                
                # Create a stair for each "free" climber to avoid problems with climbing structure
                stair = w.CreateClimbingStair(stairposition = gpos, defendersarmy = againstarmy, climber = newbattalion, movedList = movedList)
                
                # Set the new soldier placement and command
                newbattalion._placement.SetClimbingWall(wall = w, stairposition = gpos, clearprevious = False, stair = stair)
                newbattalion._action.SetCommand(Command.GOTO_CASTLE, w)
                
                if movedList:
                    movedList.append(newbattalion)
            
                ntroops -= 1
            
            if movedList:
                movedList.append(battalion)     
        return b3.SUCCESS
コード例 #17
0
ファイル: TilesManager.py プロジェクト: neich/BattleField
    def GetTileCenter(self, tile):
        # Returns the 3D center of given tile
        # Note that this is the real position, not local wall position

        vector = Vector2D()
        vector.CreateFrom2Points(self.__construction.GetStartPosition(),
                                 self.__construction.GetEndPosition())

        pos = self.__construction.GetStartPosition().Copy()
        pos.Move(vector, (self.__tileDims["width"] * tile.index["column"]) +
                 (self.__tileDims["width"] / 2))

        height = (tile.index["row"] *
                  self.__tileDims["height"]) + (self.__tileDims["height"] / 2)

        return Point3D(pos.x, pos.y, height)
コード例 #18
0
ファイル: GroundCell.py プロジェクト: neich/BattleField
    def __init__(self, battlefield, row, column):
        self.__battleField = battlefield
        self.__movementPenalty = Battles.Utils.Settings.SETTINGS.Get_F(
            'Battlefield', 'GroundCell', 'MovementPenalty')
        self.__defenseIncrease = Battles.Utils.Settings.SETTINGS.Get_F(
            'Battlefield', 'GroundCell', 'DefenseIncrease')
        self.__battalion = None
        self.__index = {"row": row, "column": column}
        self.__groundHeight = Battles.Utils.Settings.SETTINGS.Get_F(
            'Battlefield', 'GroundCell', 'Height')
        self.__constructions = []
        self.__moat = None
        self.__city = False
        self.__trench = None
        self.__river = None

        cellsize = self.__battleField.GetCellSize()
        self.center = Point3D(
            (self.__index["column"] * cellsize) + (cellsize / 2),
            (self.__index["row"] * cellsize) + (cellsize / 2),
            self.__groundHeight)
コード例 #19
0
ファイル: Wall.py プロジェクト: neich/BattleField
    def Project(self, position=Point3D(), wallside=1):
        # Projects given position over the exterior wall
        # If wallside is 1, projects over exterior wall. If it is 2, projects over the back wall side. Finally, if it is 3, projects over the medial axis
        # This is usually used when an attacker needs to be attached to the wall to climb it

        p = Point2D().SetFrom3D(position)

        if wallside == 1:
            prj = self.GetExteriorSegment().ProjectPoint(p)
        elif wallside == 2:
            seg = Segment2D(self._shape2D[3], self._shape2D[2])
            prj = seg.ProjectPoint(p)
        elif wallside == 3:
            seg = Segment2D(self.GetStartPosition(), self.GetEndPosition())
            prj = seg.ProjectPoint(p)
        else:
            return None

        position.x = prj.x
        position.y = prj.y

        return position
コード例 #20
0
    def AppendBattalion(self, battalion, offset=0):
        # Appends a battalion
        # Returns false if there isn't enough space to place the battalion
        # Parameter offset is used to place the next battalion at offset distance - NOT IMPLEMENTED YET -> TODO

        if (self.GetAvaiableCells(margin=offset) == 0):
            return False

        # Calculate next avaiable placement
        nmax = self.__GetMaxCellsNumber(margin=offset)
        ang = 360.0 / nmax
        nextang = (ang * len(self._battalions)) + ang
        nextang = math.radians(nextang)

        p = Point2D()
        p.x = self.__center.x + (math.cos(nextang) * self.__radius)
        p.y = self.__center.y + (math.sin(nextang) * self.__radius)

        self._battalions.append(
            DefendingBattalion(battalion, Point3D(p.x, p.y, self._height)))
        self._battalionsMap[battalion.GetLabel()] = len(self._battalions) - 1

        return True
コード例 #21
0
ファイル: TilesManager.py プロジェクト: neich/BattleField
    def GetNearestHolePosition(self, frompos):
        # Returns the nearest hole position, that is the central tile point of the nearest 0 tile value

        minD = -1
        posMin = Point3D()

        i = 0
        while (i < self.__tilesSize["rows"]):
            j = 0
            while (j < self.__tilesSize["columns"]):
                if (self.__tiles[i][j].IsHole()):
                    center = self.GetTileCenter(self.__tiles[i][j])
                    dist = center.Distance(frompos)
                    if ((dist < minD) or (minD == -1)):
                        minD = dist
                        posMin = center
                j += 1
            i += 1

        if (minD == -1):
            return None
        else:
            return posMin
コード例 #22
0
    def GetRandomCellPosition(self, battalion):
        # Returns a random position inside battalion cell

        db = self.GetDefendingBattalion(battalion)
        if (db == None):
            print "ERROR: Battalion dont found for GetRandomCellPosition"
            return None

        vector = self.__GetVector2D()
        tvector = vector.Copy()
        tvector.Rotate(-90)

        # Move to cell position
        pos = Point2D().SetFrom3D(db.position.Copy())

        # Calculate the random point
        #random.seed()
        r1 = random.uniform(0, self._gridCellSize)
        r2 = random.uniform(0, self._width / 2)
        pos.Move(vector, r1)
        pos.Move(tvector, -r2)

        return Point3D(pos.x, pos.y, self._height)
コード例 #23
0
    def GetSubPositions(self, center, number, bounding):
        # Return a list of positions that should be the center of given bounding subdivided number times and centered at center
        # The subdivision is performed by length
        # This function is usefull for those battalions that want to be dissolved into smaller ones

        ret = []
        if (number <= 0):
            return ret

        parts = (bounding.length / float(number))

        vector = self.__GetVector2D()
        pos = Point2D().SetFrom3D(center)
        pos.Move(vector, (-bounding.length / 2.0) - (parts / 2.0))

        i = 0
        while (i < number):

            pos.Move(vector, parts)
            ret.append(Point3D(pos.x, pos.y, center.z))

            i += 1

        return ret
コード例 #24
0
 def __GetEndLine3D(self):
     return Point3D(self._line.p2.x, self._line.p2.y, self._height)
コード例 #25
0
ファイル: Wall.py プロジェクト: neich/BattleField
    def JoinShape(self, obj, invert=False):
        # Creates and join current shape with given object's shape
        # Note the order of objects: "Current wall is going to be joined with given object". This means that only is calculated the ending wall join
        # The invert flag changes this behaviour (only for towers -> TODO: Also for walls)

        factory = ConstructionFactory()

        if obj == None:
            # None object to join. Constructs a simple rectangular wall shape

            del self._shape2D[0:len(self._shape2D)]

            l = self.GetLength()
            vector = Vector2D()
            vector.CreateFrom2Points(self.GetStartPosition(), self.GetEndPosition())
            tvector = vector.Copy()
            tvector.Rotate(-90)

            p = self.GetStartPosition().Copy()
            p.Move(tvector, self._thickness / 2)
            self._shape2D.append(p.Copy())
            p.Move(vector, l)
            self._shape2D.append(p.Copy())
            p.Move(tvector, -self._thickness)
            self._shape2D.append(p.Copy())
            p.Move(vector, -l)
            self._shape2D.append(p.Copy())

            return

        else:

            # Updates the adjacencies

            if invert:
                self._adjacentConstructions[0] = obj
                obj._adjacentConstructions[1] = self
            else:
                self._adjacentConstructions[1] = obj
                obj._adjacentConstructions[0] = self

        if factory.IsWall(obj):

            # Calculate the bisector between both walls
            bisecang = self.GetBisector(obj)

            # The join point will be along the bisector 
            d = (self._thickness / 2.0) / math.cos(
                math.radians(bisecang["angle"] / 2.0))  # WARNING: We consider all walls of same thickness
            p = self.GetEndPosition().Copy()
            p.Move(bisecang["bisector"], d)

            self._shape2D[1] = p.Copy()
            obj._shape2D[0] = p.Copy()

            p.Move(bisecang["bisector"], -(d * 2.0))
            self._shape2D[2] = p.Copy()
            obj._shape2D[3] = p.Copy()

            self._adjacentConstructions[1] = obj
            obj._adjacentConstructions[0] = self




        elif factory.IsSquaredTower(obj):

            # Calculate the intersection points of wall shape with tower   

            # We must consider the invert flag. If it is true, the joined part will be the starting wall. Otherwise, the ending wall
            if invert:
                v = Vector3D().SetFrom2D(self.GetWallVector())
                v.Invert()
                ray1 = Ray(origin=Point3D().SetFrom2D(self._shape2D[1]), direction=v)
                ray2 = Ray(origin=Point3D().SetFrom2D(self._shape2D[2]), direction=v)
            else:
                v = Vector3D().SetFrom2D(self.GetWallVector())
                ray1 = Ray(origin=Point3D().SetFrom2D(self._shape2D[0]), direction=v)
                ray2 = Ray(origin=Point3D().SetFrom2D(self._shape2D[3]), direction=v)

            int1 = obj.RecieveImpact(ray1)
            int2 = obj.RecieveImpact(ray2)

            if int1 != None:
                if invert:
                    self._shape2D[0] = Point2D().SetFrom3D(int1)
                else:
                    self._shape2D[1] = Point2D().SetFrom3D(int1)
            if int2 != None:
                if invert:
                    self._shape2D[3] = Point2D().SetFrom3D(int2)
                else:
                    self._shape2D[2] = Point2D().SetFrom3D(int2)

            # Reshape the wall axis (and all dependant data). Get the medium points of side shape segments
            mp1 = Segment2D(self._shape2D[0], self._shape2D[3]).GetMidPoint()
            mp2 = Segment2D(self._shape2D[1], self._shape2D[2]).GetMidPoint()
            self.SetPosition(mp1, mp2, reshape=False)


        elif factory.IsRoundedTower(obj):

            # Calculate the intersection points of wall shape with tower   

            # We must consider the invert flag. If it is true, the joined part will be the starting wall. Otherwise, the ending wall
            if invert:
                v = Vector3D().SetFrom2D(self.GetWallVector())
                v.Invert()
                ray1 = Ray(origin=Point3D().SetFrom2D(self._shape2D[1]), direction=v)
                ray2 = Ray(origin=Point3D().SetFrom2D(self._shape2D[2]), direction=v)
            else:
                v = Vector3D().SetFrom2D(self.GetWallVector())
                ray1 = Ray(origin=Point3D().SetFrom2D(self._shape2D[0]), direction=v)
                ray2 = Ray(origin=Point3D().SetFrom2D(self._shape2D[3]), direction=v)

            int1 = obj.RecieveImpact(ray1)
            int2 = obj.RecieveImpact(ray2)

            if int1 != None:
                if invert:
                    self._shape2D[0] = Point2D().SetFrom3D(int1)
                else:
                    self._shape2D[1] = Point2D().SetFrom3D(int1)
            if int2 != None:
                if invert:
                    self._shape2D[3] = Point2D().SetFrom3D(int2)
                else:
                    self._shape2D[2] = Point2D().SetFrom3D(int2)

            # Reshape the wall axis (and all dependant data). Get the medium points of side shape segments
            mp1 = Segment2D(self._shape2D[0], self._shape2D[3]).GetMidPoint()
            mp2 = Segment2D(self._shape2D[1], self._shape2D[2]).GetMidPoint()
            self.SetPosition(mp1, mp2, reshape=False)


        elif factory.IsBastion(obj):
            # Fit the wall to the bastion

            if invert:
                self._shape2D[3] = obj.GetEndPosition(exterior=False)
                self._shape2D[0] = obj.GetEndPosition(exterior=True)
            else:
                self._shape2D[1] = obj.GetStartPosition(exterior=True)
                self._shape2D[2] = obj.GetStartPosition(exterior=False)

            # Reshape the wall axis (and all dependant data). Get the medium points of side shape segments
            mp1 = Segment2D(self._shape2D[0], self._shape2D[3]).GetMidPoint()
            mp2 = Segment2D(self._shape2D[1], self._shape2D[2]).GetMidPoint()
            self.SetPosition(mp1, mp2, reshape=False)
コード例 #26
0
 def GetStartCircle3D(self):
     p = Point3D()
     p.x = self.__center.x
     p.y = self.__center.y
     p.z = self._height
コード例 #27
0
 def GetPosition(self):
     return Point3D()
コード例 #28
0
 def GetWeakestPoint(self):
     if (len(self.__weakestConstructionList) > 0):
         return self.__weakestConstructionList[0]["weakPoint"]
     else:
         return Point3D()
コード例 #29
0
    def CalculateResults(self):
        # Performs results calculations to extract useful data
        self.__meanRounds = 0
        self.__attackersVictories = 0
        self.__defendersVictories = 0
        self.__attackersKilled = 0
        self.__defendersKilled = 0
        del self.__constructionsDefeated["Climbed"][
            0:len(self.__constructionsDefeated["Climbed"])]
        del self.__constructionsDefeated["Fall"][
            0:len(self.__constructionsDefeated["Fall"])]
        del self.__constructionsDefeated["SiegeTower"][
            0:len(self.__constructionsDefeated["SiegeTower"])]
        del self.__weakestConstructionList[0:len(self.__weakestConstructionList
                                                 )]

        if (len(self.__resultsList) == 0):
            Message.Log('No statistics for 0 games',
                        Message.VERBOSE_STATISTICS)
            return

        # Gather results
        constr = {}
        for r in self.__resultsList:
            self.__meanRounds += r.GetRounds()

            if (r.IsWallDefeated()):
                w = constr.get(r.GetConstruction())
                if (w == None):
                    constr[r.GetConstruction()] = {
                        "number": 1,
                        "climbs": [],
                        "falls": [],
                        "siegetowers": []
                    }
                else:
                    constr[r.GetConstruction()]["number"] += 1

                if (r.IsWallDefeatedByClimbing()):
                    constr[r.GetConstruction()]["climbs"].append(
                        r.GetPosition())
                elif (r.IsWallDefeatedByFall()):
                    constr[r.GetConstruction()]["falls"].append(Point3D())
                elif (r.IsWallDefeatedBySiegeTower()):
                    constr[r.GetConstruction()]["siegetowers"].append(
                        r.GetPosition())
            else:
                if (r.AttackersWon()):
                    self.__defendersKilled += 1
                else:
                    self.__attackersKilled += 1

            if (r.AttackersWon()):
                self.__attackersVictories += 1

        self.__meanRounds /= len(self.__resultsList)

        self.__defendersVictories = len(
            self.__resultsList) - self.__attackersVictories

        # Calculate constructions weak points clustering all succeed climbings
        tmplist = []
        for k, v in constr.iteritems():

            cclimb = ClusteringKMeans(points=v["climbs"], initialMeans=3)
            cclimb.execute()
            weakclimb = cclimb.GetLargestCluster()

            sclimb = ClusteringKMeans(points=v["siegetowers"], initialMeans=3)
            sclimb.execute()
            weaksiegetower = sclimb.GetLargestCluster()

            if (len(v["climbs"]) > 0):
                self.__constructionsDefeated["Climbed"].append({
                    "label":
                    k,
                    "defeats":
                    len(v["climbs"]),
                    "weakPoint":
                    weakclimb
                })
            if (len(v["falls"]) > 0):
                self.__constructionsDefeated["Fall"].append({
                    "label":
                    k,
                    "defeats":
                    len(v["falls"]),
                    "weakPoint":
                    Point3D()
                })
            if (len(v["siegetowers"]) > 0):
                self.__constructionsDefeated["SiegeTower"].append({
                    "label":
                    k,
                    "defeats":
                    len(v["siegetowers"]),
                    "weakPoint":
                    weaksiegetower
                })

            # Calculate the weakest point in construction
            wc = {"label": None, "defeats": 0, "weakPoint": Point3D()}

            wc["label"] = k
            wc["defeats"] = v["number"]

            wlst = v["climbs"]
            wlst.extend(v["siegetowers"])
            wclust = ClusteringKMeans(points=wlst, initialMeans=3)
            wclust.execute()
            wc["weakPoint"] = wclust.GetLargestCluster()

            tmplist.append(wc)

        # Finally, sort the weakest construction list by number of defeats
        self.__weakestConstructionList = sorted(tmplist,
                                                key=lambda k: k['defeats'],
                                                reverse=True)
コード例 #30
0
 def __GetStartLine3D(self):
     return Point3D(self._line.p1.x, self._line.p1.y, self._height)