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))
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))
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))
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))
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))