def prepareBotsDraw(self): slots = OrderedDict({}) RBots = self.session.query(db.Bots).order_by(db.Bots.slotsEmpty.desc()).all() for RBot in RBots: slots[RBot.id] = RBot.slotsEmpty # Create a dictionary with additional items data itemsBots = {} for item in self.RMatch.BetsTotal1.items: itemsBots[item[2]] = int(item[3]) for item in self.RMatch.BetsTotal2.items: itemsBots[item[2]] = int(item[3]) # Find optimal bots for the players' items trades = OrderedDefaultDict(lambda: defaultdict(dict)) self.playersBots = {} for playerIndex, RBet in enumerate(self.drawBets): botsItems = defaultdict(list) for assetID in RBet.items: botsItems[itemsBots[assetID]] += [assetID] # Iterate over bots to find the one with enough slots to fit all items while botsItems: tradesCopy = trades.copy() slotsCopy = OrderedDict() slotsCopy.update(slots) bestBot = max(botsItems, key=lambda x:len(botsItems[x])) itemsCounts = Counter({}) itemsIDs = defaultdict(list) # Create dictionaries for other bots' items for assetID in RBet.items: if itemsBots[assetID] != bestBot: itemsCounts[itemsBots[assetID]] += 1 itemsIDs[itemsBots[assetID]] += [assetID] # Iterate over other bots' items to find the best tradeoffer to add them to for otherBot, itemsCount in itemsCounts.items(): bestKey = "%d_%d" % (bestBot, otherBot) otherKey = "%d_%d" % (otherBot, bestBot) result = 0 for botsKey, tradeCopy in tradesCopy.items(): if bestKey or otherKey in botsKey: result = 1 if tradeCopy[bestBot]["slots"] >= itemsCount: result = 2 break # Add a trade if possible otherwise mark this trial as failed if result == 1 or result == 0: if slotsCopy[bestBot] >= itemsCount: if result == 1: keyArray = botsKey.split("_") botsKey = "%d_%d_%d" % (bestBot, otherBot, keyArray[2] + 1) else: botsKey = "%d_%d_0" % (bestBot, otherBot) tradesCopy[botsKey][bestBot]["slots"] = 0 tradesCopy[botsKey][otherBot]["slots"] = 0 tradesCopy[botsKey][bestBot]["receive"] = [] tradesCopy[botsKey][otherBot]["receive"] = [] else: del botsItems[bestBot] break slotsCopy[bestBot] -= itemsCounts[otherBot] slotsCopy[otherBot] += itemsCounts[otherBot] tradesCopy[botsKey][bestBot]["slots"] = slotsCopy[bestBot] tradesCopy[botsKey][otherBot]["slots"] = slotsCopy[otherBot] tradesCopy[botsKey][bestBot]["receive"] += itemsIDs[otherBot] else: # Add trades information if items can fit in bots inventory trades = tradesCopy slots = sorted(slotsCopy.iteritems(), key = lambda x:x[1], reverse = True) self.playersBots[playerIndex] = bestBot break self.newIDs = {} for botsKey, trade in trades.items(): keyArray = botsKey.split("_") mainBot = int(keyArray[0]) otherBot = int(keyArray[1]) mainHandler = self.Handlers[mainBot] mainPartner = mainHandler.Bot.Community().Friend(mainHandler.Meta.steamID) otherHandler = self.Handlers[otherBot] otherPartner = mainHandler.Bot.Community().Friend(otherHandler.Meta.steamID) otherPartner.token = otherHandler.Meta.token itemsToGive = [] itemsToReceive = [] for assetID in trade[otherBot]["receive"]: itemsToGive.append({ "appid": 440, "contextid": 2, "amount": 1, "assetid": str(assetID) }) for assetID in trade[mainBot]["receive"]: itemsToReceive.append({ "appid": 440, "contextid": 2, "amount": 1, "assetid": str(assetID) }) offerID = mainHandler.Bot.Trade().sendOffer(otherPartner, itemsToGive, itemsToReceive, "Those are the items for match %d" % self.RMatch.id) otherHandler.Bot.Trade().Offer(offerID, mainPartner).accept() inventory = mainHandler.Bot.Community().Inventory() for items in inventory.values(): for id, item in items.items(): if item["originID"] in self.assetIDs: self.newIDs[self.assetIDs[item["originID"]]] = item["assetID"]
def prepareBotsDraw(self): slots = OrderedDict({}) for botID, RBot in self.RBots.items(): slots[botID] = RBot.slotsEmpty slots = sorted(slots.iteritems(), key = lambda x:x[1], reverse = True) # Find optimal bots for the players' items trades = OrderedDefaultDict(lambda: defaultdict(dict)) self.playersBots = {} for playerIndex, RBet in enumerate(self.drawBets): botsItems = defaultdict(list) for item in RBet.items: botsItems[self.itemsBots[item[2]]] += [item[2]] # Iterate over bots to find the one with enough slots to fit all items while botsItems: tradesCopy = trades.copy() slotsCopy = OrderedDict() slotsCopy.update(slots) bestBot = max(botsItems, key=lambda x:len(botsItems[x])) itemsCounts = Counter({}) itemsIDs = defaultdict(list) # Create dictionaries for other bots' items for item in RBet.items: if self.itemsBots[item[2]] != bestBot: itemsCounts[self.itemsBots[item[2]]] += 1 itemsIDs[self.itemsBots[item[2]]] += [item[2]] # Iterate over other bots' items to find the best tradeoffer to add them to for otherBot, itemsCount in itemsCounts.items(): bestKey = "%d_%d" % (bestBot, otherBot) otherKey = "%d_%d" % (otherBot, bestBot) result = 0 for botsKey, tradeCopy in tradesCopy.items(): if bestKey in botsKey or otherKey in botsKey: result = 1 if tradeCopy[bestBot]["slots"] >= itemsCount: result = 2 break # Add a trade if possible otherwise mark this trial as failed if result == 1 or result == 0: if slotsCopy[bestBot] >= itemsCount: if result == 1: keyArray = botsKey.split("_") botsKey = "%d_%d_%d" % (bestBot, otherBot, keyArray[2] + 1) else: botsKey = "%d_%d_0" % (bestBot, otherBot) tradesCopy[botsKey][bestBot]["slots"] = 0 tradesCopy[botsKey][otherBot]["slots"] = 0 tradesCopy[botsKey][bestBot]["receive"] = [] tradesCopy[botsKey][otherBot]["receive"] = [] else: del botsItems[bestBot] break slotsCopy[bestBot] -= itemsCounts[otherBot] slotsCopy[otherBot] += itemsCounts[otherBot] tradesCopy[botsKey][bestBot]["slots"] = slotsCopy[bestBot] tradesCopy[botsKey][otherBot]["slots"] = slotsCopy[otherBot] tradesCopy[botsKey][bestBot]["receive"] += itemsIDs[otherBot] else: # Add trades information if items can fit in bots inventory trades = tradesCopy slots = sorted(slotsCopy.iteritems(), key = lambda x:x[1], reverse = True) self.playersBots[playerIndex] = bestBot break self.newIDs = {} count = 0 for botsKey, trade in trades.items(): keyArray = botsKey.split("_") mainBot = int(keyArray[0]) otherBot = int(keyArray[1]) mainHandler = self.SteamHandlers[mainBot] mainInventory, slots = mainHandler.botInventory() mainPartner = mainHandler.Bot.Community().Friend(mainHandler.Meta["steamID"]) otherHandler = self.SteamHandlers[otherBot] otherInventory, slots = otherHandler.botInventory() otherPartner = mainHandler.Bot.Community().Friend(otherHandler.Meta["steamID"]) otherPartner.token = otherHandler.Meta["token"] botItems = {} for items in mainInventory.values(): for item in items.values(): botItems[item["originID"]] = item for items in otherInventory.values(): for item in items.values(): botItems[item["originID"]] = item itemsToGive = [] itemsToReceive = [] for originID in trade[otherBot]["receive"]: itemsToGive.append({ "appid": 440, "contextid": 2, "amount": 1, "assetid": str(botItems[originID]["assetID"]) }) for originID in trade[mainBot]["receive"]: itemsToReceive.append({ "appid": 440, "contextid": 2, "amount": 1, "assetid": str(botItems[originID]["assetID"]) }) offerID, UUID = mainHandler.Bot.Trade().sendOffer(otherPartner, itemsToGive, itemsToReceive, "Those are the items for match %d" % self.RMatch.id) if offerID is False: return False otherHandler.Bot.Trade().Offer(offerID, mainPartner).accept() originIDs = [] accepted = False mainInventory, slots = mainHandler.botInventory() for items in mainInventory.values(): for item in items.values(): originIDs += [item["originID"]] for originID in originIDs: if originID in trade[mainBot]["receive"]: accepted = True for originID in trade[otherBot]["receive"]: if originID not in originIDs: accepted = True if not accepted: return False count += 1 for originID in trade[mainBot]["receive"]: item = [botItems[originID]["defindex"], botItems[originID]["quality"], botItems[originID]["originID"]] self.RBotsItems[mainBot].items = self.RBotsItems[mainBot].items + [item] self.RBotsItems[otherBot].items = [testedItem for testedItem in self.RBotsItems[otherBot].items if testedItem != item] for originID in trade[otherBot]["receive"]: item = [botItems[originID]["defindex"], botItems[originID]["quality"], botItems[originID]["originID"]] self.RBotsItems[otherBot].items = self.RBotsItems[otherBot].items + [item] self.RBotsItems[mainBot].items = [testedItem for testedItem in self.RBotsItems[mainBot].items if testedItem != item] return True