Esempio n. 1
0
def connect_lonely_people(player, board, distances, game_state):
    aims = []
    moves = []
    my_groups = []
    for tile in board:
        if board[tile]["player"] == player:
            g = group(tile, board)
            if g not in my_groups:
                my_groups.append(g)
    for my_group in my_groups:
        libs = liberties(my_group[0], board)
        for l in libs:
            for n in board[l]["neighbours"]:
                for mg in my_groups:
                    if n in mg:
                        if mg != my_group:
                            aims.append(l)
                    if n in liberties(mg[0], board):
                        if mg != my_group:
                            aims.append(l)
    for i in aims:
        if board[i]["player"] == None and is_suicidal(player, i,
                                                      board) == False:
            if is_ko == False or game_state["last_ko"] == False:
                good = False
                for n in board[i]["neighbours"]:
                    a = is_alive(n, board)
                    if a == False:
                        good = True
                if good == True:
                    moves.append(i)
    return moves
Esempio n. 2
0
def is_ko(player, move, board):
    #default response is false, and if the move isn't a valid position then return false.
    response = False
    if move not in board:
        return response

    #play in the position and find the neighbouring groups for that position.
    if move in board:
        board[move]["player"] = player
        g = group(move, board)
        n_g = neighbouring_groups(move, board)

        #takens stores the number of pieces that have been captured by the input move
        takens = 0

        #if the move is not part of a larger group (only solitary pieces can commit ko) then loop through neighbouring groups
        if len(g) == 1:
            for n in n_g:
                #if the neighbouring group is owned by the enemy then calculate it's liberties
                if board[n[0]]["player"] is not None:
                    t = n[0]
                    l = liberties(t, board)

                    #if the piece has no liberties left then it will be captured so add 1 to takens if the group consists of only one piece, or 5 (an arbitrary number) if the group is larger than 1
                    if len(l) == 0:
                        if len(n) == 1:
                            takens = takens + 1
                        elif len(n) > 1:
                            takens = takens + 5

        #if only one piece has been taken (the second condition for ko) then set response to true. Undo the move and return response
        if takens == 1:
            response = True
        board[move]["player"] = None
    return response
Esempio n. 3
0
def find_friends(board):
    groups = []
    friends = []
    #loop through the board, if the tile is not empty then add it's group to the list of groups, if not already in there
    for tile in board:
        if board[tile]["player"] is not None:
            g = group(tile, board)
            if g not in groups:
                groups.append(g)

    #loop through groups and find the player who own's them and a list of tiles that could be played to make the group "alive" if it isn't already
    for g in groups:
        player = board[g[0]]["player"]
        s = saviours(g[0], board)

        #if the group has only one saviour place then add that place to friends (if there are two or more then it is unnecessary to play in the spot because if attacked it can be saved by one of the other places)
        if len(s) == 1:
            friends.append(s[0])

        #or if there are no saviour tiles then loop through the liberties of the group
        elif len(s) == 0:
            for tile in liberties(g[0], board):
                #pretend to play in the position and look for saviours then undo the move
                board[tile]["player"] = player
                t = saviours(g[0], board)
                board[tile]["player"] = None
                #if there are now two or more saviours then add the original position to friends
                if len(t) >= 2:
                    friends.append(tile)
    return friends
Esempio n. 4
0
def ladder(tile, player, board, distances, game_state):
    v = False
    #if the tile is unowned...
    if board[tile]["player"] is None:
        enemies = []
        frees = 0
        #loop through the tile's neighbours, if the neighbour is unowned then add 1 to frees
        for n in board[tile]["neighbours"]:
            if board[n]["player"] is None:
                frees += 1
            #or if the neighbour is owned by the enemy then add the neighbour's position to the enemies lists
            elif board[n]["player"] != player:
                enemies.append(n)
        #if there is only 1 enemy then find the groups that neighbour on the enemy group
        if len(enemies) == 1:
            ng = neighbouring_groups(enemies[0], board)
            safe = True
            #loop through all the neighbouring groups, if the group is owned by the player and the group is in atari then the ladder is no longer safe
            for g in ng:
                if board[g[0]]["player"] == player:
                    if is_in_atari(g, board) == True:
                        safe = False
            #if the ladder is safe then calculate the liberties of the enemy group. If it only has 2 liberties and we have one less free than the number of neighbours that surround the original tile then return True
            if safe == True:
                libs = liberties(enemies[0], board)
                if len(libs) == 2:
                    if frees + 1 == len(board[tile]["neighbours"]):
                        v = True
    return v
Esempio n. 5
0
def is_in_atari(group, board):
    #calculate the liberties of the group, if it's equal to 1 then return true, otherwise return false
    l = liberties(group[0], board)
    q = len(l)
    if q == 1:
        return True
    else:
        return False
Esempio n. 6
0
def save_from_probable_death(tile, player, board, distances, game_state):
    v = False
    #if the tile is unoccupied then loop through all of it's neighbours
    if board[tile]["player"] == None:
        for n in board[tile]["neighbours"]:
            #if the neighbour is owned by me then calculate its liberties
            if board[n]["player"] == player:
                libs = liberties(n, board)
                #if there is only one liberty then pretend to play in the tile and calculate liberties again.
                if len(libs) == 1:
                    board[tile]["player"] = player
                    newlibs = liberties(n, board)
                    #undo the move and if there are now more than 2 liberties then it is a good move
                    board[tile]["player"] = None
                    if len(newlibs) > 2:
                        v = True
    return v
Esempio n. 7
0
def is_suicidal(player, move, board):
    #default response is false.
    response = False
    #play in the position and calculate its liberties
    board[move]["player"] = player
    l = liberties(move, board)

    #if it has no liberties then set the response to true
    if len(l) == 0:
        response = True

        #but loop through neighbouring groups
        n_g = neighbouring_groups(move, board)
        for g in n_g:
            g_l = liberties(g[0], board)
            #and if a group has 0 liberties then it would be captured so the move is legal and set response to true
            if len(g_l) == 0:
                response = False
    #undo the move
    board[move]["player"] = None
    return response
Esempio n. 8
0
def capture(tile, player, board, distances, game_state):
    v = False
    if board[tile]["player"] == None:
        x = is_eye_candidate(tile, board)
        if x is not None:
            if x["owner"] == player:
                return False
        for n in board[tile]["neighbours"]:
            if board[n]["player"] is not None and board[n]["player"] != player:
                l = liberties(n, board)
                if len(l) == 1:
                    v = True
    return v
Esempio n. 9
0
def saviours(tile, board):
    player = board[tile]["player"]
    saviours = []
    if player == None:
        return []
    else:
        first = is_alive(tile, board)
        if first == True:
            return []
        if first == False:
            libs = liberties(tile, board)
            for l in libs:
                board[l]["player"] = player
                second = is_alive(tile, board)
                board[l]["player"] = None
                if second == True:
                    saviours.append(l)
    return saviours
Esempio n. 10
0
def check_captures(t, board, capture_points):
    #find all neighbouring groups and the player who owns the input piece
    n_g = neighbouring_groups(t, board)
    player = board[t]["player"]

    #loop through all neighbouring groups and find their player.
    for h in n_g:
        j = h[0]
        p = board[j]["player"]

        #if the groups are owned by a player then they must be owned by the enemy player (as if they were owned by the same player then it would be part of the original group). Calculate liberties of enemy group
        if p is not None:
            l = liberties(j, board)
            q = len(l)

            #if the group has no liberties then loop through all of it's peices and remove them, adding capture points.
            if q == 0:
                for i in h:
                    board[i]["player"] = None
                    capture_points[player] = capture_points[player] + 1
    return board
Esempio n. 11
0
def save_from_certain_death(player, board, distances, game_state):
    moves = []
    my_groups = []
    for tile in board:
        if board[tile]["player"] == player:
            g = group(tile, board)
            if g not in my_groups:
                my_groups.append(g)
    for my_group in my_groups:
        if is_alive(my_group[0], board) == False:
            libs = liberties(my_group[0], board)
            for l in libs:
                board[l]["player"] = player
                if is_alive(my_group[0], board) == True:
                    moves.append(l)
                board[l]["player"] = None
                for n in board[l]["neighbours"]:
                    if board[n]["player"] == None:
                        board[n]["player"] = player
                        if is_alive(my_group[0], board) == True:
                            moves.append(n)
                        board[n]["player"] = None
    return moves
Esempio n. 12
0
def play(player,board):
    #this is a territorial player
    my_groups=[]
    enemy_groups=[]
    my_territory=[]
    enemy_territory=[]
    loosely_mine=[]
    loosely_enemy=[]
    neutral_space=[]
    allowed_moves=[]
    stupid_moves=[]
    fight_points=[]
    distances=distances_from_edge(board)
    #work out what's what
    for tile in board:
        if board[tile]["player"]==player:
            g=group(tile,board)
            if g not in my_groups:
                my_groups.append(g)
        elif board[tile]["player"] is None:
            if is_ko(player, tile, board)==False or game_state["last_ko"]==False:
                if is_suicidal(player, tile, board)==False:
                    allowed_moves.append(tile)
            sort_of_owner=loosely_territory(tile,board)
            if sort_of_owner==player:
                loosely_mine.append(tile)
            elif sort_of_owner=="Neutral":
                neutral_space.append(tile)
            elif sort_of_owner=="Nobody":
                fight_points.append(tile)
            else:
                loosely_enemy.append(tile)
            actual_owner=territory(tile,board)
            if actual_owner==player:
                my_territory.append(tile)
            elif actual_owner=="Neutral":
                pi=3.14
            else:
                enemy_territory.append(tile)
        else:
            h=group(tile,board)
            if h not in enemy_groups:
                enemy_groups.append(h)
    #forget about stuff inside other people's eyes
    for enemy_group in enemy_groups:
        rep=enemy_group[0]
        libs=liberties(rep,board)
        is_deaded=False
        eyeness=is_eye_candidate(libs[0],board)
        if eyeness==None:
            break
        else:
            if eyeness["owner"]==player:
                enemy_groups.remove(enemy_group)
            for l in eyeness["group"]:
                if l in allowed_moves:
                    stupid_moves.append(l)
                if l in fight_points:
                    fight_points.remove(l)
    for my_group in my_groups:
        rep=my_group[0]
        libs=liberties(rep,board)
        is_deaded=False
        eyeness=is_eye_candidate(libs[0],board)
        if eyeness==None:
            break
        else:
            if eyeness["owner"]!=player:
                my_groups.remove(my_group)
            for l in eyeness["group"]:
                if l in allowed_moves:
                    stupid_moves.append(l)
                if l in fight_points:
                    fight_points.remove(l)
    #1: if possible, make a non-alive group of mine be an alive group
    #2: make a nearly_alive group of the enemy's be a deaded group
    #3: seal off some loosely territory into proper territory (multiple seal points??)
    #4: claim some new loosely territory close-ish to the edge (row 3 or 4)
    #We do these in reverse order so that more important things overwrite the move variable
    move="pass"
    #So without further ado: Number 4:
    break_new_ground=[]
    for i in allowed_moves:
        if i in distances[2] or (i in distances[3] and i not in distances[5]):
            if i in neutral_space:
                break_new_ground.append(i)
    #Cool.  Now let's try Number 3, securing loose territory:
    fight_moves=[]
    for i in fight_points:
        if i in allowed_moves:
            fight_moves.append(i)
    #Before we do that, let's kill dangerous people, 2.5:
    saviours=[]
    for my_group in my_groups:
        a=is_in_atari(my_group,board)
        if a==True:
            n_g=neighbouring_groups(my_group[0],board)
            for nnn in n_g:
                b=is_in_atari(nnn,board)
                if b==True and nnn[0] in allowed_moves:
                    saviours.append(liberties(nnn[0],board)[0])
    feedback="I'm not doing anything"
    if len(fight_moves)>0:
        move=random.choice(fight_moves)
        feedback="I'm fighting"
    if len(break_new_ground)>0:
        move=random.choice(break_new_ground)
        feedback="I'm breaking new ground"
    if len(saviours)>0:
        move=random.choice(saviours)
        feedback="I'm saving people"
    #print(feedback)
    return move
Esempio n. 13
0
def play_game(player1, player2, graphics=True):
    #make a board and set all the default values
    board = make_a_board()
    game_state = {
        "in_progress": True,
        "last_pass": False,
        "last_ko": False,
        "capture points": {
            "Black": 0,
            "White": 0
        },
        "moves_made": 0,
        "history": []
    }

    x = "pass"
    y = "pass"

    #if drawing graphics then remove all the current screen drawings and redraw the screen in size 9x9
    if graphics == True:
        delete()
        setupDrawing(9)

    #while the game is still in progress...
    while game_state["in_progress"] == True:
        #take a move from player1, if it's pass then set last_pass to true and if the previous move was a pass as well then end the game
        x = player1("Black", board, game_state)
        if x == "pass":
            print("black passed")
            if game_state["last_pass"] == True:
                game_state["in_progress"] = False
                print("game over")
            game_state["last_pass"] = True

        #if x is not a move that exists on the board then pass instead
        elif x not in board:
            print("Black was really really stupid")
            game_state["last_pass"] = True

        #if x is already occupied then pass instead
        elif x in board and board[x]["player"] != None:
            print("Black was Stupid")
            game_state["last_pass"] = True

        #otherwise so long as the move is not pass and the tile is unowned then play there
        else:
            if x != "pass":
                game_state["last_pass"] = False
                if board[x]["player"] is None:
                    board[x]["player"] = "Black"

                    #check if any captures have happened, and check if the new board state is ko or not
                    board = check_captures(x, board,
                                           game_state["capture points"])
                    k = is_ko(board, game_state["history"])
                    #if the move is ko then return the board to it's previous state and set last_pass to true
                    if k == True:
                        board = unstring(board, game_state["history"][-1])
                        game_state["last_pass"] = True
                        print("Black attempted ko")
                    #calculate the liberties of the group containing the piece that was just played in
                    l = liberties(x, board)
                    q = len(l)
                    #if the piece has no liberties then undo the move and set last pass to true
                    if q == 0:
                        #print ("Black was suicidal")
                        board[x]["player"] = None
                        game_state["last_pass"] = True
        #add one to moves made (even pass counts as a move in this case) and add the hash of board state to history
        game_state["moves_made"] = game_state["moves_made"] + 1
        game_state["history"].append(stringy(board))

        #if graphics is true then draw the new board and then check if game is still in progress
        if graphics == True:
            update(board)
        if game_state["in_progress"] == True:
            #take a move from player1, if it's pass then set last_pass to true and if the previous move was a pass as well then end the game
            y = player2("White", board, game_state)
            if y == "pass":
                print("white passed")
                if game_state["last_pass"] == True:
                    game_state["in_progress"] = False
                    print("game over")
                game_state["last_pass"] = True

            #if y is not a move that exists on the board then pass instead
            elif y not in board:
                print("White was really really stupid")
                game_state["last_pass"] = True

            #if y is already occupied then pass instead
            elif y in board and board[y]["player"] != None:
                print("White was Stupid")
                game_state["last_pass"] = True

            #otherwise so long as the move is not pass and the tile is unowned then play there
            else:
                if y != "pass":
                    game_state["last_pass"] = False
                    if board[y]["player"] is None:
                        board[y]["player"] = "White"

                        #check if any captures have happened, and check if the new board state is ko or not
                        board = check_captures(y, board,
                                               game_state["capture points"])
                        k = is_ko(board, game_state["history"])
                        #if the move is ko then return the board to it's previous state and set last_pass to true
                        if k == True:
                            board = unstring(board, game_state["history"][-1])
                            game_state["last_pass"] = True
                            print("Black attempted ko")
                        #calculate the liberties of the group containing the piece that was just played in
                        l = liberties(y, board)
                        q = len(l)
                        #if the piece has no liberties then undo the move and set last pass to true
                        if q == 0:
                            #print ("Black was suicidal")
                            board[y]["player"] = None
                            game_state["last_pass"] = True
            #add one to moves made (even pass counts as a move in this case)
            game_state["moves_made"] = game_state["moves_made"] + 1
            game_state["history"].append(stringy(board))

            #if graphics is true then draw the new board and then check if game is still in progress
            if graphics == True:
                update(board)

    #at the end of the game score the board and then return this dictionary.
    points = score(board, game_state["capture points"], {
        "Black": 0,
        "White": 5.5
    })
    return points
Esempio n. 14
0
def play(player, board, game_state):

    #find how far each tile is from the end of the board
    distances = greatest_distance(board)

    #patterns is the list of functiosn (declared below) that return true or false when given a move, according to certain criteria. These are in priority order.
    patterns = [
        capture, save_from_probable_death, ladder, invade_large_empty_space,
        seal_off_territory, seal_the_edges, sneak
    ]

    #default move is pass, allowed moves stores all moves that aren't illegal and decisions is a dictionary mapping from pattern to movs that the patern wants to make
    move = "pass"
    allowed_moves = []
    decisions = {}

    #friends is a list of tiles that are essential to the life of a group. f is the list of friend moves
    friends = find_friends(board)
    f = []

    #loop through friends, if any of the moves are allowed then add them to f
    for i in friends:
        if is_allowed(i, board, player, game_state) == True:
            f.append(i)

    #if there are any moves in f, then pick a random f to return (because friends is the most important patern and is run across the entire board
    if len(f) > 0:
        return random.choice(f)

    #loop through the board, if the move is allowed (not occupied and not suicidal) and is not ko then pretend to play there
    for tile in board:
        if board[tile]["player"] == None and is_suicidal(player, tile,
                                                         board) == False:
            if check_ko(player, tile, board, game_state) == False:
                board[tile]["player"] = player

                #check whether the group is in atari after the move
                a = is_in_atari(group(tile, board), board)
                b = False
                #loop through the board and if the move makes any captures then set b = True
                for n in board[tile]["neighbours"]:
                    if board[n]["player"] is not None and board[n][
                            "player"] != player:
                        l = liberties(n, board)
                        if len(l) == 0:
                            b = True
                #if we are not putting ourselves in atari or we make captures despite this then add the tile to allowed moves
                if a == False or b == True:
                    allowed_moves.append(tile)
                #undo the hypothetical move
                board[tile]["player"] = None

    #loop through patterns, adding a new empty list for each pattern (these will store the moves that this pattern wants to make)
    for p in patterns:
        decisions[p] = []

    #loop through all allowed moves and all patterns.
    for tile in allowed_moves:
        for pat in patterns:
            #call the pattern's function on the tile and if the pattern wants to play there, add it to it's corresponding decisions list
            verdict = pat(tile, player, board, distances, game_state)
            if verdict == True:
                decisions[pat].append(tile)

    #loop through patterns again and if there are any moves for that pattern then choose a random one of them to return
    for i in patterns:
        if len(decisions[i]) > 0:
            move = random.choice(decisions[i])
            return move
    #this will return pass if none of the patterns decide on any moves
    return move