Exemplo n.º 1
0
def randomRandom(board, player, opponent, **info):
    '''
        Purely random
    '''

    tileList = np.where(player.used == False)[0]
    used = np.zeros(21, dtype=bool)
    cnt = 0

    while cnt < tileList.size:
        t = np.random.choice(tileList)
        while used[t]:
            t = np.random.choice(tileList)
        direction = np.random.permutation(shape.tileMaxRotation[t])
        for d in direction:
            f = 0
            tile = Tiles(t, d, f)
            possiblePos = board.canDropPos(player, tile)
            if possiblePos[0].size != 0:
                i = np.random.choice(possiblePos[0].size)
                x, y = possiblePos[0][i], possiblePos[1][i]
                return [t, d, f, x, y]
            if shape.tileMaxFlip[t]:
                f = 1
                tile = Tiles(t, d, f)
                possiblePos = board.canDropPos(player, tile)
                if possiblePos[0].size != 0:
                    i = np.random.choice(possiblePos[0].size)
                    x, y = possiblePos[0][i], possiblePos[1][i]
                    return [t, d, f, x, y]
        used[t] = True
        cnt += 1
    return [-1, 0, 0, 0, 0]
Exemplo n.º 2
0
def randomGreedy(board, player, opponent, **info):
    '''
        Randomly choose one of the biggest tile 
        which can be dropped and drop it on a 
        random legal position.
    '''

    remain = []
    nowSize = 0
    for i in range(21):
        if not player.used[i]:
            if nowSize == shape.tileSizes[i]:
                remain[nowSize - 1].append(i)
            else:
                remain.append([])
                nowSize = nowSize + 1
                remain[nowSize - 1].append(i)
    for size in range(5, 0, -1):
        if size > len(remain):
            continue
        random.shuffle(remain[size - 1])
        for i in range(len(remain[size - 1])):
            t = remain[size - 1][i]
            direction = [i for i in range(shape.tileMaxRotation[t])]
            random.shuffle(direction)
            for k in direction:
                f = 0
                tile = Tiles(t, k, f)
                xlist, ylist = board.canDropPos(player, tile)
                if xlist.size != 0:
                    j = np.random.choice(xlist.size)
                    return [
                        t,  # type of tile
                        k,  # rotation
                        f,  # flip
                        xlist[j],  # x
                        ylist[j]  # y
                    ]
                if shape.tileMaxFlip[t]:
                    f = 1
                    tile = Tiles(t, k, f)
                    xlist, ylist = board.canDropPos(player, tile)
                    if xlist.size == 0:
                        continue
                    j = np.random.choice(xlist.size)
                    return [
                        t,  # type of tile
                        k,  # rotation
                        f,  # flip
                        xlist[j],  # x
                        ylist[j]  # y
                    ]
    return [-1, 0, 0, 0, 0]
Exemplo n.º 3
0
 def action(self, board, opponent, **info):
     if self.decisionMaker is None:
         raise ValueError("The player is human")
     if not isinstance(board, Board):
         raise TypeError
     if self.type != board.type or self.order >= board.playerNum:
         raise ValueError
     if 'setEvalWeight' in info:
         self.w1, self.w2 = info['setEvalWeight']
     ef = 0
     if 'setEvalFunc' in info:
         ef = info['setEvalFunc']
     tileType, rot, flp, x, y = self.decisionMaker(board, self, opponent, \
                                 setEvalWeight = [self.w1, self.w2], setEvalFunc = ef)
     if tileType != -1:
         tile = Tiles(tileType, rot, flp)
         board.dropTile(self, tile, x, y, False)
         self.used[tileType] = True
         self.score = self.score + tileSizes[tileType]
         return {
             "action": True,
             "tileType": tileType,
             "rotation": rot,
             "flip": flp,
             "x": x,
             "y": y
         }
     else:
         return {"action": False}
Exemplo n.º 4
0
 def action(self, board, opponent):
     if self.decisionMaker is None:
         raise ValueError("The player is human")
     if not isinstance(board, Board):
         raise TypeError
     if self.type != board.type or self.order >= board.playerNum:
         raise ValueError
     tileType, rot, flp, x, y = self.decisionMaker(board, self, opponent, setEvalWeight = [self.w1, self.w2])
     if tileType != -1:
         tile = Tiles(tileType, rot, flp)
         board.dropTile(self, tile, x, y)
         self.used[tileType] = True
         for coo in cornerSet[tileType][rot + flp * 4]:
             if board.isInBound(x + coo[0], y + coo[1]):
                 self.corners.update([(x + coo[0], y + coo[1])])
         self.score = self.score + self.tiles[tileType].size
         return {
             "action" : True,
             "tileType" : tileType,
             "rotation" : rot,
             "flip" : flp,
             "x" : x,
             "y" : y
         }
     else:
         return {
             "action" : False
         }
Exemplo n.º 5
0
def mctsEval(board, player, opponent, **info):
    score = 0
    rev = False
    tot = 6
    stp = 4
    if 'setTot' in info:
        tot = info['setTot']
    if 'setReverse' in info:
        rev = info['setReverse']
    if 'setStep' in info:
        stp = info['setStep']

    tmpDecMaker = [player.decisionMaker, opponent.decisionMaker]
    player.decisionMaker = opponent.decisionMaker = randomRandom
    tmpPlayer = player
    tmpOpponent = opponent
    if rev:
        tmpPlayer = opponent
        tmpOpponent = player
    initScore = greedyEval(board, tmpPlayer, tmpOpponent)

    for game in range(tot):
        tmpHistory = []
        flag = False
        for step in range(stp):
            flag = False
            result = tmpPlayer.action(board, tmpOpponent, setEvalFunc=0)
            if result['action']:
                flag = True
                result['id'] = 0
                tmpHistory.append(result)
            result = tmpOpponent.action(board, tmpPlayer, setEvalFunc=0)
            if result['action']:
                flag = True
                result['id'] = 1
                tmpHistory.append(result)
            if not flag:
                break
        if flag:
            if greedyEval(board, tmpPlayer, tmpOpponent) > initScore:
                score += 1
        else:
            if tmpPlayer.score > tmpOpponent.score:
                score += 1
        for h in tmpHistory:
            if h['id'] == 0:
                tmpPlayer.used[h['tileType']] = False
                tmpPlayer.score -= shape.tileSizes[h['tileType']]
            else:
                tmpOpponent.used[h['tileType']] = False
                tmpOpponent.score -= shape.tileSizes[h['tileType']]
            board.retraceDrop(Tiles(h['tileType'], h['rotation'], h['flip']),
                              h['x'], h['y'])

    player.decisionMaker, opponent.decisionMaker = tmpDecMaker
    return score / tot if not rev else 1 - score / tot
Exemplo n.º 6
0
def greedy(board, player, opponent, evalFunc=0, **info):
    '''
        Enumerate all possible drops, and get a score
        using EvalFunc[evalFunc]
    '''

    if 'setEvalFunc' in info:
        evalFunc = info['setEvalFunc']

    global evalWeight
    if 'setEvalWeight' in info:
        evalWeight = info['setEvalWeight']

    maxScore = -32768
    maxDecision = []
    remain = np.where(player.used == False)[0]
    if remain.size == 0:
        return [-1, 0, 0, 0, 0]
    remain = remain[::-1]
    for i in remain:
        for p in range(shape.tileMaxRotation[i]):
            f = [0]
            if shape.tileMaxFlip[i]:
                f.append(1)
            for q in f:
                tile = Tiles(i, p, q)
                xlist, ylist = board.canDropPos(player, tile)
                if xlist.size == 0:
                    continue
                for k in range(xlist.size):
                    x = xlist[k]
                    y = ylist[k]
                    result = board.dropTile(player, tile, x, y, False)
                    if result:
                        player.score += tile.size
                        player.used[tile.type] = True
                        score = EvalFunc[evalFunc](board,
                                                   player,
                                                   opponent,
                                                   setReverse=True)
                        if score > maxScore:
                            maxScore = score
                            maxDecision = [
                                i,  # type of tile
                                p,  # rotation
                                q,  # flip
                                x,  # x
                                y  # y
                            ]
                        board.retraceDrop(tile, x, y)
                        player.used[tile.type] = False
                        player.score -= tile.size
    if maxScore > -32768:
        return maxDecision
    else:
        return [-1, 0, 0, 0, 0]
Exemplo n.º 7
0
 def test_corner(self):
     fout = open("testCorner.out", "w+")
     tiles = []
     for i in range(21):
         tiles.append(Tiles(i))
     for i in range(21):
         fout.write("type %d\n" % i)
         for r in range(4):
             self.__printTileAll(tiles[i], fout)
             tiles[i].rightRotate()
         tiles[i].horFlip()
         for r in range(4):
             self.__printTileAll(tiles[i], fout)
             tiles[i].rightRotate()
         fout.write("\n")
Exemplo n.º 8
0
def _alphaBeta(depth, board, player, opponent, evalFunc, alpha, beta,
               desPlayer):
    '''
        Internal recursive alphabeta pruning
    '''

    if depth == minimaxDepth:
        return EvalFunc[evalFunc](board, player, opponent)
    bestMove = [-1, 0, 0, 0, 0]
    remain = np.where(player.used == False)[0]
    remain = remain[::-1]
    #reverse the array to search in a specific order

    for i in remain:
        for p in range(shape.tileMaxRotation[i]):
            f = [0]
            if shape.tileMaxFlip[i]:
                f.append(1)
            for q in f:
                tile = Tiles(i, p, q)
                xlist, ylist = board.canDropPos(player, tile)
                if xlist.size == 0:
                    continue
                for k in range(xlist.size):
                    x = xlist[k]
                    y = ylist[k]
                    result = board.dropTile(player, tile, x, y, False)
                    if result:
                        player.score += tile.size

                        score = -_alphaBeta(depth + 1, board, opponent, player,
                                            evalFunc, -beta, -alpha, desPlayer)

                        board.retraceDrop(tile, x, y)
                        player.score -= tile.size
                        if score >= alpha:
                            alpha = score
                            if depth == 0:
                                bestMove = [i, p, q, x, y]
                                if alpha >= beta:
                                    return [alpha, bestMove]
                            else:
                                if alpha >= beta:
                                    return alpha
    return alpha if depth != 0 else [alpha, bestMove]
Exemplo n.º 9
0
 def test_rotate(self):
     fout = open("testRotate.out", "w+")
     tiles = []
     for i in range(21):
         tiles.append(Tiles(i))
     for i in range(21):
         fout.write("type %d\n" % i)
         for r in range(4):
             tiles[i].print(fout)
             fout.write("\n")
             tiles[i].rightRotate()
         tiles[i].horFlip()
         for r in range(4):
             tiles[i].print(fout)
             fout.write("\n")
             tiles[i].rightRotate()
         fout.write("\n")
     fout.close()
Exemplo n.º 10
0
 def __init__(self, type = -1, order = 0, level = 0, **info):
     if type == -1:
         pass
     else:
         self.type = type
         self.order = order
         if type is 0:
             self.tiles = [Tiles(i) for i in range(21)]
             self.used = [False for i in range(21)]
             self.score = 0
             if order == 0:
                 self.corners = set([(4, 4)])
             else:
                 self.corners = set([(9, 9)])
             self.tmpSet = []
             if level == -1:
                 self.decisionMaker = None
             else:
                 self.decisionMaker = DecisionFunc[level]
             self.w1, self.w2 = [20, 10]
             if 'setWeight' in info:
                 self.w1, self.w2 = info['setWeight']
Exemplo n.º 11
0
    else:
        matrix = [[0 for i in range(14)] for j in range(14)]
        player = Player(0, 0, lv)
        opponent = Player(0, 1, 0)

    if playerOrder == 0:
        board.parseFromMatrix(matrix, [player, opponent])
    else:
        board.parseFromMatrix(matrix, [opponent, player])

    result = player.action(board,
                           opponent,
                           setEvalWeight=evalWeight,
                           setEvalFunc=evalFunc)

    if result['action']:
        output['status'] = "Success"
        output['is_pass'] = False
        output['action'] = []
        tile = Tiles(result['tileType'], result['rotation'], result['flip'])
        x = result['x']
        y = result['y']
        for (i, j) in tile.shape:
            output['action'].append({"row": int(x + i), "col": int(y + j)})
        print(json.dumps(output))
    else:
        output['status'] = "Success"
        output['is_pass'] = True
        output['action'] = []
        print(json.dumps(output))
Exemplo n.º 12
0
# test for Board.canDropPos
from board import Tiles, Board
from player import Player
import numpy as np

board = Board()
player = Player(0, 0, -1)

board.board[3][3] = 1
board.board[4][4] = 1
tile = Tiles(17, 0, 0)

ret = board.canDropPos(player, tile)
print(ret)

print(board.getCorners(player)[0].size)
Exemplo n.º 13
0
def analBoard(board, player, opponent, **info):
    '''
        return the best 5 drops and their winning rate
    '''

    maxDecision = []
    remain = np.where(player.used == False)[0]

    for i in remain:
        for p in range(shape.tileMaxRotation[i]):
            f = [0]
            if shape.tileMaxFlip[i]:
                f.append(1)
            for q in f:
                tile = Tiles(i, p, q)
                xlist, ylist = board.canDropPos(player, tile)
                if xlist.size == 0:
                    continue
                for k in range(xlist.size):
                    x = xlist[k]
                    y = ylist[k]
                    board.dropTile(player, tile, x, y, False)
                    player.score += tile.size
                    player.used[tile.type] = True
                    score = greedyEval(board,
                                       player,
                                       opponent,
                                       setEvalWeight=[20, 10])
                    if len(maxDecision) < 5:
                        maxDecision.append({
                            'score': score,
                            'tileType': i,  # type of tile
                            'rot': p,  # rotation
                            'flip': q,  # flip
                            'x': x,  # x
                            'y': y  # y
                        })
                    elif score > maxDecision[-1]['score']:
                        m = 4
                        while m > 0:
                            if maxDecision[m]['score'] > score:
                                break
                            maxDecision[m] = maxDecision[m - 1]
                            m -= 1
                        maxDecision[m] = {
                            'score': score,
                            'tileType': i,  # type of tile
                            'rot': p,  # rotation
                            'flip': q,  # flip
                            'x': x,  # x
                            'y': y  # y
                        }
                    board.retraceDrop(tile, x, y)
                    player.used[tile.type] = False
                    player.score -= tile.size

    for i, dec in enumerate(maxDecision):
        tile = Tiles(dec['tileType'], dec['rot'], dec['flip'])
        board.dropTile(player, tile, dec['x'], dec['y'], False)
        player.used[dec['tileType']] = True
        winningRate = mctsEval(board,
                               player,
                               opponent,
                               setTot=61,
                               setReverse=True)
        maxDecision[i]['winningRate'] = int(winningRate * 1000)
        board.retraceDrop(tile, dec['x'], dec['y'])
        player.used[dec['tileType']] = False
    return maxDecision
Exemplo n.º 14
0
def mcts(board, player, opponent, evalFunc=0, **info):
    '''
        Enumerate all possible drops and select the best
        5 of them, then use mcstEval to reevaluate them
    '''

    if 'setEvalFunc' in info:
        evalFunc = info['setEvalFunc']

    global evalWeight
    if 'setEvalWeight' in info:
        evalWeight = info['setEvalWeight']

    totGame = 80
    if 'setTotalGame' in info:
        totGame = info['setTotalGame']

    maxDecision = []
    remain = np.where(player.used == False)[0]

    for i in remain:
        for p in range(shape.tileMaxRotation[i]):
            f = [0]
            if shape.tileMaxFlip[i]:
                f.append(1)
            for q in f:
                tile = Tiles(i, p, q)
                xlist, ylist = board.canDropPos(player, tile)
                if xlist.size == 0:
                    continue
                for k in range(xlist.size):
                    x = xlist[k]
                    y = ylist[k]
                    board.dropTile(player, tile, x, y, False)
                    player.score += tile.size
                    player.used[tile.type] = True
                    score = EvalFunc[evalFunc](board,
                                               player,
                                               opponent,
                                               setReverse=True)
                    if len(maxDecision) < 5:
                        maxDecision.append({
                            'score': score,
                            'tileType': i,  # type of tile
                            'rot': p,  # rotation
                            'flip': q,  # flip
                            'x': x,  # x
                            'y': y  # y
                        })
                    elif score > maxDecision[-1]['score']:
                        m = 4
                        while m > 0:
                            if maxDecision[m]['score'] > score:
                                break
                            maxDecision[m] = maxDecision[m - 1]
                            m -= 1
                        maxDecision[m] = {
                            'score': score,
                            'tileType': i,  # type of tile
                            'rot': p,  # rotation
                            'flip': q,  # flip
                            'x': x,  # x
                            'y': y  # y
                        }
                    board.retraceDrop(tile, x, y)
                    player.used[tile.type] = False
                    player.score -= tile.size
    if maxDecision != []:
        maxscore = -1
        maxd = -1
        for i, dec in enumerate(maxDecision):
            tile = Tiles(dec['tileType'], dec['rot'], dec['flip'])
            board.dropTile(player, tile, dec['x'], dec['y'], False)
            player.used[dec['tileType']] = True
            score = mctsEval(board,
                             player,
                             opponent,
                             setTot=totGame,
                             setReverse=True)
            if score > maxscore:
                maxd = i
            board.retraceDrop(tile, dec['x'], dec['y'])
            player.used[dec['tileType']] = False
        return [
            maxDecision[maxd]['tileType'], maxDecision[maxd]['rot'],
            maxDecision[maxd]['flip'], maxDecision[maxd]['x'],
            maxDecision[maxd]['y']
        ]
    else:
        return [-1, 0, 0, 0, 0]
Exemplo n.º 15
0
    p_id = int(args.player_id)
    player = Player(0, p_id, 0)
    opponent = Player(0, p_id ^ 1, 0)

    matrix = json.loads(args.state)
    if p_id == 0:
        board.parseFromMatrix(matrix, [player, opponent])
    else:
        board.parseFromMatrix(matrix, [opponent, player])

    result = analBoard(board, player, opponent)

    def wr(pack):
        return pack['winningRate']

    result.sort(key=wr, reverse=True)

    output = []
    for r in result:
        tile = Tiles(r['tileType'], r['rot'], r['flip'])
        x = r['x']
        y = r['y']
        action = []
        for i, j in tile.shape:
            action.append({"row": int(x + i), "col": int(y + j)})
        output.append({
            "action": action,
            "winning_rate": r['winningRate'] / 10
        })
    print(json.dumps(output))