Exemple #1
0
def checkForSensei():
    username = Sensei.username
    exists = yield Penguin.exists(where=['username = ?', username])

    if not exists:
        sensei = Penguin(username=username,
                         nickname="Sensei",
                         password='',
                         email='*****@*****.**',
                         coins=1000,
                         igloos='',
                         urnitures='',
                         floors='',
                         locations='',
                         care='',
                         stamps='',
                         cover='')

        yield sensei.save()
        yield sensei.refresh()

        SenseiNinja = Ninja(
            penguin_id=sensei.id,
            belt=10,
            cards=
            '427,99|749,99|591,99|724,99|90,99|259,99|574,99|736,99|257,99|580,99|83,99|97,99|748,99|76,99|252,99|355,99|590,99|593,99|734,99|260,99|739,99',
            matches='')
        yield SenseiNinja.save()

    logger.debug('Sensei has been born!')
class FindFourAI(IPlugin):
    """
	Adds an intelligent find four bot to the four lounge!
	Make sure you have dassets.swf active!
	"""

    requirements = [Requirement(**{'name': 'Commands', 'developer': 'Dote'})]
    name = 'FindFourAI'
    developer = 'Dote'

    AI_username = '******'  # username of bot in the database
    Bots = dict()  # engine => Bot

    AI = None
    Call_AI_Command = "Find4"

    def __init__(self):
        super(FindFourAI, self).__init__()

        self.logger = logging.getLogger(TIMELINE_LOGGER)
        self.Bots = {}

        self.AICreatedDefer = self.setupAI()
        self.setupCommands()
        self.logger.debug("FindFour AI Active!")
        self.logger.debug("Please ensure you have dassets.swf active!")

        GeneralEvent.on('onEngine', self.attachBotToServer)

    def Play4(self, client, params):
        if client['room'].ext_id is not 220:
            return

        engine = client.engine
        if engine not in self.Bots:
            return client.send('sm', client['id'],
                               "Sorry, bot is not available in this server!")

        AI = self.Bots[engine]['bot']
        if self.Bots[engine]['playing'] is not None:
            return client.send(
                'sm', AI['id'], "Sorry, am currently playing with {}".format(
                    self.Bots[engine]['playing']['nickname']))

        try:
            difficulty = int(params[0])
        except:
            difficulty = 2  # default

        if difficulty > self.Bots[engine]['difficulty'] or difficulty < 1:
            difficulty = self.Bots[engine]['difficulty']  # maximum

        client.send(
            'sm', AI['id'],
            "Let's play! Difficulty level set to {}".format(difficulty))
        sleep(3)

        client.send('sm', AI['id'], "Finding a board to play...")
        AvailableBoard = self.getFourBoard(engine)

        if AvailableBoard is None:
            return client.send('sm', AI['id'],
                               "Sorry, no boards are available to play! :(")

        self.Bots[engine]['playing'] = client
        AI.penguin.difficulty = difficulty

        GeneralEvent.on(
            'Table-Left-{}-{}'.format(client['id'], AvailableBoard.table),
            self.ClientLeft)

        client.send('zaf',
                    AvailableBoard.table)  # make sure you have dote's assets
        Event.call('JoinTable-{}'.format(AvailableBoard.table), AI,
                   AvailableBoard.table)

        AI['room'].send(
            'sm', AI['id'],
            "FindFour: {} V/S {}, difficulty: {}, started!".format(
                AI['nickname'], client['nickname'], difficulty))
        AI['game'].joinGame(AI)

    def makeNextTurn(self, AI):
        FourGame = AI['game']
        if FourGame is None:
            return

        FourBoard = list(FourGame.FourGame)

        nextMove = self.Bots[AI.engine]['algorithm'].calculateNextMove(
            FourBoard, AI['difficulty'])
        x, y = nextMove[0]

        AI.penguin.lastMoved = True
        FourGame.play(AI, [y, x])

    def manipulateSend(self, AI, *a):
        if len(a) < 2:
            return

        FourGame = AI['game']

        if a[0] == 'sz':
            self.makeNextTurn(AI)
        elif a[0] == 'zm':
            if FourGame.currentPlayer() is not AI:
                reactor.callLater(1, self.makeNextTurn, AI)

    def ClientLeft(self, client, FourGame):
        GeneralEvent.removeListener(
            'Table-Left-{}-{}'.format(client['id'], FourGame.table),
            self.ClientLeft)
        if client.engine not in self.Bots:
            return

        FourGame.remove(self.Bots[client.engine]['bot'])
        self.Bots[client.engine]['playing'] = None

        AI = self.Bots[client.engine]['bot']
        AI['room'].send(
            'sm', AI['id'],
            "I've completed my game with {}. Ready for next round!".format(
                client['nickname']))

    def getFourBoard(self, engine):
        FourLounge = self.Bots[engine]['Room']
        _id = FourLounge.ext_id

        RoomHandler = engine.roomHandler
        if not _id in RoomHandler.ROOM_CONFIG.FourGame:
            return None

        Tables = RoomHandler.ROOM_CONFIG.FourGame[_id]
        for table in Tables:
            table = RoomHandler.ROOM_CONFIG.FourGame[_id][table]
            if table.FourStarted == False and len(table.Waddling) == 0:
                return table

        return None

    @inlineCallbacks
    def attachBotToServer(self, engine, defer=None):
        if defer is not None:
            engine = defer

        if engine.type is not WORLD_SERVER:
            return

        if self.AI is None:
            self.AICreatedDefer.addCallback(self.attachBotToServer, engine)
            return

        AI = engine.protocol(engine)
        AI.dbpenguin = self.AI
        AI.penguin.id = self.AI.id
        # Nullify major methods
        AI.disconnect = AI.makeConnection = lambda *x, **y: None
        # might need this to identify next moves!
        AI.send = lambda *x: self.manipulateSend(AI, *x)
        AI.initialize()

        yield AI['RefreshHandler'].CacheInitializedDefer

        AI.penguin.x = 351
        AI.penguin.y = 269
        AI.penguin.frame = 24

        FourLounge = engine.roomHandler.getRoomByExtId(220)
        #                                                       increasing difficulty may increase time to process next move
        self.Bots[engine] = {
            'bot': AI,
            'algorithm': FindFourAlgorithm(),
            'difficulty': 3,
            'Room': FourLounge,
            'playing': None
        }  # Attach algo to each FindFour game object created suring gameplay
        FourLounge.append(AI)

        self.logger.debug('FindFour AI added to %s', engine)

    def setupCommands(self):
        CommandsPlugin = self.dependencies[0]

        if self.Call_AI_Command not in CommandsPlugin.__commands__:
            CommandsPlugin.__commands__.append(self.Call_AI_Command)

        GeneralEvent.on('command={}'.format(self.Call_AI_Command.lower()),
                        self.Play4)
        self.logger.debug("FindFour AI Call Command set. Command : %s",
                          self.Call_AI_Command)

    # Maybe make a comprehensive link between a bot plugin and this AI, to a specific room?
    @inlineCallbacks
    def setupAI(self):
        AIExists = yield Penguin.exists(['`Username` = ?', self.AI_username])

        if not AIExists:
            yield self.createAI()

        if self.AI is None:
            self.AI = yield Penguin.find(
                where=['Username = ?', self.AI_username], limit=1)

    @inlineCallbacks
    def createAI(self):
        self.AI = Penguin(username=self.AI_username,
                          nickname="FindFour AI",
                          password='',
                          email='*****@*****.**')
        yield self.AI.save()
        yield self.AI.refresh()  # update values from DB