コード例 #1
0
ファイル: robot.py プロジェクト: miloszw/BombAI
        def look_n_predict(presumptive=False):            
            ret = ''
            bots_in_sight = False
            mock_bombs = bombs[:]
            
            _line_of_sight = line_of_sight(self.me.loc, board)
            for bot in (bot for bot in alive_players if bot.id != game.PLAYER_ID):
                if bot.loc in _line_of_sight:
                    bots_in_sight = True
                    log("Bot %s in line of sight @ %s"%(bot.id,bot.loc))
                                        
                    # assume bot will place bomb
                    bomb_count = len([bomb for bomb in bombs if (bomb.player_id == bot.id and bomb.tick > 1)])
                    for _ in range(5-bomb_count):
                        b = game.Bomb(bot.id, bot.loc.x, bot.loc.y, DEFAULT_TICKS)
                        b.ghost = True
                        mock_bombs.append(b)

            if bots_in_sight:
                _backup = get_current_round()
                mock_state = (board, alive_players, mock_bombs, previous_actions)
                game.CURRENT_ROUND = game.Round(mock_state, 1337)
                best_move = get_best_move(self.me.loc, mock_state)
                log("** If bots place bombs -> best move: %s"%best_move)
                ret = best_move
                game.CURRENT_ROUND = _backup
            
            return (bots_in_sight, ret)
コード例 #2
0
ファイル: robot.py プロジェクト: mwielondek/BombAI
        def look_n_predict(presumptive=False):
            ret = ''
            bots_in_sight = False
            mock_bombs = bombs[:]

            _line_of_sight = line_of_sight(self.me.loc, board)
            for bot in (bot for bot in alive_players
                        if bot.id != game.PLAYER_ID):
                if bot.loc in _line_of_sight:
                    bots_in_sight = True
                    log("Bot %s in line of sight @ %s" % (bot.id, bot.loc))

                    # assume bot will place bomb
                    bomb_count = len([
                        bomb for bomb in bombs
                        if (bomb.player_id == bot.id and bomb.tick > 1)
                    ])
                    for _ in range(5 - bomb_count):
                        b = game.Bomb(bot.id, bot.loc.x, bot.loc.y,
                                      DEFAULT_TICKS)
                        b.ghost = True
                        mock_bombs.append(b)

            if bots_in_sight:
                _backup = get_current_round()
                mock_state = (board, alive_players, mock_bombs,
                              previous_actions)
                game.CURRENT_ROUND = game.Round(mock_state, 1337)
                best_move = get_best_move(self.me.loc, mock_state)
                log("** If bots place bombs -> best move: %s" % best_move)
                ret = best_move
                game.CURRENT_ROUND = _backup

            return (bots_in_sight, ret)
コード例 #3
0
ファイル: robot.py プロジェクト: miloszw/BombAI
 def play_round(self, state):
     (board, alive_players, bombs, previous_actions) = state
     self.me = get_me()
     # current_round = get_current_round()
     
     if not self.me.is_alive():
         log("Fatal Error: Dead :( ... fatal, haha, get it?")
         return "break"
         
     log("My position: %s"%self.me.loc)
     
     # get possible commands
     possible_commands = get_possible_moves(self.me.loc, board, bombs)
     log("Possible commands: %s"%possible_commands)
     
     ret = ''
     # Rule 1: defend your ass
     ret = self.defend(state, possible_commands)
     
     # Rule 2: if no need to defend, attack!
     if not ret:
         log("Attack mode activated. Prepare to die bitchez.")
         ret = self.attack(state, possible_commands)
     elif ret == "pass":
         log("Tried returning \"pass\". Why not see if we can attack meanwhile?")
         ret = self.attack(state, possible_commands)
     return ret if ret else "pass"
コード例 #4
0
ファイル: robot.py プロジェクト: mwielondek/BombAI
    def play_round(self, state):
        (board, alive_players, bombs, previous_actions) = state
        self.me = get_me()
        # current_round = get_current_round()

        if not self.me.is_alive():
            log("Fatal Error: Dead :( ... fatal, haha, get it?")
            return "break"

        log("My position: %s" % self.me.loc)

        # get possible commands
        possible_commands = get_possible_moves(self.me.loc, board, bombs)
        log("Possible commands: %s" % possible_commands)

        ret = ''
        # Rule 1: defend your ass
        ret = self.defend(state, possible_commands)

        # Rule 2: if no need to defend, attack!
        if not ret:
            log("Attack mode activated. Prepare to die bitchez.")
            ret = self.attack(state, possible_commands)
        elif ret == "pass":
            log("Tried returning \"pass\". Why not see if we can attack meanwhile?"
                )
            ret = self.attack(state, possible_commands)
        return ret if ret else "pass"
コード例 #5
0
ファイル: robot.py プロジェクト: miloszw/BombAI
 def passive_defence():
     # check if trapped
     if not loc_is_safe(self.me.loc, 1, False, True):
         log("Threat level low, but I seem trapped!")
         pc = possible_commands[:]
         pc.remove("pass")
         return move(pc, False)
     
     # check if other bot in direct line of sight
     # and predict best move if bot places bomb
     lnp = look_n_predict()
     if lnp and lnp[1]: return lnp[1]
         
     return
コード例 #6
0
ファイル: robot.py プロジェクト: mwielondek/BombAI
        def passive_defence():
            # check if trapped
            if not loc_is_safe(self.me.loc, 1, False, True):
                log("Threat level low, but I seem trapped!")
                pc = possible_commands[:]
                pc.remove("pass")
                return move(pc, False)

            # check if other bot in direct line of sight
            # and predict best move if bot places bomb
            lnp = look_n_predict()
            if lnp and lnp[1]: return lnp[1]

            return
コード例 #7
0
ファイル: robot.py プロジェクト: mwielondek/BombAI
    def attack(self, state, possible_commands, force=False):
        # do no checks, just do it!
        if force:
            return BOMB_MIN_TICK

        (board, alive_players, bombs, previous_actions) = state
        if not (len(get_bombs_for_player(self.my_id, bombs)) <
                BOMB_MAX_PER_PLAYER):
            log("Cannot place more bombs.. :( Fuucking buullshit!")
            return

        # Check if other bots around
        for bot in (bot for bot in alive_players if bot.id != game.PLAYER_ID):
            l = abs(self.me.loc - bot)
            d = l.x + l.y
            if d > ATTACK_DISTANCE:
                log("Other bots too far away to be wasting bombs..")
                try:
                    prev_action = get_prev_action_for_player(
                        self.my_id, previous_actions).action
                    possible_commands.remove(
                        (DIRECTIONS[-(RDIRECTIONS[prev_action])]))
                except:
                    pass
                ret = possible_commands.pop()
                if ret == "pass": ret = possible_commands.pop()
                return ret

        # Now place bomb, but first check if not kamikaze move
        mock_bombs = bombs[:]
        mock_state = (board, alive_players, mock_bombs, previous_actions)
        # pushing clock 1 tick ahead
        for bomb in mock_bombs:
            bomb.tick -= 1
        _backup = get_current_round()
        for bomb_tick in range(BOMB_MIN_TICK + 5, BOMB_MAX_TICK + 1, 10):
            mock_bombs.append(
                game.Bomb(self.my_id, self.me.loc.x, self.me.loc.y, bomb_tick))
            game.CURRENT_ROUND = game.Round(mock_state, 1337)
            best_move = get_best_move(self.me.loc, mock_state)
            log("** If I'd place a bomb -> best move: %s" % best_move)

            if best_move:
                log("Placing bomb with %s ticks" % bomb_tick)
                return bomb_tick

        game.CURRENT_ROUND = _backup
        log("Can't place bomb without killing myself.")
        return
コード例 #8
0
ファイル: robot.py プロジェクト: miloszw/BombAI
 def attack(self, state, possible_commands, force=False):
     # do no checks, just do it!
     if force:
         return BOMB_MIN_TICK
     
     (board, alive_players, bombs, previous_actions) = state
     if not (len(get_bombs_for_player(self.my_id, bombs)) < BOMB_MAX_PER_PLAYER):
         log("Cannot place more bombs.. :( Fuucking buullshit!")
         return
     
     # Check if other bots around
     for bot in (bot for bot in alive_players if bot.id != game.PLAYER_ID):
         l = abs(self.me.loc - bot)
         d = l.x + l.y
         if d > ATTACK_DISTANCE:
             log("Other bots too far away to be wasting bombs..")
             try:
                 prev_action = get_prev_action_for_player(self.my_id, previous_actions).action
                 possible_commands.remove((DIRECTIONS[-(RDIRECTIONS[prev_action])]))
             except:
                 pass
             ret = possible_commands.pop()
             if ret == "pass": ret = possible_commands.pop()
             return ret
     
     # Now place bomb, but first check if not kamikaze move
     mock_bombs = bombs[:]
     mock_state = (board, alive_players, mock_bombs, previous_actions)
     # pushing clock 1 tick ahead
     for bomb in mock_bombs:
         bomb.tick -= 1
     _backup = get_current_round()
     for bomb_tick in range(BOMB_MIN_TICK+5, BOMB_MAX_TICK+1, 10):
         mock_bombs.append(game.Bomb(self.my_id, self.me.loc.x, self.me.loc.y, bomb_tick))
         game.CURRENT_ROUND = game.Round(mock_state, 1337)
         best_move = get_best_move(self.me.loc, mock_state)
         log("** If I'd place a bomb -> best move: %s"%best_move)
     
         if best_move:
             log("Placing bomb with %s ticks"%bomb_tick)
             return bomb_tick
     
     game.CURRENT_ROUND = _backup
     log("Can't place bomb without killing myself.")
     return
コード例 #9
0
def get_best_move(loc, state, ticks=DEFAULT_TICKS, allow_pass=True):
    # reset shortest
    global shortest
    for b00l in [True, False]:
        shortest = RECURSION_LIMIT
        safelist = get_safe_move(loc, state, ticks=ticks, traps=b00l, allow_pass=allow_pass)
        if safelist: break

    if not safelist:
        return None
        
    best_moves = safelist[0]
    for moves in safelist[1:]:
        if len(moves) < len(best_moves):
            best_moves = moves       
    log("Best move strategy (%s ticks): %s"%(ticks,best_moves))
    if not b00l: log("It's a trap! ... but what else am I gonna do")
    # safelist is mutable, clear it!
    del safelist[:]
    return best_moves[0] if best_moves else None
コード例 #10
0
ファイル: robot.py プロジェクト: miloszw/BombAI
 def move(possible_commands=possible_commands, allow_pass=True):
     for move in possible_commands:
         if loc_is_safe(self.me.loc + RDIRECTIONS[move], traps=False):
             return move
 
     # if no single move guarantees safety, look for closest safe spot
     best_move = get_best_move(self.me.loc, state, allow_pass=allow_pass)
     log("Calculated best move (%s ticks): %s"%(DEFAULT_TICKS, best_move))
     if best_move:
         return best_move
 
     # check for closest safe spot but for less turns ahead
     for i in reversed(range(1,6)):
         best_move = get_best_move(self.me.loc, state, i)
         log("Calculated best move (%s ticks): %s"%(i, best_move))
         if best_move:
             return best_move
 
     # else PANIC! Haha, jk. No but seriously, auto-destruct.
     log("No safe moves! Self-destruct sequence initiated...")
     return self.attack(0, 0, force=True)
コード例 #11
0
 def wrapper(*args, **kwargs):
     ret = func(*args, **kwargs)
     me = get_me()
     state = args[1]
     bombs = state[2]
     if me.is_alive():
         if not check(ret, me, bombs):
             log("Wanted to return \""+str(ret)+"\" - blocked by I.S.A.S.")
             io.PREFIX = "* "
             # try to find best move for 3,2,1 turns ahead
             for i in reversed(range(1,4)):
                 best_move = get_best_move(me.loc, args[1], ticks=i)
                 # bombs = args[1][2]
                 # log("Bombs ISAS %s"%bombs)
                 # for bomb in bombs:
                 #     log("Ticks %s"%bomb.tick)
                 if check(best_move, me, bombs):
                     log("Alternative best move (%s ticks): %s"%(i, best_move))
                     io.PREFIX = ""
                     return best_move
             log("No other option - prepare to die...")
             io.PREFIX = ""
     return ret
コード例 #12
0
ファイル: robot.py プロジェクト: mwielondek/BombAI
        def move(possible_commands=possible_commands, allow_pass=True):
            for move in possible_commands:
                if loc_is_safe(self.me.loc + RDIRECTIONS[move], traps=False):
                    return move

            # if no single move guarantees safety, look for closest safe spot
            best_move = get_best_move(self.me.loc,
                                      state,
                                      allow_pass=allow_pass)
            log("Calculated best move (%s ticks): %s" %
                (DEFAULT_TICKS, best_move))
            if best_move:
                return best_move

            # check for closest safe spot but for less turns ahead
            for i in reversed(range(1, 6)):
                best_move = get_best_move(self.me.loc, state, i)
                log("Calculated best move (%s ticks): %s" % (i, best_move))
                if best_move:
                    return best_move

            # else PANIC! Haha, jk. No but seriously, auto-destruct.
            log("No safe moves! Self-destruct sequence initiated...")
            return self.attack(0, 0, force=True)
コード例 #13
0
ファイル: robot.py プロジェクト: miloszw/BombAI
    def defend(self, state, possible_commands):
        (board, alive_players, bombs, previous_actions) = state
        bots_in_sight = False
        
        def look_n_predict(presumptive=False):            
            ret = ''
            bots_in_sight = False
            mock_bombs = bombs[:]
            
            _line_of_sight = line_of_sight(self.me.loc, board)
            for bot in (bot for bot in alive_players if bot.id != game.PLAYER_ID):
                if bot.loc in _line_of_sight:
                    bots_in_sight = True
                    log("Bot %s in line of sight @ %s"%(bot.id,bot.loc))
                                        
                    # assume bot will place bomb
                    bomb_count = len([bomb for bomb in bombs if (bomb.player_id == bot.id and bomb.tick > 1)])
                    for _ in range(5-bomb_count):
                        b = game.Bomb(bot.id, bot.loc.x, bot.loc.y, DEFAULT_TICKS)
                        b.ghost = True
                        mock_bombs.append(b)

            if bots_in_sight:
                _backup = get_current_round()
                mock_state = (board, alive_players, mock_bombs, previous_actions)
                game.CURRENT_ROUND = game.Round(mock_state, 1337)
                best_move = get_best_move(self.me.loc, mock_state)
                log("** If bots place bombs -> best move: %s"%best_move)
                ret = best_move
                game.CURRENT_ROUND = _backup
            
            return (bots_in_sight, ret)
        
        def move(possible_commands=possible_commands, allow_pass=True):
            for move in possible_commands:
                if loc_is_safe(self.me.loc + RDIRECTIONS[move], traps=False):
                    return move
        
            # if no single move guarantees safety, look for closest safe spot
            best_move = get_best_move(self.me.loc, state, allow_pass=allow_pass)
            log("Calculated best move (%s ticks): %s"%(DEFAULT_TICKS, best_move))
            if best_move:
                return best_move
        
            # check for closest safe spot but for less turns ahead
            for i in reversed(range(1,6)):
                best_move = get_best_move(self.me.loc, state, i)
                log("Calculated best move (%s ticks): %s"%(i, best_move))
                if best_move:
                    return best_move
        
            # else PANIC! Haha, jk. No but seriously, auto-destruct.
            log("No safe moves! Self-destruct sequence initiated...")
            return self.attack(0, 0, force=True)
        
        def passive_defence():
            # check if trapped
            if not loc_is_safe(self.me.loc, 1, False, True):
                log("Threat level low, but I seem trapped!")
                pc = possible_commands[:]
                pc.remove("pass")
                return move(pc, False)
            
            # check if other bot in direct line of sight
            # and predict best move if bot places bomb
            lnp = look_n_predict()
            if lnp and lnp[1]: return lnp[1]
                
            return
                
        if not bombs:
            log("No bombs. No stress.")
            return passive_defence()
        
        bombs.sort(key=lambda bomb: bomb.x)
        log("Bombs at %s"%bombs)
        # log("Blast paths for next turn %s"%current_round.get_blast_paths(1))

        if loc_is_safe(self.me.loc):
            log("Not in blast path, chillax.")
            return passive_defence()
        
        # else (is in blastpath) move
        log("In blast path, run Forrest!")
        return move()
        
        return "pass"
コード例 #14
0
ファイル: robot.py プロジェクト: mwielondek/BombAI
    def defend(self, state, possible_commands):
        (board, alive_players, bombs, previous_actions) = state
        bots_in_sight = False

        def look_n_predict(presumptive=False):
            ret = ''
            bots_in_sight = False
            mock_bombs = bombs[:]

            _line_of_sight = line_of_sight(self.me.loc, board)
            for bot in (bot for bot in alive_players
                        if bot.id != game.PLAYER_ID):
                if bot.loc in _line_of_sight:
                    bots_in_sight = True
                    log("Bot %s in line of sight @ %s" % (bot.id, bot.loc))

                    # assume bot will place bomb
                    bomb_count = len([
                        bomb for bomb in bombs
                        if (bomb.player_id == bot.id and bomb.tick > 1)
                    ])
                    for _ in range(5 - bomb_count):
                        b = game.Bomb(bot.id, bot.loc.x, bot.loc.y,
                                      DEFAULT_TICKS)
                        b.ghost = True
                        mock_bombs.append(b)

            if bots_in_sight:
                _backup = get_current_round()
                mock_state = (board, alive_players, mock_bombs,
                              previous_actions)
                game.CURRENT_ROUND = game.Round(mock_state, 1337)
                best_move = get_best_move(self.me.loc, mock_state)
                log("** If bots place bombs -> best move: %s" % best_move)
                ret = best_move
                game.CURRENT_ROUND = _backup

            return (bots_in_sight, ret)

        def move(possible_commands=possible_commands, allow_pass=True):
            for move in possible_commands:
                if loc_is_safe(self.me.loc + RDIRECTIONS[move], traps=False):
                    return move

            # if no single move guarantees safety, look for closest safe spot
            best_move = get_best_move(self.me.loc,
                                      state,
                                      allow_pass=allow_pass)
            log("Calculated best move (%s ticks): %s" %
                (DEFAULT_TICKS, best_move))
            if best_move:
                return best_move

            # check for closest safe spot but for less turns ahead
            for i in reversed(range(1, 6)):
                best_move = get_best_move(self.me.loc, state, i)
                log("Calculated best move (%s ticks): %s" % (i, best_move))
                if best_move:
                    return best_move

            # else PANIC! Haha, jk. No but seriously, auto-destruct.
            log("No safe moves! Self-destruct sequence initiated...")
            return self.attack(0, 0, force=True)

        def passive_defence():
            # check if trapped
            if not loc_is_safe(self.me.loc, 1, False, True):
                log("Threat level low, but I seem trapped!")
                pc = possible_commands[:]
                pc.remove("pass")
                return move(pc, False)

            # check if other bot in direct line of sight
            # and predict best move if bot places bomb
            lnp = look_n_predict()
            if lnp and lnp[1]: return lnp[1]

            return

        if not bombs:
            log("No bombs. No stress.")
            return passive_defence()

        bombs.sort(key=lambda bomb: bomb.x)
        log("Bombs at %s" % bombs)
        # log("Blast paths for next turn %s"%current_round.get_blast_paths(1))

        if loc_is_safe(self.me.loc):
            log("Not in blast path, chillax.")
            return passive_defence()

        # else (is in blastpath) move
        log("In blast path, run Forrest!")
        return move()

        return "pass"
コード例 #15
0
def preprocess(X,
               GDM,
               normalise=1000,
               replicatesIDs=None,
               flipSamples=None,
               expressionValueThreshold=10.0,
               replacementVal=0.0,
               atleastinconditions=1,
               atleastindatasets=1,
               absvalue=False,
               usereplacementval=False,
               filteringtype='raw',
               filterflat=True,
               params=None,
               datafiles=None):
    # Fixing parameters
    Xloc = ds.listofarrays2arrayofarrays(X)
    L = len(Xloc)
    if datafiles is None:
        if L == 1:
            datafiles = ['X']
        else:
            datafiles = np.array([], dtype=str)
            for i in range(L):
                datafiles = np.append(datafiles, 'X{0}'.format(i + 1))
    if params is None:
        params = {}
    if replicatesIDs is None:
        replicatesIDsloc = [
            np.array([ii for ii in range(x.shape[1])]) for x in Xloc
        ]
    else:
        replicatesIDsloc = ds.listofarrays2arrayofarrays(replicatesIDs)
        replicatesIDsloc = [np.array(x) for x in replicatesIDsloc]
    if flipSamples is None:
        flipSamplesloc = None
    else:
        flipSamplesloc = ds.listofarrays2arrayofarrays(flipSamples)
        flipSamplesloc = [np.array(x) for x in flipSamplesloc]
    # Revise if the if statement below is accurate!
    if not isinstance(normalise, (list, tuple, np.ndarray)):
        normaliseloc = [
            normalise if isinstance(normalise, (list, tuple,
                                                np.ndarray)) else [normalise]
            for i in range(L)
        ]
        normaliseloc = ds.listofarrays2arrayofarrays(normaliseloc)
    else:
        normaliseloc = [
            nor if isinstance(nor, (list, tuple, np.ndarray)) else [nor]
            for nor in normalise
        ]
        normaliseloc = ds.listofarrays2arrayofarrays(normaliseloc)

    # Get rid of nans by fixing
    Xproc = Xloc
    for l in range(L):
        Xproc[l] = fixnans(Xproc[l])

    # Prepare applied_norm dictionary before any normalisation takes place
    applied_norm = collec.OrderedDict(zip(datafiles, deepcopy(normaliseloc)))

    # Tell the user if any automatic normalisation is taking place
    allare1000 = True
    anyis1000 = False
    for l in range(L):
        if 1000 in normaliseloc[l]:
            anyis1000 = True
        else:
            allare1000 = False
    if allare1000:
        io.log(' - Automatic normalisation mode (default in v1.7.0+).')
        io.log('   Clust automatically normalises your dataset(s).')
        io.log('   To switch it off, use the `-n 0` option (not recommended).')
        io.log('   Check https://github.com/BaselAbujamous/clust for details.')
    elif anyis1000:
        io.log(
            ' - Some datasets are not assigned normalisation codes in the provided'
        )
        io.log(
            '   normalisation file. Clust automatically identifies and applies the'
        )
        io.log('   most suitable normalisation to them (default in v1.7.0+).')
        io.log('   If you don'
               't want clust to normalise them, assign each of them a')
        io.log('   normalisation code of 0 in the normalisation file.')
        io.log('   Check https://github.com/BaselAbujamous/clust for details.')

    # Quantile normalisation
    for l in range(L):
        if 101 in normaliseloc[l] or 1000 in normaliseloc[l]:
            Xproc[l] = normaliseSampleFeatureMat(Xproc[l], 101)[0]
            if 101 in normaliseloc[l]:
                i = np.argwhere(np.array(normaliseloc[l]) == 101)
                i = i[0][0]
                normaliseloc[l][i] = 0

    # Combine replicates and sort out flipped samples
    Xproc = combineReplicates(Xproc, replicatesIDsloc, flipSamplesloc)

    # Filter genes not exceeding the threshold
    (Xproc, GDMnew,
     Iincluded) = filterlowgenes(Xproc, GDM, expressionValueThreshold,
                                 replacementVal, atleastinconditions,
                                 atleastindatasets, absvalue,
                                 usereplacementval, filteringtype)

    # Normalise
    for l in range(L):
        (Xproc[l], codes) = normaliseSampleFeatureMat(Xproc[l],
                                                      normaliseloc[l])
        if np.all(codes == normaliseloc[l]):
            applied_norm[datafiles[l]] = op.arraytostring(
                applied_norm[datafiles[l]],
                delim=' ',
                openbrac='',
                closebrac='')
        else:
            applied_norm[datafiles[l]] = op.arraytostring(codes,
                                                          delim=' ',
                                                          openbrac='',
                                                          closebrac='')

    if filterflat:
        io.log(
            ' - Flat expression profiles filtered out (default in v1.7.0+).')
        io.log(
            '   To switch it off, use the --no-fil-flat option (not recommended).'
        )
        io.log('   Check https://github.com/BaselAbujamous/clust for details.')
        (Xproc, GDMnew, Iincluded) = filterFlat(Xproc, GDMnew, Iincluded)

    # Prepare params for the output
    params = dict(
        params, **{
            'normalise': normaliseloc,
            'replicatesIDs': replicatesIDs,
            'flipSamples': flipSamplesloc,
            'L': L
        })

    return Xproc, GDMnew, Iincluded, params, applied_norm
コード例 #16
0
def uncles(X,
           type='A',
           Ks=[n for n in range(2, 21)],
           params=None,
           methods=None,
           methodsDetailed=None,
           U=None,
           Utype='PM',
           relabel_technique='minmin',
           setsP=None,
           setsN=None,
           dofuzzystretch=False,
           wsets=None,
           wmethods=None,
           GDM=None,
           smallestClusterSize=11,
           CoPaMfinetrials=1,
           CoPaMfinaltrials=1,
           binarise_techniqueP='DTB',
           binarise_paramP=np.arange(0.0, 1.1, 0.1, dtype='float'),
           binarise_techniqueN='DTB',
           binarise_paramN=np.concatenate(([sys.float_info.epsilon],
                                           np.arange(0.1,
                                                     1.1,
                                                     0.1,
                                                     dtype='float'))),
           Xnames=None,
           deterministic=False,
           ncores=1):
    Xloc = ds.listofarrays2arrayofarrays(X)
    L = len(Xloc)  # Number of datasets

    # Fix parameters
    if params is None: params = {}
    if setsP is None: setsP = [x for x in range(int(math.floor(L / 2)))]
    if setsN is None: setsN = [x for x in range(int(math.floor(L / 2)), L)]
    setsPN = np.array(np.concatenate((setsP, setsN), axis=0), dtype=int)
    Xloc = Xloc[setsPN]
    L = np.shape(Xloc)[0]  # Number of datasets
    if wsets is None:
        wsets = np.array([1 for x in range(L)])
    else:
        wsets = np.array(wsets)[setsPN]
    if GDM is None:
        Ng = np.shape(Xloc[0])[0]
        GDMloc = np.ones([Ng, L], dtype='bool')
    else:
        GDMloc = GDM[:, setsPN]
        Ng = GDMloc.shape[0]
    if Xnames is None:
        Xnames = ['X{0}'.format(l) for l in range(L)]

    if methods is None:
        largest_DS = np.max([x.shape[0] for x in Xloc])
        if (largest_DS <= maxgenesinsetforpdist):
            if (deterministic):
                methods = [['k-means'], ['HC']]
            else:
                methods = [['k-means'], ['SOMs'], ['HC']]
        else:
            if (deterministic):
                methods = [['k-means']]
            else:
                methods = [['k-means'], ['SOMs']]
    else:
        largest_DS = np.max([x.shape[0] for x in Xloc])
        if (largest_DS > maxgenesinsetforpdist):
            methods = [
                m for m in methods
                if 'hc' not in [entry.lower() for entry in m]
            ]
            if not methods:
                io.log('No valid base clustering can be used. Please note that clust would not use HC clustering ' \
                       'on datasets with more than {0} genes. You have a dataset with {1} genes.' \
                       ''.format(maxgenesinsetforpdist, largest_DS))
                io.log('Clust will terminate here.')
                io.log(op.bottomline(), addextrastick=False)
                sys.exit()
    if methodsDetailed is None:
        methodsDetailedloc = np.array([methods for l in range(L)])
    else:
        methodsDetailedloc = methodsDetailed[setsPN]
    if wmethods is None:
        wmethods = [[1 for x in m] for m in methodsDetailedloc]
    elif not isinstance(wmethods[0], (list, tuple, np.ndarray)):
        wmethods = np.tile(methods, [L, 1])
    else:
        wmethods = np.array(wmethods)[setsPN]

    setsPloc = [ii for ii in range(len(setsP))]
    if L > len(setsPloc):
        setsNloc = [ii for ii in range(len(setsPloc), L)]

    Ds = [nu.closest_to_square_factors(k)
          for k in Ks]  # Grid sizes for the SOMs method for each value of K
    NKs = len(Ks)  # Number of K values

    # Clustering
    if U is None:
        Utype = 'PM'
        Uloc = np.array([None] * (L * NKs)).reshape([L, NKs])
        totalparallel = np.sum(Ks) * np.sum(
            [len(meths) for meths in methodsDetailedloc])
        for meths in methodsDetailedloc:
            for meth in meths:
                if 'k-means' in meth:
                    totalparallel += np.max(Ks) * np.max(Ks)
                    continue
        io.resetparallelprogress(totalparallel)

        for l in range(L):
            # Cache kmeans initialisations for the dataset once to save time:
            cl.cache_kmeans_init(Xloc[l],
                                 Ks,
                                 methodsDetailedloc[l],
                                 datasetID=l)

            # Now go to parallel clustering
            with warnings.catch_warnings():
                warnings.simplefilter("ignore")
                Utmp = Parallel(n_jobs=ncores)\
                    (delayed(clustDataset)
                     (Xloc[l], Ks[ki], Ds[ki], methodsDetailedloc[l], GDMloc[:, l], Ng, l) for ki in range(NKs))

                Utmp = [u for u in Utmp]
                for ki in range(NKs):
                    Uloc[l, ki] = Utmp[ki]

                gc.collect()
                #io.updateparallelprogress(np.sum(Ks) * len(methodsDetailedloc))

    else:
        Uloc = ds.listofarrays2arrayofarrays(U)[setsPN]

    # Calculate a CoPaM for each dataset at each K
    CoPaMsFine = np.array([None] * (L * NKs)).reshape([L, NKs])
    for l in range(L):
        for ki in range(NKs):
            if Utype.lower() == 'pm':
                CoPaMsFineTmp = [
                    generateCoPaM(Uloc[l, ki],
                                  relabel_technique=relabel_technique,
                                  X=[Xloc[l]],
                                  w=wmethods[l],
                                  K=Ks[ki],
                                  GDM=GDMloc[:, l].reshape([-1, 1]))
                    for i in range(CoPaMfinetrials)
                ]
            elif Utype.lower() == 'idx':
                CoPaMsFineTmp = \
                    [generateCoPaMfromidx(Uloc[l, ki], relabel_technique=relabel_technique, X=Xloc,
                                          w=wmethods[l], K=Ks[ki])
                     for i in range(CoPaMfinetrials)]
            else:
                raise ValueError('Invalid Utype')
            CoPaMsFine[l,
                       ki] = generateCoPaM(CoPaMsFineTmp,
                                           relabel_technique=relabel_technique,
                                           X=[Xloc[l]],
                                           GDM=GDMloc[:, l].reshape([-1, 1]))

            if dofuzzystretch:
                CoPaMsFine[l, ki] = fuzzystretch(CoPaMsFine[l, ki])

    # Calculate the final CoPaM for each K
    CoPaMs = np.array([None] * (CoPaMfinaltrials * NKs)).reshape(
        [CoPaMfinaltrials, NKs])
    CoPaMsP = np.array([None] * (CoPaMfinaltrials * NKs)).reshape(
        [CoPaMfinaltrials, NKs])
    CoPaMsN = np.array([None] * (CoPaMfinaltrials * NKs)).reshape(
        [CoPaMfinaltrials, NKs])
    for t in range(CoPaMfinaltrials):
        for ki in range(NKs):
            if type == 'A':
                if Utype.lower() == 'pm':
                    CoPaMs[t, ki] = generateCoPaM(
                        CoPaMsFine[:, ki],
                        relabel_technique=relabel_technique,
                        w=wsets,
                        X=Xloc,
                        GDM=GDMloc)
                elif Utype.lower() == 'idx':
                    CoPaMs[t, ki] = generateCoPaMfromidx(
                        CoPaMsFine[:, ki],
                        relabel_technique=relabel_technique,
                        X=Xloc,
                        w=wsets,
                        GDM=GDMloc)
                else:
                    raise ValueError('Invalid Utype')
            elif type == 'B':
                if Utype.lower() == 'pm':
                    CoPaMsP[t, ki] = generateCoPaM(
                        CoPaMsFine[setsPloc, ki],
                        relabel_technique=relabel_technique,
                        X=Xloc,
                        w=wsets[setsPloc],
                        GDM=GDMloc[:, setsPloc])
                    CoPaMsN[t, ki] = generateCoPaM(
                        CoPaMsFine[setsNloc, ki],
                        relabel_technique=relabel_technique,
                        X=Xloc,
                        w=wsets[setsNloc],
                        GDM=GDMloc[:, setsNloc])
                elif Utype.lower() == 'idx':
                    CoPaMsP[t, ki] = generateCoPaMfromidx(
                        CoPaMsFine[setsPloc, ki],
                        relabel_technique=relabel_technique,
                        X=Xloc,
                        w=wsets[setsPloc],
                        GDM=GDMloc[:, setsPloc])
                    CoPaMsN[t, ki] = generateCoPaMfromidx(
                        CoPaMsFine[setsNloc, ki],
                        relabel_technique=relabel_technique,
                        X=Xloc,
                        w=wsets[setsNloc],
                        GDM=GDMloc[:, setsNloc])
                else:
                    raise ValueError('Invalid Utype')
            else:
                raise ValueError(
                    'Invalid UNCLES type. It has to be either A or B')

    # Binarise
    NPp = len(binarise_paramP)  # Number of P params
    NNp = len(binarise_paramN)  # Number of N params
    if type == 'A':
        B = np.zeros([CoPaMfinaltrials, NPp, 1, NKs], dtype=object)
        Mc = np.zeros([CoPaMfinaltrials, NKs], dtype=object)
    elif type == 'B':
        B = np.zeros([CoPaMfinaltrials, NPp, NNp, NKs], dtype=object)
        Mc = np.zeros([CoPaMfinaltrials, NKs], dtype=object)

    for t in range(CoPaMfinaltrials):
        for ki in range(NKs):
            if type == 'A':
                # Pre-sorting binarisation
                for p in range(NPp):
                    B[t, p, 0, ki] = binarise(CoPaMs[t,
                                                     ki], binarise_techniqueP,
                                              binarise_paramP[p])
                Mc[t, ki] = [np.sum(Bp, axis=0) for Bp in B[t, :, 0, ki]]

                # Sorting
                CoPaMs[t, ki] = sortclusters(CoPaMs[t, ki], Mc[t, ki],
                                             smallestClusterSize)

                # Post-sorting binarisation
                for p in range(NPp):
                    B[t, p, 0, ki] = binarise(CoPaMs[t,
                                                     ki], binarise_techniqueP,
                                              binarise_paramP[p])
                Mc[t, ki] = [np.sum(Bp, axis=0) for Bp in B[t, :, 0, ki]]
            elif type == 'B':
                # Pre-sorting binarisation
                BP = [
                    binarise(CoPaMsP[t, ki], binarise_techniqueP,
                             binarise_paramP[p]) for p in range(NPp)
                ]
                McP = [np.sum(BPp, axis=0) for BPp in BP]

                BN = [
                    binarise(CoPaMsN[t, ki], binarise_techniqueN,
                             binarise_paramN[p]) for p in range(NNp)
                ]
                McN = [np.sum(BNp, axis=0) for BNp in BN]

                # Sorting
                CoPaMsP[t, ki] = sortclusters(CoPaMsP[t, ki], McP,
                                              smallestClusterSize)
                CoPaMsN[t, ki] = sortclusters(CoPaMsN[t, ki], McN,
                                              smallestClusterSize)

                # Post-sorting binarisation
                BP = [
                    binarise(CoPaMsP[t, ki], binarise_techniqueP,
                             binarise_paramP[p]) for p in range(NPp)
                ]
                McP = [np.sum(BPp, axis=0) for BPp in BP]

                BN = [
                    binarise(CoPaMsN[t, ki], binarise_techniqueN,
                             binarise_paramN[p]) for p in range(NNp)
                ]
                McN = [np.sum(BNp, axis=0) for BNp in BN]

                # UNCLES B logic
                for pp in range(NPp):
                    for pn in range(NNp):
                        B[t, pp, pn, ki] = BP[pp]
                        B[t, pp, pn, ki][np.any(BN[pn], axis=1)] = False

                # Fill Mc
                Mc[t, ki] = [None] * Ks[ki]
                for k in range(Ks[ki]):
                    Mc[t, ki][k] = np.zeros([NPp, NNp])
                    for pp in range(NPp):
                        for pn in range(NNp):
                            Mc[t, ki][k][pp, pn] = np.sum(B[t, pp, pn, ki][:,
                                                                           k])

    # Prepare and return the results:
    params = dict(
        params, **{
            'methods': methods,
            'setsP': setsPloc,
            'setsN': setsNloc,
            'dofuzzystretch': dofuzzystretch,
            'type': type,
            'Ks': Ks,
            'NKs': NKs,
            'wsets': wsets,
            'wmethods': wmethods,
            'Ds': Ds,
            'L': L,
            'CoPaMs': CoPaMs,
            'smallestclustersize': smallestClusterSize,
            'GDM': GDMloc
        })

    UnclesRes = collections.namedtuple('UnclesRes',
                                       ['B', 'Mc', 'params', 'X', 'U'])
    return UnclesRes(B, Mc, params, Xloc, Uloc)