예제 #1
0
def player_vs_uct():

    player1 = Player(1)
    player2 = Player(2, 'ai')

    #player1.punkte = 3

    d = {player1: player2, player2: player1}

    #zum probieren
    #spiel = Spiel(create_kartenliste(determinized_short_karteninfoliste, False), player1, player2)

    spiel = Spiel(create_kartenliste(speed_test_karteninfoliste, False),
                  player1, player2)
    #spiel = Spiel(create_kartenliste(test_karteninfolist, False), player1, player2)      #['OSSW', 'WWSS', 'OSSW', 'WWSWK']

    #select startspieler
    current_player = player2  #random.choice((player1, player2))
    print('Der Startspieler ist Player{}'.format(current_player.nummer))

    mcts = MCTS((player1, player2), spiel.play_random1v1,
                spiel.calculate_possible_actions)
    mcts.root = Node(True, None, current_player.nummer)

    game_is_running = True
    while game_is_running:

        print(
            '\n\nNEUER ZUG: Aktuell hat player1 {} Punkte und player2 {} Punkte.\n'
            .format(player1.punkte, player2.punkte))

        display_spielbrett_dict(spiel.cards_set)
        current_card = spiel.cards_left[0]

        print('Die nachste Karte ist [{0}, {1}, {2}, {3}, {4}, {5}]'.format(
            current_card.info[0], current_card.info[1], current_card.info[2],
            current_card.info[3], current_card.mitte, current_card.schild))
        draw_card(current_card)
        print('Sie enthält folgende moegliche Meeplepositionen:')
        print('Orte:')
        for o in current_card.orte:
            print(o.name, o.kanten)
        print('Strassen:')
        for s in current_card.strassen:
            print(s.name, s.kanten)
        print('Wiesen:')
        for w in current_card.wiesen:
            print(w.name, w.ecken)

        pos = spiel.calculate_possible_actions(current_card, current_player)

        # wenn es moegliche anlegestellenn (fuer den aktuellen Spieler) gibt, (es gibt fuer einen spieler auf jeden Fall
        # eine Anlegemoeglichkeit, wenn es fuer den anderen auch eine gibt)
        if pos:
            if current_player.art == 'human':

                #gib move ein
                inp = input('Bitte gib deine Aktion an:')
                inp_split = inp.split(' ')

                ungueltig = True
                action = None
                try:
                    if inp_split[3][0] == 'o':
                        o = [
                            a for a in current_card.orte
                            if a.name == int(inp_split[3][1])
                        ]
                        action = (int(inp_split[0]), int(inp_split[1]),
                                  int(inp_split[2]), o[0])
                    elif inp_split[3][0] == 's':
                        s = [
                            a for a in current_card.strassen
                            if a.name == int(inp_split[3][1])
                        ]
                        action = (int(inp_split[0]), int(inp_split[1]),
                                  int(inp_split[2]), s[0])
                    elif inp_split[3][0] == 'w':
                        w = [
                            a for a in current_card.wiesen
                            if a.name == int(inp_split[3][1])
                        ]
                        action = (int(inp_split[0]), int(inp_split[1]),
                                  int(inp_split[2]), w[0])
                    elif inp_split[3][0] == 'k':
                        action = (int(inp_split[0]), int(inp_split[1]),
                                  int(inp_split[2]), 'k')
                    else:
                        action = (int(inp_split[0]), int(inp_split[1]),
                                  int(inp_split[2]), None)
                except IndexError or ValueError:
                    print('ERROR CATCHED')

                # falls move unguelig:
                if action in pos:
                    ungueltig = False
                while ungueltig:
                    print("illegaler Move")
                    inp = input('Bitte gib deine Aktion an:')
                    inp_split = inp.split(' ')
                    try:
                        if inp_split[3][0] == 'o':
                            o = [
                                a for a in current_card.orte
                                if a.name == int(inp_split[3][1])
                            ]
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), o[0])
                        elif inp_split[3][0] == 's':
                            s = [
                                a for a in current_card.strassen
                                if a.name == int(inp_split[3][1])
                            ]
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), s[0])
                        elif inp_split[3][0] == 'w':
                            w = [
                                a for a in current_card.wiesen
                                if a.name == int(inp_split[3][1])
                            ]
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), w[0])
                        elif inp_split[3][0] == 'k':
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), 'k')
                        else:
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), None)
                    except IndexError or ValueError:
                        pass
                    if action in pos:
                        ungueltig = False

                spiel.make_action(current_player, current_card, action[0],
                                  action[1], action[2], action[3])

                # gespielte action formulieren
                if action[3]:
                    lak_id = inp_split[3][0]
                    lak_name = 1 if inp_split[3][0] == 'k' else action[3].name
                else:
                    lak_id = None
                    lak_name = None

                node_action = (action[0], action[1], action[2], lak_id,
                               lak_name)

                # root anpassen

                # falls die aktuelle root_node bereits Kinder hat
                if mcts.root.children:
                    for child in mcts.root.children:

                        # wenn die action von der child-node der gespielten entspricht
                        if child.action == node_action:  ###
                            mcts.root = child
                            break

                # another player made the first move of the game, or the node has no visits yet
                else:
                    p_num = 1 if current_player.nummer == 2 else 2
                    mcts.root = Node(True, node_action, p_num, mcts.root)

            # AI-PLayer
            else:
                #mcts.root = mcts.find_next_move(spiel)

                # erstelle Liste mit den root_nodes_kopien fuer welche die Trees aufgebaut wurden
                t_start = time.time()
                root_copies = [deepcopy(mcts.root) for i in range(4)]

                # multiprocessing
                pool = multiprocessing.Pool()
                roots = pool.starmap(calculate_tree,
                                     zip(root_copies, repeat(spiel, 4)))

                pool.close()
                pool.join()
                # ermittle die neue child-Node
                mcts.root = get_best_child(roots)

                t_ende = time.time()

                print(
                    f'Es wurden {t_ende - t_start} Sekunden gebraucht, um die naechste Node auszurechnen.'
                )

                # l_a_K auf die gespielt werden soll
                if mcts.root.action[3] is None:
                    landschaft = None
                elif mcts.root.action[3] == 'k':
                    landschaft = 'k'
                else:
                    l_dict = {
                        'o': current_card.orte,
                        's': current_card.strassen,
                        'w': current_card.wiesen
                    }
                    landschaft = [
                        l for l in l_dict[mcts.root.action[3]]
                        if l.name == mcts.root.action[4]
                    ][0]

                spiel.make_action(
                    current_player, current_card, mcts.root.action[0],
                    mcts.root.action[1], mcts.root.action[2],
                    landschaft)  #######################################

                # falls die AI-Aktion einen Meeple auf eine Landschaft (ausser Kloster) setzt
                if mcts.root.action[3] is not None:
                    print("\nDie AI setzt einen Meeple auf {}{}.".format(
                        mcts.root.action[3], mcts.root.action[4]))
                elif mcts.root.action[3] == 'k':
                    print("\nDie AI setzt einem Meeple auf das Kloster.")
                else:
                    print("\nDie AI setzt keinen Meeple.")

                print(
                    "Die AI setzt die Karte an ({}, {}) und rotiert sie {} mal"
                    .format(mcts.root.action[0], mcts.root.action[1],
                            mcts.root.action[2]))

            # Vorbereitung fuer naechsten Zug
            # gesetzte Karte loeschen
            del spiel.cards_left[0]

            if len(spiel.cards_left) == 0:
                game_is_running = False

            # spieler wechseln
            current_player = d[current_player]

        # wenn es fuer die gezogene Karte keine Anlegestelle gibt
        else:
            print("ES GIBT FUER DIESE KARTE KEINE ANLEGESTELLE")

            # gesetzte Karte loeschen
            del spiel.cards_left[0]

            if len(spiel.cards_left) == 0:
                game_is_running = False

    spiel.final_evaluate()
    print("\nSpielende: Player1 hat {} Punkte, Player2 hat {} Punkte.".format(
        player1.punkte, player2.punkte))
예제 #2
0
파일: UCB.py 프로젝트: T3K14/Carcassonne
def player_vs_ucb(kartenliste=None):

    player1 = Player(1)
    player2 = Player(2, 'ai')

    #player1.meeples = 3
    #player2.meeples = 3

    #player1.punkte = 3

    d = {player1: player2, player2: player1}

    if kartenliste is None:
        spiel = Spiel(create_kartenliste(karteninfoliste))
    else:
        spiel = Spiel(kartenliste)

    #select startspieler
    current_player = player2



    #####
    #k1 = Card('O', 'W', 'W', 'O', 'O')
    #spiel.make_action(k1, (1, 0), 0, player1, k1.orte[0])

    #k2 = Card('O', 'W', 'W', 'O', 'O')
    #spiel.make_action(k2, (1, 0), 0, player1)
    #####


    game_is_running = True
    while game_is_running:

        print('player1 hat {} Punkte, player2 hat {} Punkte.'.format(player1.punkte, player2.punkte))

        # display spielbrett
        display_spielbrett_dict(spiel.cards_set)

        current_card = spiel.draw_card()
        #print('Alle moeglichen actions:')
        #print(spiel.calculate_possible_actions(current_card, current_player))

        print('\nDie nachste Karte ist [{0}, {1}, {2}, {3}, {4}, {5}]'.format(current_card.info[0], current_card.info[1], current_card.info[2], current_card.info[3], current_card.mitte, current_card.schild))

        draw_card(current_card)
        print('Sie enthält folgende moegliche Meeplepositionen:')
        print('Orte:')
        for o in current_card.orte:
            print(o.name, o.kanten)
        print('Strassen:')
        for s in current_card.strassen:
            print(s.name, s.kanten)
        print('Wiesen:')
        for w in current_card.wiesen:
            print(w.name, w.ecken)

        pos = spiel.calculate_possible_actions(current_card, current_player)

        if pos:

            if current_player.art == 'human':
                 #gib move ein
                    inp = input('Bitte gib deine Aktion an:')

                    inp_split = inp.split(' ')
                    ungueltig = True
                    action = None
                    try:
                        if inp_split[3][0] == 'o':
                            o = [a for a in current_card.orte if a.name == int(inp_split[3][1])]
                            action = (int(inp_split[0]), int(inp_split[1]), int(inp_split[2]), o[0])
                        elif inp_split[3][0] == 's':
                            s = [a for a in current_card.strassen if a.name == int(inp_split[3][1])]
                            action = (int(inp_split[0]), int(inp_split[1]), int(inp_split[2]), s[0])
                        elif inp_split[3][0] == 'w':
                            w = [a for a in current_card.wiesen if a.name == int(inp_split[3][1])]
                            action = (int(inp_split[0]), int(inp_split[1]), int(inp_split[2]), w[0])
                        elif inp_split[3][0] == 'k':
                            action = (int(inp_split[0]), int(inp_split[1]), int(inp_split[2]), 'K')
                        else:
                            action = (int(inp_split[0]), int(inp_split[1]), int(inp_split[2]), None)
                    except IndexError or ValueError:
                        pass

                    #falls move unguelig:
                    if action in pos:
                        ungueltig = False
                    while ungueltig:
                        print("illegaler Move")
                        inp = input('Bitte gib deine Aktion an:')
                        inp_split = inp.split(' ')
                        try:
                            if inp_split[3][0] == 'o':
                                o = [a for a in current_card.orte if a.name == int(inp_split[3][1])]
                                action = (int(inp_split[0]), int(inp_split[1]), int(inp_split[2]), o[0])
                            elif inp_split[3][0] == 's':
                                s = [a for a in current_card.strassen if a.name == int(inp_split[3][1])]
                                action = (int(inp_split[0]), int(inp_split[1]), int(inp_split[2]), s[0])
                            elif inp_split[3][0] == 'w':
                                w = [a for a in current_card.wiesen if a.name == int(inp_split[3][1])]
                                action = (int(inp_split[0]), int(inp_split[1]), int(inp_split[2]), w[0])
                            elif inp_split[3][0] == 'k':
                                action = (int(inp_split[0]), int(inp_split[1]), int(inp_split[2]), 'K')
                            else:
                                action = (int(inp_split[0]), int(inp_split[1]), int(inp_split[2]), None)
                        except IndexError or ValueError:
                            pass
                        if action in pos:
                            ungueltig = False


                    spiel.make_action(current_card, (action[0], action[1]), action[2], current_player, action[3])

                    #spieler wechseln
                    current_player = d[current_player]

                    if not spiel.cards_left:
                        game_is_running = False

            else:

                # ai
                child_nodes = [Node(action) for action in pos]

                t = 0
                t_end = 500

                # player stats in real game
                current_player_stats = (current_player.meeples, current_player.punkte)
                other_player_stats = (d[current_player].meeples, d[current_player].punkte)

                # loop as long as time is left:
                while t < t_end:

                    spiel_copy = deepcopy(spiel)
                    current_card_copy = deepcopy(current_card)

                    #player zurueckaendern:
                    """die spieler, die beim kopieren vom Spiel veraendert wurden werden hier wieder zurueckgesetzt"""
                    l = [spiel_copy.alle_orte, spiel_copy.alle_wiesen, spiel_copy.alle_strassen]
                    for landart in l:
                        for instance in landart:
                            if instance.meeples:

                                new_d = {current_player: 0, d[current_player]: 0}
                                for player in instance.meeples:
                                    for global_player in new_d:
                                        if global_player.nummer == player.nummer:
                                            new_d[global_player] = instance.meeples[player]
                                instance.meeples = new_d
                                instance.update_besitzer()

                    # spieler von kloestern zuruecksetzen
                    for global_kloster in spiel.alle_kloester:
                        for kloster in spiel_copy.alle_kloester:
                            if kloster.umgebungs_koordinaten == global_kloster.umgebungs_koordinaten:
                                kloster.besitzer = global_kloster.besitzer

                    #current_card_copy = deepcopy(current_card)

                    current_node = max(child_nodes, key=lambda nod: nod.calculate_UCB1_value(t))

                    meeple_pos = 'K'

                    if isinstance(current_node.action[3], Ort_auf_Karte):
                        for ort in current_card_copy.orte:
                            if ort.name == current_node.action[3].name:
                                meeple_pos = ort
                                break
                    elif isinstance(current_node.action[3], StasseAufKarte):
                        for strasse in current_card_copy.strassen:
                            if strasse.name == current_node.action[3].name:
                                meeple_pos = strasse
                                break
                    elif isinstance(current_node.action[3], WieseAufKarte):
                        for wiese in current_card_copy.wiesen:
                            if wiese.name == current_node.action[3].name:
                                meeple_pos = wiese
                                break

                    spiel_copy.make_action(current_card_copy, (current_node.action[0], current_node.action[1]), current_node.action[2], current_player, meeple_pos)

                    # play random
                    winner = spiel_copy.play_random1v1(d[current_player], current_player)

                    current_node.visits += 1
                    if winner == current_player:
                        current_node.wins += 1
                    elif winner == 0:
                        current_node.wins += 0.5

                    # spieler nach random-spiel wieder auf ihre ausgangswerte setzen
                    current_player.meeples = current_player_stats[0]
                    current_player.punkte = current_player_stats[1]

                    d[current_player].meeples = other_player_stats[0]
                    d[current_player].punkte = other_player_stats[1]

                    # erste Karte nach dem Spiel wieder resetten
                    #current_card.ecken, current_card.kanten, current_card.orte, current_card.orte_kanten,\
                    #current_card.strassen, current_card.strassen_kanten, current_card.wiesen, current_card.wiesen_kanten = card_stats[0], card_stats[1], card_stats[2], card_stats[3], card_stats[4], card_stats[5], card_stats[6], card_stats[7]

                    t += 1


                #spiel.make_action(max(child_nodes, key=lambda nod: nod.wins).action)
                action = max(child_nodes, key=lambda nod: nod.wins).action
                spiel.make_action(current_card, (action[0], action[1]), action[2], current_player, action[3])

                if action[3] is not None:
                    action_ausgabe = 'K' if action[3] == 'K' else action[3].name
                    print("\nEin Meeple wird auf {} mit Namen {} gesetzt".format(action[3], action_ausgabe))
                else:
                    print("\nEs wird kein Meeple gesetzt")

                print("\nDie AI setzt die Karte an ({}, {}) und rotiert sie {} mal".format(action[0], action[1], action[2]))


                # switch players
                current_player = d[current_player]

                if not spiel.cards_left:
                    game_is_running = False

        else:
            continue

    spiel.final_evaluate()
    print("Spielende: Player1 hat {} Punkte, Player2 hat {} Punkte.".format(player1.punkte, player2.punkte))
예제 #3
0
    def test_1(self):

        player1 = Player(1)
        player2 = Player(2, 'ai')
        d = {player1: player2, player2: player1}

        #zum probieren
        #spiel = Spiel(create_kartenliste(determinized_short_karteninfoliste, False), player1, player2)

        spiel = Spiel(create_kartenliste(determinized_karteninfoliste, False),
                      player1, player2)

        #select startspieler
        current_player = player1

        k1 = spiel.cards_left.pop(0)
        spiel.make_action(current_player, k1, 1, 0, 2, k1.orte[0])

        self.assertEqual(70, len(spiel.cards_left))
        self.assertEqual(player1.punkte, 4)
        self.assertEqual(player1.meeples, 7)

        k1 = spiel.cards_left.pop(0)
        wiese = None
        for w in k1.wiesen:
            if w.ecken == [4, 5, 6]:
                wiese = w
                break
        spiel.make_action(d[current_player], k1, 0, 1, 0, wiese)

        self.assertEqual(69, len(spiel.cards_left))
        self.assertEqual(4, player1.punkte)
        self.assertEqual(7, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(6, player2.meeples)

        k1 = spiel.cards_left.pop(0)

        spiel.make_action(current_player, k1, 0, -1, 1, k1.orte[0])

        self.assertEqual(68, len(spiel.cards_left))
        self.assertEqual(4, player1.punkte)
        self.assertEqual(6, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(6, player2.meeples)

        k1 = spiel.cards_left.pop(0)

        spiel.make_action(d[current_player], k1, -1, 0, 2)

        self.assertEqual(67, len(spiel.cards_left))
        self.assertEqual(4, player1.punkte)
        self.assertEqual(6, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(6, player2.meeples)

        k1 = spiel.cards_left.pop(0)

        spiel.make_action(current_player, k1, -1, -1, 3, k1.orte[0])

        self.assertEqual(66, len(spiel.cards_left))
        self.assertEqual(4, player1.punkte)
        self.assertEqual(5, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(6, player2.meeples)

        k1 = spiel.cards_left.pop(0)

        spiel.make_action(d[current_player], k1, 1, 1, 3, 'k')

        self.assertEqual(65, len(spiel.cards_left))
        self.assertEqual(4, player1.punkte)
        self.assertEqual(5, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(5, player2.meeples)

        k1 = spiel.cards_left.pop(0)

        #display_spielbrett_dict(spiel.cards_set)
        spiel.make_action(current_player, k1, -1, 1, 0, k1.strassen[0])

        self.assertEqual(64, len(spiel.cards_left))
        self.assertEqual(4, player1.punkte)
        self.assertEqual(4, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(5, player2.meeples)

        k1 = spiel.cards_left.pop(0)

        wiese = None
        for w in k1.wiesen:
            if w.ecken == [7]:
                wiese = w
                break
        spiel.make_action(d[current_player], k1, -2, 0, 3, wiese)

        self.assertEqual(63, len(spiel.cards_left))
        self.assertEqual(4, player1.punkte)
        self.assertEqual(4, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(4, player2.meeples)

        k1 = spiel.cards_left.pop(0)

        spiel.make_action(current_player, k1, 0, 2, 1, None)

        self.assertEqual(62, len(spiel.cards_left))
        self.assertEqual(4, player1.punkte)
        self.assertEqual(4, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(4, player2.meeples)

        k1 = spiel.cards_left.pop(0)

        spiel.make_action(d[current_player], k1, 0, 3, 0, k1.orte[0])

        self.assertEqual(61, len(spiel.cards_left))
        self.assertEqual(4, player1.punkte)
        self.assertEqual(4, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(3, player2.meeples)

        k1 = spiel.cards_left.pop(0)

        spiel.make_action(current_player, k1, -2, -1, 0, None)

        self.assertEqual(60, len(spiel.cards_left))
        self.assertEqual(11, player1.punkte)
        self.assertEqual(5, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(3, player2.meeples)

        k1 = spiel.cards_left.pop(0)

        spiel.make_action(d[current_player], k1, -1, 3, 0, None)

        self.assertEqual(59, len(spiel.cards_left))
        self.assertEqual(11, player1.punkte)
        self.assertEqual(5, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(3, player2.meeples)

        self.assertEqual(len(spiel.alle_kloester), 1)
        self.assertEqual(len(spiel.alle_strassen), 8)
        self.assertEqual(len(spiel.alle_orte), 5)
        self.assertEqual(len(spiel.alle_wiesen), 8)

        k1 = spiel.cards_left.pop(0)

        spiel.make_action(current_player, k1, -1, -2, 3, k1.wiesen[0])

        self.assertEqual(58, len(spiel.cards_left))
        self.assertEqual(21, player1.punkte)
        self.assertEqual(5, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(3, player2.meeples)

        self.assertEqual(len(spiel.alle_kloester), 1)
        self.assertEqual(len(spiel.alle_strassen), 8)
        self.assertEqual(len(spiel.alle_orte), 6)
        self.assertEqual(len(spiel.alle_wiesen), 9)

        k1 = spiel.cards_left.pop(0)

        spiel.make_action(d[current_player], k1, 2, 1, 1, None)

        self.assertEqual(57, len(spiel.cards_left))
        self.assertEqual(21, player1.punkte)
        self.assertEqual(5, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(3, player2.meeples)

        self.assertEqual(len(spiel.alle_kloester), 1)
        self.assertEqual(len(spiel.alle_strassen), 8)
        self.assertEqual(len(spiel.alle_orte), 6)
        self.assertEqual(len(spiel.alle_wiesen), 9)

        k1 = spiel.cards_left.pop(0)

        spiel.make_action(current_player, k1, -1, -3, 0, k1.orte[0])

        self.assertEqual(56, len(spiel.cards_left))
        self.assertEqual(21, player1.punkte)
        self.assertEqual(4, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(3, player2.meeples)

        self.assertEqual(len(spiel.alle_kloester), 1)
        self.assertEqual(len(spiel.alle_strassen), 8)
        self.assertEqual(len(spiel.alle_orte), 7)
        self.assertEqual(len(spiel.alle_wiesen), 10)

        k1 = spiel.cards_left.pop(0)

        ort = None
        for o in k1.orte:
            if o.kanten == [3]:
                ort = o
                break
        spiel.make_action(d[current_player], k1, -3, 0, 1, ort)

        self.assertEqual(55, len(spiel.cards_left))
        self.assertEqual(21, player1.punkte)
        self.assertEqual(4, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(2, player2.meeples)

        self.assertEqual(len(spiel.alle_kloester), 1)
        self.assertEqual(len(spiel.alle_strassen), 8)
        self.assertEqual(len(spiel.alle_orte), 9)
        self.assertEqual(len(spiel.alle_wiesen), 10)

        k1 = spiel.cards_left.pop(0)

        spiel.make_action(current_player, k1, 0, -2, 0, None)

        self.assertEqual(54, len(spiel.cards_left))
        self.assertEqual(27, player1.punkte)
        self.assertEqual(5, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(2, player2.meeples)

        self.assertEqual(len(spiel.alle_kloester), 1)
        self.assertEqual(len(spiel.alle_strassen), 8)
        self.assertEqual(len(spiel.alle_orte), 8)
        self.assertEqual(len(spiel.alle_wiesen), 11)

        k1 = spiel.cards_left.pop(0)

        spiel.make_action(d[current_player], k1, 3, 1, 1, None)

        self.assertEqual(53, len(spiel.cards_left))
        self.assertEqual(27, player1.punkte)
        self.assertEqual(5, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(2, player2.meeples)

        self.assertEqual(len(spiel.alle_kloester), 1)
        self.assertEqual(len(spiel.alle_strassen), 8)
        self.assertEqual(len(spiel.alle_orte), 8)
        self.assertEqual(len(spiel.alle_wiesen), 11)

        k1 = spiel.cards_left.pop(0)

        spiel.make_action(current_player, k1, -2, 1, 0, 'k')

        self.assertEqual(52, len(spiel.cards_left))
        self.assertEqual(27, player1.punkte)
        self.assertEqual(4, player1.meeples)

        self.assertEqual(0, player2.punkte)
        self.assertEqual(2, player2.meeples)

        self.assertEqual(len(spiel.alle_kloester), 2)
        self.assertEqual(len(spiel.alle_strassen), 8)
        self.assertEqual(len(spiel.alle_orte), 8)
        self.assertEqual(len(spiel.alle_wiesen), 11)

        mcts = MCTS((player1, player2), spiel.play_random1v1,
                    spiel.calculate_possible_actions)
        mcts.root = Node(True, None, d[current_player].nummer)

        player1.art = 'human'
        player2.art = 'ai'

        current_player = d[current_player]

        game_is_running = True
        while game_is_running:
            print(
                '\n\nNEUER ZUG: Aktuell hat player1 {} Punkte und player2 {} Punkte.\n'
                .format(player1.punkte, player2.punkte))
            display_spielbrett_dict(spiel.cards_set)
            current_card = spiel.cards_left[0]
            print(
                'Die nachste Karte ist [{0}, {1}, {2}, {3}, {4}, {5}]'.format(
                    current_card.info[0], current_card.info[1],
                    current_card.info[2], current_card.info[3],
                    current_card.mitte, current_card.schild))
            draw_card(current_card)
            print('Sie enthält folgende moegliche Meeplepositionen:')
            print('Orte:')
            for o in current_card.orte:
                print(o.name, o.kanten)
            print('Strassen:')
            for s in current_card.strassen:
                print(s.name, s.kanten)
            print('Wiesen:')
            for w in current_card.wiesen:
                print(w.name, w.ecken)
            pos = spiel.calculate_possible_actions(current_card,
                                                   current_player)
            # wenn es moegliche anlegestellenn (fuer den aktuellen Spieler) gibt, (es gibt fuer einen spieler auf jeden Fall
            # eine Anlegemoeglichkeit, wenn es fuer den anderen auch eine gibt)
            if pos:
                if current_player.art == 'human':
                    #mache deinen move
                    #gib move ein
                    inp = input('Bitte gib deine Aktion an:')
                    inp_split = inp.split(' ')
                    ungueltig = True
                    action = None
                    try:
                        if inp_split[3][0] == 'o':
                            o = [
                                a for a in current_card.orte
                                if a.name == int(inp_split[3][1])
                            ]
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), o[0])
                        elif inp_split[3][0] == 's':
                            s = [
                                a for a in current_card.strassen
                                if a.name == int(inp_split[3][1])
                            ]
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), s[0])
                        elif inp_split[3][0] == 'w':
                            w = [
                                a for a in current_card.wiesen
                                if a.name == int(inp_split[3][1])
                            ]
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), w[0])
                        elif inp_split[3][0] == 'k':
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), 'K')
                        else:
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), None)
                    except IndexError or ValueError:
                        pass
                    # falls move unguelig:
                    if action in pos:
                        ungueltig = False
                    while ungueltig:
                        print("illegaler Move")
                        inp = input('Bitte gib deine Aktion an:')
                        inp_split = inp.split(' ')
                        try:
                            if inp_split[3][0] == 'o':
                                o = [
                                    a for a in current_card.orte
                                    if a.name == int(inp_split[3][1])
                                ]
                                action = (int(inp_split[0]), int(inp_split[1]),
                                          int(inp_split[2]), o[0])
                            elif inp_split[3][0] == 's':
                                s = [
                                    a for a in current_card.strassen
                                    if a.name == int(inp_split[3][1])
                                ]
                                action = (int(inp_split[0]), int(inp_split[1]),
                                          int(inp_split[2]), s[0])
                            elif inp_split[3][0] == 'w':
                                w = [
                                    a for a in current_card.wiesen
                                    if a.name == int(inp_split[3][1])
                                ]
                                action = (int(inp_split[0]), int(inp_split[1]),
                                          int(inp_split[2]), w[0])
                            elif inp_split[3][0] == 'k':
                                action = (int(inp_split[0]), int(inp_split[1]),
                                          int(inp_split[2]), 'K')
                            else:
                                action = (int(inp_split[0]), int(inp_split[1]),
                                          int(inp_split[2]), None)
                        except IndexError or ValueError:
                            pass
                        if action in pos:
                            ungueltig = False
                    spiel.make_action(current_card, (action[0], action[1]),
                                      action[2], current_player, action[3])
                    # root anpassen
                    if mcts.root.children:
                        for child in mcts.root.children:
                            # wenn die action von der child-node der gespielten entspricht
                            # wenn nicht none
                            if action[3]:
                                landschafts_name = 1 if inp_split[3][
                                    0] == 'k' else action[3].name
                                landschafts_id = inp_split[3][0]
                            else:
                                landschafts_name = None
                                landschafts_id = None
                            if child.action == ((action[0], action[1]),
                                                action[2], landschafts_id,
                                                landschafts_name):  ###
                                mcts.root = child
                                break
                    else:
                        #another player made the first move of the game
                        if action[3]:
                            landschafts_name = 1 if inp_split[3][
                                0] == 'k' else action[3].name
                            landschafts_id = inp_split[3][0]
                        else:
                            landschafts_name = None
                            landschafts_id = None
                        p_num = 1 if current_player.nummer == 2 else 2
                        mcts.root = Node(True,
                                         ((action[0], action[1]), action[2],
                                          landschafts_id, landschafts_name),
                                         p_num, mcts.root)
                    #gesetzte Karte loeschen
                    del spiel.cards_left[0]
                    if len(spiel.cards_left) == 0:
                        game_is_running = False
                    #spieler wechseln
                    current_player = d[current_player]
                else:
                    # AI-PLayer
                    mcts.root = mcts.find_next_move(spiel)
                    # l_a_K auf die gespielt werden soll
                    if mcts.root.action[2] is None:
                        landschaft = None
                    elif mcts.root.action[2] == 'k':
                        landschaft = 'K'
                    else:
                        l_dict = {
                            'o': current_card.orte,
                            's': current_card.strassen,
                            'w': current_card.wiesen
                        }
                        landschaft = [
                            l for l in l_dict[mcts.root.action[2]]
                            if l.name == mcts.root.action[3]
                        ][0]
                    spiel.make_action(
                        current_card, mcts.root.action[0], mcts.root.action[1],
                        current_player,
                        landschaft)  #######################################
                    if mcts.root.action[2] is not None:
                        #action_ausgabe = 'K' if mcts.root.action[2] == 'k' else mcts.root.action[2]
                        print("\nDie AI setzt einen Meeple auf {}{}.".format(
                            mcts.root.action[2], mcts.root.action[3]))
                    elif mcts.root.action[2] == 'k':
                        print("\nDie AI setzt einem Meeple auf das Kloster.")
                    else:
                        print("\nDie AI setzt keinen Meeple.")
                    print(
                        "Die AI setzt die Karte an {} und rotiert sie {} mal".
                        format(mcts.root.action[0], mcts.root.action[1]))
                    # gesetzte Karte loeschen
                    del spiel.cards_left[0]
                    if len(spiel.cards_left) == 0:
                        game_is_running = False
                    # spieler wechseln
                    current_player = d[current_player]
            else:
                continue
        spiel.final_evaluate()
        print("\nSpielende: Player1 hat {} Punkte, Player2 hat {} Punkte.".
              format(player1.punkte, player2.punkte))
예제 #4
0
def human_vs_ai(decorator,
                karteninfos=karteninfoliste,
                shuffle=True,
                startspieler='human'):
    """

    function for playing a game against any implemented AI as a human player, based on a determinized cardlist

    :param decorator:       the decorator function of the AI player
    :param karteninfos:     list of card_informations for the game, the cardlist will be created from that list which has
                            the following form: ['WWSWK', 'WWSS', 'OOSSOOT', ...]
    :param shuffle:         boolean which ensures that the cardlist is beeing shuffled if True
    :param startspieler:    either 'human', or 'ai' for selecting the starting player
    :return:                None

    The human player enters his commands via the python console:

    For every card that is drawn by the human player there are information printed to the console.
    One example might be:

        Die naechste Karte ist [S, O, S, S, G, False]
        Sie enthaelt folgende moegliche Meeplepositionen:
        Orte:
        1 [1]
        Strassen:
        1 [0]
        2 [2]
        3 [3]
        Wiesen:
        1 [4]
        2 [5, 6]
        3 [7]
        Bitte gib deine Aktion an:

    To enter the command, one has to use the following format:
    x y (# of right-rotations) (letter for territory+# of territory)

    For example:
    0 1 3 o1

    This stands for the following action:
        - placing a meeple on the ort 1, which is located on the right side of the card
        - rotating the card three times to the right
        - placing the tile on the filed (0,1)

    """

    player1 = Player(1)
    player2 = Player(2, 'ai')
    d = {player1: player2, player2: player1}

    spiel = Spiel(create_kartenliste(karteninfos, shuffle), player1, player2)

    # select startspieler
    current_player = player1 if startspieler == 'human' else player2
    print('Der Startspieler ist {} und hat die Nummer {}'.format(
        current_player.art, current_player.nummer))

    # the function that the AI uses for selecting it's next move
    dic1 = {}
    ai_select = decorator(select_to_decorator[decorator.__name__], dic1)

    # playing against an UCT-Player?
    uct_bool = True if select_to_decorator[
        decorator.__name__] == uct_select else False

    root = Node(True, None, current_player.nummer)

    while len(spiel.cards_left) > 0:

        print(
            f'\n\nNEUER ZUG: Aktuell hat player1 {player1.punkte} Punkte und {player1.meeples} Meeples und player2 {player2.punkte} Punkte und {player2.meeples} Meeples.\n'
        )

        display_spielbrett_dict(spiel.cards_set)
        current_card = spiel.cards_left.pop(0)

        print('Die nachste Karte ist [{0}, {1}, {2}, {3}, {4}, {5}]'.format(
            current_card.info[0], current_card.info[1], current_card.info[2],
            current_card.info[3], current_card.mitte, current_card.schild))

        print('Sie enthält folgende moegliche Meeplepositionen:')
        print('Orte:')
        for o in current_card.orte:
            print(o.name, o.kanten)
        print('Strassen:')
        for s in current_card.strassen:
            print(s.name, s.kanten)
        print('Wiesen:')
        for w in current_card.wiesen:
            print(w.name, w.ecken)

        draw_card(current_card)

        pos = spiel.calculate_possible_actions(current_card, current_player)

        # wenn es moegliche anlegestellenn (fuer den aktuellen Spieler) gibt, (es gibt fuer einen spieler auf jeden Fall
        # eine Anlegemoeglichkeit, wenn es fuer den anderen auch eine gibt)
        if pos:
            if current_player.art == 'human':

                # gib move ein
                inp = input('Bitte gib deine Aktion an:')
                inp_split = inp.split(' ')

                ungueltig = True
                action = None
                try:
                    if inp_split[3][0] == 'o':
                        o = [
                            a for a in current_card.orte
                            if a.name == int(inp_split[3][1])
                        ]
                        action = (int(inp_split[0]), int(inp_split[1]),
                                  int(inp_split[2]), o[0])
                    elif inp_split[3][0] == 's':
                        s = [
                            a for a in current_card.strassen
                            if a.name == int(inp_split[3][1])
                        ]
                        action = (int(inp_split[0]), int(inp_split[1]),
                                  int(inp_split[2]), s[0])
                    elif inp_split[3][0] == 'w':
                        w = [
                            a for a in current_card.wiesen
                            if a.name == int(inp_split[3][1])
                        ]
                        action = (int(inp_split[0]), int(inp_split[1]),
                                  int(inp_split[2]), w[0])
                    elif inp_split[3][0] == 'k':
                        action = (int(inp_split[0]), int(inp_split[1]),
                                  int(inp_split[2]), 'k')
                    else:
                        action = (int(inp_split[0]), int(inp_split[1]),
                                  int(inp_split[2]), None)
                except IndexError or ValueError:
                    print('ERROR CATCHED')

                # falls move unguelig:
                if action in pos:
                    ungueltig = False
                while ungueltig:
                    print("illegaler Move")
                    inp = input('Bitte gib deine Aktion an:')
                    inp_split = inp.split(' ')
                    try:
                        if inp_split[3][0] == 'o':
                            o = [
                                a for a in current_card.orte
                                if a.name == int(inp_split[3][1])
                            ]
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), o[0])
                        elif inp_split[3][0] == 's':
                            s = [
                                a for a in current_card.strassen
                                if a.name == int(inp_split[3][1])
                            ]
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), s[0])
                        elif inp_split[3][0] == 'w':
                            w = [
                                a for a in current_card.wiesen
                                if a.name == int(inp_split[3][1])
                            ]
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), w[0])
                        elif inp_split[3][0] == 'k':
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), 'k')
                        else:
                            action = (int(inp_split[0]), int(inp_split[1]),
                                      int(inp_split[2]), None)
                    except IndexError or ValueError:
                        pass
                    if action in pos:
                        ungueltig = False

                spiel.make_action(current_player, current_card, action[0],
                                  action[1], action[2], action[3])

                if uct_bool:

                    # gespielte action formulieren
                    if action[3]:
                        lak_id = inp_split[3][0]
                        lak_name = 1 if inp_split[3][0] == 'k' else action[
                            3].name
                    else:
                        lak_id = None
                        lak_name = None

                    node_action = (action[0], action[1], action[2], lak_id,
                                   lak_name)

                    # root anpassen

                    # falls die aktuelle root_node bereits Kinder hat
                    if root.children:
                        for child in root.children:

                            # wenn die action von der child-node der gespielten entspricht
                            if child.action == node_action:
                                root = child
                                break

                    # another player made the first move of the game, or the node has no visits yet
                    else:
                        root = Node(True, node_action, 2, None)

            # AI-PLayer
            else:

                action, root = ai_select(spiel, current_card, current_player,
                                         pos, d, root)
                spiel.make_action(current_player, current_card, action[0],
                                  action[1], action[2], action[3])

                # falls die AI-Aktion einen Meeple auf eine Landschaft (ausser Kloster) setzt
                if action[3] == 'k':
                    print("\nDie AI setzt einem Meeple auf das Kloster.")
                elif action[3] is not None:
                    print("\nDie AI setzt einen Meeple auf {}{}.".format(
                        action[3].id, action[3].name))
                else:
                    print("\nDie AI setzt keinen Meeple.")

                print(
                    "Die AI rotiert die Karte {} mal und setzt sie an ({}, {}) "
                    .format(action[2], action[0], action[1]))

            # spieler wechseln
            current_player = d[current_player]

        # wenn es fuer die gezogene Karte keine Anlegestelle gibt
        else:
            print("ES GIBT FUER DIESE KARTE KEINE ANLEGESTELLE")
            continue

    print(
        f'\nVor der finalen Auswertung hat Player1 {player1.punkte} und {player1.meeples} Meeples und Player2 {player2.punkte} Punkte und {player2.meeples} Meeples.'
    )

    spiel.final_evaluate()
    print("\nSpielende: Player1 hat {} Punkte, Player2 hat {} Punkte.".format(
        player1.punkte, player2.punkte))
예제 #5
0
    return l


#Kartenliste = create_kartenliste(Karteninfos_neu)

if __name__ == "__main__":
    ka = Card("O", "S", "S", "W")
    print(ka.matrix)
    ka.rotate_right()
    print("\n", ka.matrix)
    ka.rotate_right()
    print("\n", ka.matrix)
    ka.rotate_right()
    print("\n", ka.matrix)

    random.shuffle(karteninfoliste)
    print(karteninfoliste)

    import plot_cards
    for c in determinized_karteninfoliste:
        i = list(c)

        if len(i) == 4:
            a, b, c, d, m, schild = i[0], i[1], i[2], i[3], None, False
        elif len(i) == 5:
            a, b, c, d, m, schild = i[0], i[1], i[2], i[3], i[4], False
        else:
            a, b, c, d, m, schild = i[0], i[1], i[2], i[3], i[4], True

        plot_cards.draw_card(Card(a, b, c, d, m, schild))