Пример #1
0
def ai_rank(c, hmod=1, mxhmod=1):
    # Gets a card's rank based on its stats
    out = ((c.card.cost * v.aiMod["c_costMod"])
             + ((c.card.attack + c.changes["attack"]) * v.aiMod["c_attackMod"])
             + ((c.card.health + c.changes["health"]) * v.aiMod["c_healthMod"] * hmod)
             + ((c.card.health / (c.card.health + c.changes["health"])) * v.aiMod["c_mxHealthMod"] * mxhmod))
    
    path = pathfind.pathfind(c.tile.pos, (-1, 1), pathfind.get_grid(castle=True))
    # Gets card's distance from opponent castle
    if path != False:
        while path[-1][0] > 3 and path[-2][0] > 3:
            path = path[:-1]
        if len(path) >= c.card.speed + c.changes["speed"] or c.tile.pos[0] + c.tile.range >= 4:
            out += ((c.card.attack + c.changes["attack"]) * v.aiMod["c_attackMod"])
            out += (20 / v.opHealth) * v.aiMod["p_castleMod"]
        
    return out
Пример #2
0
def changes():
    """Will implement the list of changes fetched from the game server"""
    for event in v.networkChanges:
        if v.online == False and event["type"] == "turn" and len(v.networkChanges) > 1:
            v.networkChanges.append(v.networkChanges.pop(0))
        if event["type"] == "place":
            pos = event["position"]
            pos = (3 - pos[0], pos[1])
            cunid = event["unid"]
            for tile in v.tiles:
                if tile.pos == pos:
                    target = tile
            card = v.cards[event["id"]]
            gameItems.add_card(card, tile=target, unid=cunid, player=v.opUnid, renSize=(100, 140), opintro=True)
        
        if event["type"] == "move":
            pos = event["position"]
            pos = (3 - pos[0], pos[1])
            c = None
            for card in v.gameCards:
                if card.unid == event["unid"]:
                    c = card
            if c == None:
                continue
            for tile in v.tiles:
                if tile.pos == pos:
                    path = pathfind.pathfind(c.tile.pos, pos, pathfind.get_grid())
                    c.tile = tile
            c.movePath = path
        
        if event["type"] == "movable" or "movable" in event.keys():
            c = None
            for card in v.gameCards:
                if card.unid == event["unid"]:
                    c = card
            if c == None:
                continue
            if event["movable"]:
                c.moves = 1
            else:
                c.moves = 0
        
        if event["type"] == "damage":
            for card in v.gameCards:
                if card.unid == event["unid"]:
                    c = card
            if event["target"] == v.unid:
                v.pHealth -= c.card.attack + c.changes["attack"]
                c.attack("player")
            else:
                for card in v.gameCards:
                    if card.unid == event["target"]:
                        t = card
                c.changes["health"] -= t.card.attack + t.changes["attack"]
                t.changes["health"] -= c.card.attack + c.changes["attack"]
                c.attack(t)
            #c._render((100, 140))
            #t._render((100, 140))
        
        if event["type"] == "spell":
            for card in v.gameCards:
                if card.unid == event["target"]:
                    target = card
            if "damage" in event["effects"].keys():
                target.changes["health"] -= event["effects"]["damage"]
            
            gameItems.Effect(event["animation"], target=target, sheet="assets/images/effects/fireball.png")
            target._render((100, 140))
                
        if event["type"] == "turn":
            v.gameTurn = event["turn"]
            for s in v.gameCards:
                if s.type == "minion":
                    if v.gameTurn["player"] == v.unid: # If player's turn
                        if s.player == v.unid and s.tile != None:
                            s.next_turn()
                    if v.gameTurn["player"] == v.opUnid: # If opponent's turn
                        if s.player == v.opUnid:
                            s.moves = 1
            if v.gameTurn["player"] == v.unid: # If player's turn
                if len(v.hand) < 4:
                    for card in v.gameDeck:
                        if card.order == 0:
                            card.aniCycle = 1
                        else:
                            card.order -= 1
                v.pturn.cycle = 1
                if v.totalMana < 10:
                    v.totalMana += 1
                v.pMana = v.totalMana
        if event["type"] == "stop":
            v.gameStop = event["reason"]
            v.networkHalt = True
        
        if v.online == False:
            v.networkChanges.remove(event)
            return
    v.networkChanges = []
Пример #3
0
    def update(self):
        if self.rect.collidepoint(v.mouse_pos):
            self.hovered = True
        else:
            self.hovered = False
        
        self.attack = False
        
        self.card = None
        for card in v.gameCards:
            if card.tile == self:
                self.card = card
        
        if v.dragCard != None:
            #If card is being dragged
            if v.dragCard.type == "minion":
                #If it is a minion card
                if v.dragCard.tile == None:
                    #If the card is in the player's hand
                    if self.pos[0] < 2:
                        v.availableTiles.add(self)
                else:
                    #If the card is on the board
                    if self.castle == None:
                        #If this tile isn't a castle tile
                        path = pathfind.pathfind(v.dragCard.tile.pos, self.pos, pathfind.get_grid(skip=[]))
                        a = False
                        for card in v.gameCards:
                            if card.tile == self:
                                if card.player == v.opUnid:
                                    a = True
                                    path = pathfind.pathfind(v.dragCard.tile.pos, self.pos, pathfind.get_grid(skip=[self]))
                        if path != False and len(path) - 1 <= v.dragCard.moves and v.dragCard.card.speed > 0:
                            v.availableTiles.add(self)
                            if a:
                                self.attack = True
                        if v.dragCard.moves > 0 and v.dragCard.range > 0 and a and abs(v.dragCard.tile.pos[0] - self.pos[0]) <= v.dragCard.range and abs(v.dragCard.tile.pos[1] - self.pos[1]) <= v.dragCard.range:
                            v.availableTiles.add(self)
                            self.attack = True
                    else:
                        #If this tile is a castle tile
                        if self.castle == False:
                            paths = [pathfind.pathfind((v.dragCard.tile.pos[0] + 1, v.dragCard.tile.pos[1]), (self.pos[0] + 1, 0), pathfind.get_grid(skip=[], castle=True)), 
                                     pathfind.pathfind((v.dragCard.tile.pos[0] + 1, v.dragCard.tile.pos[1]), (self.pos[0] + 1, 1), pathfind.get_grid(skip=[], castle=True)), 
                                     pathfind.pathfind((v.dragCard.tile.pos[0] + 1, v.dragCard.tile.pos[1]), (self.pos[0] + 1, 2), pathfind.get_grid(skip=[], castle=True))]
                            paths = [p for p in paths if p != False]
                            if len(paths) > 0:
                                path = paths[0]
                                for p in paths:
                                    if len(p) < len(path):
                                        path = p
                            else:
                                path = False
                                    
                            if path != False and len(path) - 1 <= v.dragCard.moves and v.dragCard.card.speed > 0:
                                v.availableTiles.add(self)
                                self.attack = True
                        
            if v.dragCard.type == "spell":
                if self.card != None:
                    v.availableTiles.add(self)
                    self.attack = True
                    
                    
                
        if v.availableTiles != None:
            if not self in v.availableTiles:
                self.hovered = False
 
        self.rimage = self.image.copy()
        
        if self.card != None:
            if self.card.player == v.unid:
                self.rimage.fill((100, 255, 100, 200), special_flags=py.BLEND_RGBA_MULT)
            else:
                self.rimage.fill((255, 100, 100, 200), special_flags=py.BLEND_RGBA_MULT)
        
        if self.castle != None:
            if self.attack:
                self.rimage = self.image.copy()
            else:
                self.rimage = py.Surface((0, 0))
        
        if self.hovered:
            v.hoverTile = self
            if self.attack:
                self.rimage.fill((200, 200, 200, 0), special_flags=py.BLEND_RGBA_MAX)
            else:
                self.rimage.fill((255, 255, 255, 200))
            
        self.draw()
Пример #4
0
def ai_action(board, c, targets):
    bestAction = (None, 0)
    #print("====", c.card.id, c.tile.pos, "====")
    for y in range(3):
        for x in range(-1, 4):
            curRank = 0
            path = pathfind.pathfind((c.tile.pos[0] + 1, c.tile.pos[1]), (x + 1, y), pathfind.get_grid(skip=[(x, y)], castle=True))
            #print(">>", (x, y))
            if path != False:
                path = [(p[0]-1, p[1]) for p in path]
                card = board[y][x] # Card is actually a tile... oops
                if card != "" or x == -1 or x == 4 and (x, y) != c.tile.pos:
                    if len(path) > 1:
                        while path[-2][0] > 3 or path[-2][0] < -1:
                            path = path[:-1]
                    if x == -1:
                        curRank = [t["rank"] for t in targets if t["card"] == "pCastle"][0]
                    elif x == 4:
                        curRank = [t["rank"] for t in targets if t["card"] == "aiCastle"][0]
                    elif card != "":
                        for t in targets:
                            if t["card"] == card and t["card"].player != 0:
                                curRank += t["rank"]
                    else:
                        curRank = 0
                    speedDiff = len(path) - c.card.speed + c.changes["speed"]
                    if speedDiff > 0:
                        curRank -= speedDiff * v.aiMod["m_moveDiffMod"]
                    
                    #print("----", curRank, path)
                    
                    if curRank > bestAction[1]:
                        #print("^^^^ overtake")
                        while len(path) > c.card.speed + c.changes["speed"] + 1:
                            path = path[:-1]
                        
                        event = []
                        if len(path) != 0 and c.card.speed + c.changes["speed"] > 0:
                            if path[-1][0] == -1 or path[-1][0] == 4:
                                while len(path) > 0 and (path[-1][0] < 0 or path[-1][0] > 3):
                                    path = path[:-1]
                                if len(path) > 1:
                                    event.append({"type": "move", "unid": c.unid, "position": ai_invertCoords(path[-1])})
                                if len(path) == 0 or path[-1][0] == -1:
                                    event.append({"type": "damage", "unid": c.unid, "target": v.unid})
                                    #print("++++ damage castle")
                            else:
                                target = board[path[-1][1]][path[-1][0]]
                                if target != "":
                                    if len(path) > 1:
                                        event.append({"type": "move", "unid": c.unid, "position": ai_invertCoords(path[-2])})
                                    event.append({"type": "damage", "unid": c.unid, "target": target.unid})
                                    #print("++++ damage", target.unid, target.tile.pos, (path[-1][0], path[-1][1]))
                                    if c.range == 0 and target.changes["health"] + target.card.health - (c.card.attack + c.changes["attack"]) <= 0 and c.changes["health"] + c.card.health - (target.card.attack + target.changes["attack"]) > 0:
                                        event[-1]["kill"] = True
                                        event.append({"type": "move", "unid": c.unid, "position": ai_invertCoords(target.tile.pos)})
                                else:
                                    event.append({"type": "move", "unid": c.unid, "position": ai_invertCoords(path[-1])})
                            bestAction = (event, curRank)
    if bestAction[0] != None:
        bestAction[0][-1]["movable"] = False
        v.networkChanges.extend(bestAction[0])
        #v.networkChanges.append({"type": "movable", "unid": c.unid, "movable": False})
        for e in bestAction[0]:
            if e["type"] == "move":
                board[ai_invertCoords(e["position"])[1]][ai_invertCoords(e["position"])[0]] = ""
            if e["type"] == "damage":
                if "kill" in e.keys():
                    for y in range(3):
                        for x in range(4):
                            if board[y][x] != "" and board[y][x].unid == e["target"]:
                                board[y][x] = ""
Пример #5
0
 def update(self):
     self._pre_update()
     if self.updateDelay != 0:
         self.updateDelay -= 1
     if self.card.health + self.changes["health"] <= 0:
         if not self.movePath and self.attackTarget == None:
             if self.updateDelay <= 0:
                 self.kill()
     if self.schRender:
         self._render(self.schRenderSize)
     for event in v.events:
         # If the card is allowed to be interacted with
         if v.gameTurn != None and v.gameTurn["player"] == v.unid and self.alive():
             # Begin dragging
             if self.hovered and event.type == py.MOUSEBUTTONDOWN and event.button == 1 and self.player == v.unid:
                 self.drag = True
                 self.dragPoint = (v.mouse_pos[0] - self.rect.x, v.mouse_pos[1] - self.rect.y)
                 v.dragCard = self
                 v.availableTiles = py.sprite.Group()
             # End Dragging
             if event.type == py.MOUSEBUTTONUP and event.button == 1 and self.drag:
                 self.drag = False
                 v.dragCard = None
                 v.availableTiles = None
                 self.preCard = []
                 self.postCard = []
                 # Card in hand
                 if self.tile == None:
                     if v.pMana >= self.card.cost:
                         for tile in v.tiles:
                             if tile.hovered:
                                 self.tile = tile
                         if self.tile != None:
                             v.pMana -= self.card.cost
                             v.networkEvents.append({"type": "place", "id": self.card.id, "position": self.tile.pos, "unid": self.unid})
                             self._render((100, 140))
                             for card in v.gameCards:
                                 if card.tile == None:
                                     if card.order > self.order:
                                         card.order -= 1
                 # Card on board
                 else:
                     if v.hoverTile == None:
                         pass
                     # If a tile is being hovered
                     else:
                         # If the hovered tile isn't the current tile
                         if v.hoverTile != self.tile:
                             # If the hovered tile is attackable
                             if v.hoverTile.attack:
                                 if self.range == 0:
                                     path = pathfind.pathfind((self.tile.pos[0] + 1, self.tile.pos[1]), (v.hoverTile.pos[0] + 1, v.hoverTile.pos[1]), pathfind.get_grid(skip=[v.hoverTile], castle=True))
                                     path = [(p[0]-1, p[1]) for p in path]
                                     self.movePath = path[:-1]
                                     while self.movePath[-1][0] > 3 or self.movePath[-1][0] < -1:
                                         self.movePath = self.movePath[:-1]
                                     if len(path) < 2:
                                         print("Bad path length", path, self.movePath)
                                     pos = self.movePath[-1]
                                     for tile in v.tiles:
                                         if tile.pos == pos:
                                             self.tile = tile
                                     v.networkEvents.append({"type": "move", "unid": self.unid, "position": pos})
                                 self.moves = 0
                                 # If the target is another minion
                                 if v.hoverTile.castle == None:
                                     target = v.hoverTile.card
                                     v.networkEvents.append({"type": "damage", "unid": self.unid, "target": target.unid})
                                     if self.range == 0:
                                         self.changes["health"] -= target.card.attack + target.changes["attack"]
                                     target.changes["health"] -= self.card.attack + self.changes["attack"]
                                     target.updateDelay += 20
                                     self.updateDelay += 20
                                     self.attackTarget = target
                                     if self.range == 0 and target.changes["health"] + target.card.health <= 0 and self.changes["health"] + self.card.health > 0:
                                         v.networkEvents.append({"type": "move", "unid": self.unid, "position": v.hoverTile.pos})
                                         self.attackWon = True
                                 # If the target is a castle
                                 else:
                                     v.networkEvents.append({"type": "damage", "unid": self.unid, "target": v.opUnid})
                                     v.opHealth -= self.card.attack + self.changes["attack"]
                                     self.attackTarget = "enemy"
                             # If the hovered card isn't attackable 
                             else:
                                 path = pathfind.pathfind(self.tile.pos, v.hoverTile.pos, pathfind.get_grid(skip=[v.hoverTile]))
                                 self.movePath = path
                                 self.tile = v.hoverTile
                                 v.networkEvents.append({"type": "move", "unid": self.unid, "position": self.tile.pos})
                                 self.moves -= len(path) - 1
                 if self.alive():
                     if self.moves <= 0:
                         v.networkEvents.append({"type": "movable", "unid": self.unid, "movable": False})
                     else:
                         v.networkEvents.append({"type": "movable", "unid": self.unid, "movable": True})
     if self.tile == None:
         self._hand_update()
     else:
         self.rect = py.Rect((0, 0), (100, 140))
         self.rimage = self.image.copy()
         if self.movePath: # and not (len(self.movePath) <= 1 and self.attackTarget != None)
             #if not (len(self.movePath) == 1 and self.attackTarget != None):
             self.move()
         else:
             self.rect.center = self.tile.rect.center
         if self.attackTarget != None:
             self.attack()
         if self.moves <= 0:
             self.rimage.fill((150, 150, 150), special_flags=py.BLEND_MULT)
     if self.drag and self.tile != None:
         self.preCard = []
         self.postCard = []
         if v.hoverTile != None and v.hoverTile != self.tile:
             if v.hoverTile.castle == None:
                 path = pathfind.pathfind(self.tile.pos, v.hoverTile.pos, pathfind.get_grid(skip=[v.hoverTile]))
             else:
                 path = pathfind.pathfind((self.tile.pos[0] + 1, self.tile.pos[1]), (v.hoverTile.pos[0] + 1, self.tile.pos[1]), pathfind.get_grid(skip=[v.hoverTile], castle=True))
                 path = [(p[0]-1, p[1]) for p in path]
             for i in range(len(path) - 1):
                 arrowRect = py.Rect(0, 0, 100, 100)
                 if path[i + 1][0] > path[i][0]:
                     arrowRect.centery = 130 + path[i][1] * 150
                     arrowRect.left = 415 + path[i][0] * 150 + 50
                     rarrow = self.arrow.copy()
                 if path[i + 1][0] < path[i][0]:
                     arrowRect.centery = 130 + path[i][1] * 150
                     arrowRect.right = 415 + path[i][0] * 150 - 50
                     rarrow = py.transform.rotate(self.arrow, 180)
                 if path[i + 1][1] > path[i][1]:
                     arrowRect.centerx = 415 + path[i][0] * 150
                     arrowRect.top = 130 + path[i][1] * 150 + 50
                     rarrow = py.transform.rotate(self.arrow, -90)
                 if path[i + 1][1] < path[i][1]:
                     arrowRect.centerx = 415 + path[i][0] * 150
                     arrowRect.bottom = 130 + path[i][1] * 150 - 50
                     rarrow = py.transform.rotate(self.arrow, 90)
                 self.preCard.append((rarrow, arrowRect))
             if v.hoverTile.attack:
                 drect = py.Rect(0, 0, 100, 100)
                 drect.center = v.hoverTile.rect.center
                 self.preCard.append((self.damage, drect))
                 font = py.font.Font("assets/fonts/Galdeano.ttf", 30)
                 dmg = font.render(str(-self.card.attack), 1, (0, 0, 0))
                 drect = dmg.get_rect()
                 drect.center = v.hoverTile.rect.center
                 self.preCard.append((dmg, drect))
                 if v.hoverTile.castle == None and self.range == 0:
                     target = v.hoverTile.card
                     drect = py.Rect(0, 0, 100, 100)
                     drect.center = self.tile.rect.center
                     self.postCard.append((self.damage, drect))
                     font = py.font.Font("assets/fonts/Galdeano.ttf", 30)
                     dmg = font.render(str(-target.card.attack), 1, (0, 0, 0))
                     drect = dmg.get_rect()
                     drect.center = self.tile.rect.center
                     self.postCard.append((dmg, drect))
         if v.hoverTile == self.tile:
             self.rarrow = None
         if v.hoverTile == None:
             self.rarrow = None
     if self.opintro:
         self._opintro()
     self.draw()