def __init__(self, playerObject, txNodeId, rxNodeId, coordinatorId, gameFreq, cost, gameType=3): """ Create a physical layer object and initialize internal parameters. Keyword arguments: coordinatorId -- Numerical cluster id. cost -- Energy cost. gateType -- Type of game played. """ self.playerObject = playerObject self.coordinatorId = coordinatorId self.gameFreq = gameFreq self.cost = cost self.gameType = gameType # configure tx and rx nodes self.txNode = GameNode(coordinatorId, txNodeId) self.rxNode = GameNode(coordinatorId, rxNodeId) # configure sense node. Just need to do this once. self.rxNode.setSenseConfiguration(gameFreq, gameFreq, 400e3) self.currentTxPower = random.choice(self.availableTxPowers) self.previousTxPower = self.currentTxPower self.bestResponseUntouched = self.currentTxPower # initialize sense and transmit objects self.transmitObject = PlayerTransmitLayer(self, self.gameFreq) self.senseObject = PlayerSenseLayer(self, self.gameType)
def main(player_key, output_path): ############################################################ load state with open(os.path.join(output_path, 'state.json'), 'r') as f: originalState = f.read().decode('utf-8-sig') ### LOAD STATE playerKey = player_key action = None firstGameNode = GameNode(json.loads(originalState)) #logger.info("FIRST NODE: " + firstGameNode.getStatePretty()) startPosition = firstGameNode.getMyPosition(playerKey) visitedBlocks = [] ############################################################ visited blocks # load visited blocks is round isnt 0 ###### TODO - fix this bug # if firstGameNode.state['CurrentRound'] == 1: #logger.info("Round ZERO, initialising visitedBlocks...") visitedBlocks.append(startPosition) with open("visited.blocks.pickle", "wb") as f: cPickle.dump(visitedBlocks, f) else: # Load visited if not round 0 try: with open("visited.blocks.pickle", "r") as f: visitedBlocks = cPickle.load(f) except Exception as error: print('oopsie in writing visited blocks :(') # Update visited blocks if startPosition not in visitedBlocks: visitedBlocks.append(startPosition) with open("visited.blocks.pickle", "wb") as f: cPickle.dump(visitedBlocks, f) #Todo: Testing """ visitedBlocks = [(2, 1), (1, 1) """ #logger.info("already visited: " + str(visitedBlocks)) firstGameNode.setVisitedBlocks(visitedBlocks) firstGameNode.setMyPlayerKey(playerKey) #graphTester(firstGameNode, playerKey) #print "DONEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" #sys.exit() firstGameNode.guessTarget() #print firstGameNode.guessedTarget cameFrom, costSoFar, foundKey, startKey = timedGameScoreSearch(firstGameNode, playerKey, timedSearchTimeout) #logger.info("found: " + str(foundKey)) nextNode = foundKey targetNode = None pathCount = 0 while nextNode != startKey: pathCount += 1 #logger.info("############################################# REVERSING") #logger.info(expandedNodes[nextNode].getStatePretty()) #logger.info("reversing: " + str(expandedNodes[nextNode].moveThatLedHere)) if cameFrom[nextNode] == startKey: targetNode = nextNode break nextNode = cameFrom[nextNode] action = moves[expandedNodes[targetNode].moveThatLedHere] ### Execute my plan executeStartTime = time.time() if action == None: #logger.info("WTF? Doing nothing") action = moves['DoNothing'] logger.info('Action: {}'.format(ACTIONS[action])) with open(os.path.join(output_path, 'move.txt'), 'w') as f: f.write('{}\n'.format(action)) finishedTime = time.time()
class PlayerPhysicalLayer: """ Control transmission and spectrum sensing for a player. """ # VESNA power generating list. This must be sorted. Powers are in dBm #minimum output power for cc2500 according to texas instruments in -30dBm availableTxPowers = [0, -2, -4, -6, -8, -10, -12, -14, -16, -18, -20, -22, -24, -26, -28, -30] # current transmitting power [dBm] currentTxPower = random.choice(availableTxPowers) # previous transmitted_power [dBm] previousTxPower = currentTxPower bestResponseUntouched = 0 # direct and cross gains directGain = 0 crossGain = 0 # used for sending data transmitObject = None # used for sensing the spectrum senseObject = None # game type - can be: 1, 2, 3 . Depends on the implementation you want to use gameType = 3 # neighborPowerEvent. When this is True, It means that neighbor player changed its power neighborPowerEvent = False # When this is triggered (=True) then it means that equilibrium has been reached and the threads stops here. equilibriumDetected = False def __init__(self, playerObject, txNodeId, rxNodeId, coordinatorId, gameFreq, cost, gameType=3): """ Create a physical layer object and initialize internal parameters. Keyword arguments: coordinatorId -- Numerical cluster id. cost -- Energy cost. gateType -- Type of game played. """ self.playerObject = playerObject self.coordinatorId = coordinatorId self.gameFreq = gameFreq self.cost = cost self.gameType = gameType # configure tx and rx nodes self.txNode = GameNode(coordinatorId, txNodeId) self.rxNode = GameNode(coordinatorId, rxNodeId) # configure sense node. Just need to do this once. self.rxNode.setSenseConfiguration(gameFreq, gameFreq, 400e3) self.currentTxPower = random.choice(self.availableTxPowers) self.previousTxPower = self.currentTxPower self.bestResponseUntouched = self.currentTxPower # initialize sense and transmit objects self.transmitObject = PlayerTransmitLayer(self, self.gameFreq) self.senseObject = PlayerSenseLayer(self, self.gameType) def isPrevTxDone(self): """Check if previous transmission has finished""" if self.transmitObject.isSendingData(): self.transmitObject.sleepUntilSignalGenerationStops() return def setCost(self,newCost): self.cost=newCost def setInitialBestResponseUntouched(self): """Set best response as current tx power, best response untouched in [W].""" self.bestResponseUntouched = self.currentTxPower def setDirectGain(self, hii): """Set player direct gain""" self.directGain = hii def getPracticalBestResponseForm1(self, txPowerDBm, rxPowerDBm): """ Compute best response strategy based current game state. Return best response power in dBm. Best response = 1/c_i + (I + n_0) / h_ii. I + n_0 = receivedPower - usefulReceivedPower Keyword arguments: txPowerDBm -- players' transmitting power. rxPowerDBm -- player received power. """ # convert powers in W txPowerWatts = 1e-3 * math.pow(10.00, float(txPowerDBm) / 10.00) rxPowerWatts = 1e-3 * math.pow(10.00, float(rxPowerDBm) / 10.00) usefulReceivedPowerWatts = txPowerWatts * self.directGain if txPowerDBm < -1000: # Player does not transmit useful data, consider only noise and interference bestResponse = (1.00 / float(self.cost)) - rxPowerWatts / float(self.directGain) else: bestResponse = (1.00 / float(self.cost)) - (rxPowerWatts - usefulReceivedPowerWatts) / float(self.directGain) # Transform in dBm try: return 10.00 * math.log10(bestResponse / 1e-3) except: print "Player %d: negative best response" % (self.playerObject.playerNumber) return None def getPracticalBestResponseForm2(self, rxPowerDBm): """ Compute best response strategy based current game state. Return best response power in dBm. This power is the best power in interference condition. This method use the practically formula which will be used in empirical games This formula is based on the received power dBm, which must be only noise and interference """ # convert received power in W rxPowerWatts = 1e-3 * math.pow(10.00, float(rxPowerDBm) / 10.00) bestResponse = (1.00 / float(self.cost)) - rxPowerWatts / float(self.directGain) # return in dBm try: return 10.00 * math.log10(bestResponse / 1e-3) except: print "Player %d: negative best response" % (self.playerObject.playerNumber) return None def computeBestResponseForm1(self, pj, hjiList): """ Compute practical best response based on current tx power a list containing opponents tx powers and a list containing cross gains h_ji for player i. Assume hjiList contains gains in [W]. Do not consider noise!!! Return best response in [W] Keyword arguments: pj -- list with player j tx power, in bBm hjiList -- list with cross gains in [W] for player i. """ # compute sum(h_ji*pJ) crossGainSum = 0 # must transform each elem of pj in [W] temp = [math.pow(10.00, float(x) / 10.00) * 1e-3 for x in pj] for index, elem in enumerate(temp): crossGainSum += elem * hjiList[index] bestResp = (1.00 / float(self.cost) - crossGainSum / float(self.directGain)) # return power in dBm try: # sometimes the difference is negative, in that case return none return 10.00 * math.log10(bestResp / 1.e-3) except: print "Player %d: negative best response" % (self.playerObject.playerNumber) return None def computeBestResponseForm2(self, receivedPower): """ Compute practical best response based on received power and direct gain. Return best response in [W] Keyword arguments: receivedPower -- Measured receiving power, i.e. sum(h_ji * p_j) + n_0 """ powerInW = math.pow(10.00, float(receivedPower)/10.00) * 1e-3 bestResp = (1.00 / float(self.cost) - powerInW/float(self.directGain)) # return power in dBm try: # sometimes the difference is negative, in that case return none return 10.00 * math.log10(bestResp / 1.e-3) except: print "Player %d: negative best response" % (self.playerObject.playerNumber) return None def computeBestResponseForm3(self, recP): """ Compute practical best response based on received power and direct gain. Return best response in [dBm] Keyword arguments: receivedPower -- Measured receiving power, i.e. sum(h_ji * p_j) + n_0 """ bestResp = (1.00 / float(self.cost) - recP/float(self.directGain)) # return power in dBm try: # sometimes the difference is negative, in that case return none return 10.00 * math.log10(bestResp / 1.e-3) except: print "Player %d: negative best response" % (self.playerObject.playerNumber) return None def getAvailTxPower(self, desiredPower): """From the available power list get a transmission power. Method will return the closest power from the available ones to the desired power. Keywords arguments: desiredPower -- Desired transmitting power. """ minDist = float("inf") rez = None for i in range(0, len(self.availableTxPowers)): if math.fabs(desiredPower - self.availableTxPowers[i]) < minDist: minDist = math.fabs(desiredPower - self.availableTxPowers[i]) rez = self.availableTxPowers[i] return rez def getCrtTxPower(self): """Get current transmission power""" return self.currentTxPower def getBestRespUntouched(self): """Return best response as real value, not discrete one""" return self.bestResponseUntouched def changeTxPowerRandomly(self): """Change current tx power randomly""" self.currentTxPower = random.choice(self.availableTxPowers) self.previousTxPower = self.currentTxPower self.bestResponseUntouched = self.currentTxPower def changeTxPower(self, newBestResponse): """ Change current tx power, save previous tx power Keyword arguments: newTxPower -- new transmitting power """ self.previousTxPower = self.currentTxPower self.bestResponseUntouched = newBestResponse self.currentTxPower = self.getAvailTxPower(newBestResponse)