Camel Up Cup: Turniej gry planszowej AI

11

Puchar Camel Up 2k18

W tym wyzwaniu będziemy grać w częściowo popularną grę planszową Camel Up.

Camel Up! to gra planszowa, w której gracze obstawiają wielbłądy, aby wygrywać rundy, wygrywać lub przegrywać, ustawiać pułapki, aby wpływać na ruch lub poruszać wielbłądem. Każda z tych decyzji nagradza Cię szansą na zdobycie pieniędzy, co decyduje o wygranej. Gracze powinni podejmować decyzje na podstawie prawdopodobieństwa, stanu gry i najmu przeciwników. Oto krótki film pokazujący graczom, jak grać .

Jak grać

Oto przybliżony pomysł na grę. Oglądanie jednego z filmów może być bardziej pomocne, ponieważ mają elementy wizualne :)

W swojej turze masz 4 opcje.

  1. Przesuń wielbłąda. Wybiera wielbłąda spośród tych, którzy się nie poruszyli, i przesuwa go między 1-3 polami. Dostajesz 1 monetę. Rundy kończą się, gdy wszystkie pięć wielbłądów się poruszy, wszystkie mogą się poruszać
  2. Umieść pułapkę. Odnosi się to do planszy do końca rundy. Wybierasz pułapkę +1 / -1. Jeśli wyląduje na nim wielbłąd lub stos wielbłądów, poruszają się + 1 / -1 i dostajesz monetę. Nie możesz umieścić pułapki na kwadracie 0. Możesz umieścić pułapkę w miejscu, w którym znajdują się wielbłądy, chociaż wpłynie to tylko na wielbłądy, które na nią wylądują.
  3. Zakład na zwycięzcę rundy. Stawiasz zakład na zwycięzcę rundy. Wygrywają, że dostaniesz 5/3/2/1 w zależności od tego, czy byłeś na 1. / 2. / 3. miejscu, aby postawić na tego wielbłąda.
  4. Zwycięzca / przegrany. Obstawiasz, kto będzie pierwszy lub ostatni na końcu gry. dostajesz 8/5/3/1/1 (myślę) na podstawie tego, czy byłeś na 1. / 2. / 3. / itd., aby postawić na tego wielbłąda

Uwagi:

  • Jest 5 wielbłądów. Zaczynają na pozycji losowo od 0-2.
  • Kiedy wielbłąd jest poruszany (patrz powyżej, co go powoduje), poruszają się o 1-3 pola. Jeśli zostaną umieszczone na kwadracie z innym wielbłądem, zostaną umieszczone „na wierzchu” drugiego, tworząc stos wielbłądów. Jeśli wielbłąd ma się poruszyć, przesuwa wszystkie wielbłądy nad nim na stosie wielbłądów. Wielbłąd u góry stosu jest uważany za smycz
  • Jeśli wylądujesz na pułapce +1 (zobacz powyżej, co to powoduje), przesuwasz się o jedno pole dalej do przodu. Obowiązują standardowe zasady układania.
  • Jeśli jednak trafisz w pułapkę -1, przesuwasz się o jedno pole do tyłu. Wchodzisz pod stos wielbłądów, które są na tym kwadracie, jeśli takie istnieją.
  • Gra kończy się, gdy wielbłąd uderzy w pole 16. To natychmiast wywołuje koniec rundy i wyzwalanie końca gry
  • Zakłady na zwycięzcę / przegranego można wykonać tylko raz na jednego wielbłąda. Tzn. Nie możesz postawić na wielbłąda, aby wygrać i przegrać

Wyzwanie

W tym wyzwaniu napiszesz program w języku Python 3, w którym bierze udział czterech graczy, zwycięzca bierze całą grę chwały w Camel Up

Twój program otrzyma gamestate, który zawiera:

  • camel_track : z lokalizacjami wielbłądów
  • trap_track : z lokalizacją pułapek (wpis postaci [trap_type (-1,1), player])
  • player_has_placed_trap : tablica informująca, czy gracze postawili pułapkę w tej rundzie
  • round_bets : tablica zakładów postawionych w tej rundzie. O formie [wielbłąd, gracz]
  • game_winner_bets / game_loser_bets : tablice zakładów postawionych przez wielbłądy na wygraną lub przegraną. Będziesz mógł zobaczyć tylko wartość graczy, którzy postawili zakłady, a nie kogo obstawiać. Możesz wiedzieć, na kogo obstawiasz. # formy [wielbłąd, gracz]
  • player_game_bets : kolejna reprezentacja game_winner_bets / game_loser_bets. Ponownie spójrz tylko na zakłady, które zrobił twój bot.
  • player_money_values : tablica pokazująca ilość pieniędzy każdego gracza.
  • camel_yet_to_move : Tablica pokazująca, czy wielbłąd poruszył się w tej rundzie.

Oprócz gamestate otrzymujesz również:

  • player : liczba całkowita określająca numer gracza (0-3).

Składnia tego, co gracze powinni zwrócić, to:

  • [0]: Przenieś wielbłąda
  • [1, trap_type, trap_location]: Umieść pułapkę
  • [2, projected_round_winner]: Postaw zakład na zwycięzcę rundy
  • [3, projected_game_winner]: Make Bet Winner Bet
  • [4, projected_game_loser]: Make Bet Loser Bet

Powinno to być owinięte metodą ruchu (gracz, gamestate)

Na przykład, oto gracz, który obstawi zwycięzcę rundy, jeśli znajdzie się na ostatnim miejscu. Jeśli nie są, umieszczają pułapkę na losowym polu.

class Player1(PlayerInterface):
     def move(player,g):
         if min(g.player_money_values) == g.player_money_values[player]:
            return [2,random.randint(0,len(g.camels)-1)]
        return [1,math.floor(2*random.random())*2-1,random.randint(1,10)]

Gra została wybrana z kilku powodów: ma stosunkowo niewielką pulę opcji do wyboru (około 20 wyborów na turę, łatwo zawęzić do zwykle około 3-4), gry są krótkie i jest element szczęścia (sprawia, że ​​jest to szczęście więc nawet „złe” boty mogą wygrać).

Rozgrywka

Biegacza turnieju można znaleźć tutaj: puchar wielbłąda . Uruchom, camelup.pyaby uruchomić turniej lub funkcję PlayGame, aby uruchomić gry. Będę aktualizować to repozytorium o nowe zgłoszenia. Przykładowe programy można znaleźć w players.py.

Turniej składa się ze 100 gier na 10 graczy (w zaokrągleniu w górę, więc 14 graczy oznacza 200 gier). W każdej grze będzie czterech losowych graczy wybranych z puli graczy, którzy zajmą cztery pozycje. Gracze nie będą mogli być w grze dwa razy.

Punktacja

Zwycięzcą każdej gry jest gracz z największą ilością pieniędzy na koniec gry. W przypadku remisu na końcu gry wszyscy gracze z maksymalną kwotą pieniężną otrzymują punkt. Gracz z największą liczbą punktów na koniec turnieju wygrywa. Będę publikować wyniki podczas uruchamiania gier.

Zgłoszeni gracze zostaną dodani do puli. Dodałem trzy naprawdę głupie boty i jeden, który stworzyłem na start.

Ostrzeżenia

Nie modyfikuj wejść. Nie próbuj wpływać na wykonanie jakiegokolwiek innego programu, z wyjątkiem współpracy lub uszkodzenia. Nie składaj ofiarnego poddania się, które usiłuje rozpoznać kolejne poddanie się i przynieść korzyści przeciwnikowi na własny koszt. Standardowe luki są zabronione.

Ograniczyć czas potrzebny botowi do ~ 10 s na turę.

Zgłoszenia nie mogą powielać wcześniejszych zgłoszeń.

Nie wyświetlaj zakładów Game_winner ani game_loser od innych graczy. Jest to dość łatwe do zrobienia, ale nadal oszukiwanie.

Jeśli masz jakieś pytania, możesz je zadać.

Zwycięski

Konkurs pozostanie otwarty przez czas nieokreślony, ponieważ publikowane będą nowe zgłoszenia. Ogłaszam jednak zwycięzcę (akceptuję odpowiedź) na podstawie wyników miesiąc po opublikowaniu tego pytania (20 lipca).

Wyniki

Player0: 12
Player1: 0
Player2: 1
Sir_Humpfree_Bogart: 87
Tyler Barron
źródło
Może przeczytałem już to, ale ile jest wielbłądów w grze? Ponadto, ile kwadratów muszą pokonać, aby przejść na drugą stronę? Na podstawie twojego kodu GitHub jestem pewien, że to 5 wielbłądów i 25 kwadratów, ale nie widziałem tego wspomnianego w opisie wyzwania. Co do stawiania zakładów, czy możemy postawić dowolną kwotę, czy domyślnie obstawi 1? Czy mamy limit wydatków, czy możemy obstawiać każdą rundę w nieskończoność? Który wielbłąd porusza się w przypadku graczy poruszających się na wielbłądzie? Wielbłąd z pasującym graczem nr? Jeśli tak, dlaczego jest 4 graczy, ale 5 wielbłądów?
Kevin Cruijssen
1
Byłoby idealnie, gdyby Perl odpowiedział
Przypadkowy facet
Witamy w PPCG!
AdmBorkBork
100 gier na 10 graczy wydaje się dość niskim IMO, szczególnie w przypadku gry o tak dużej losowości
Nathan Merrill,
1
@AdmBorkBork Dziękujemy! Jestem nowy w tym, więc witam wszystkie wskazówki. To działało dobrze w prawdziwym życiu - wzmocnione, aby zobaczyć, jak tu się gra
Tyler Barron,

Odpowiedzi:

1

Sir_Humpfree_Bogart.py

To jest bot, który stworzyłem na turniej Camel Up Cup .

Najpierw sprawdzają wszystkie możliwe konfiguracje, na których wielbłądy mogą skończyć na końcu rundy. Następnie określają oczekiwaną wartość zakładów na wielbłądzie wygrywającym rundę za pomocą

EV_roundwin = (chance_1st)*(payout) + (chance_2nd)*(payout) - (chance_3rd_or_worse)*(cost)

Następnie poruszają się wielbłądy losowo, aż wygra wielbłąd. Po zrobieniu tego kilka tysięcy razy możesz oszacować szansę, że każdy wielbłąd wygra i przegra. Ponownie otrzymujemy oczekiwaną wartość ich użycia

EV_gamewin = (chance_1st)*(payout) - (chance_2nd_or_worse)*(cost)

Jedynymi innymi opcjami jest przesunięcie wielbłąda (który zawsze daje jedną monetę, więc jego oczekiwana wartość to jedna) i umieszczenie pułapki. Obie drużyny uważały, że umieszczenie pułapki było wystarczająco słabą opcją, aby całkowicie ją zignorować. Dzięki tym informacjom boty wybrały opcję o najwyższej oczekiwanej wartości.

Ponieważ w turnieju oglądano drugie miejsce, tak samo jak ostatnie miejsce, sensowne jest, jeśli masz zaległe szanse na zajęcie pierwszego miejsca. SBH zastosował odległość od pierwszego miejsca i bliskość do końca, aby określić, jak ryzykowny powinien być bot, gdzie jeśli jesteś daleko od pierwszego i blisko końca, wówczas ryzyko byłoby wysokie, a jeśli jesteś na początku lub daleko od końca gry, ryzyko byłoby niskie . Przy niskim ryzyku bot zdecydowałby się na akcję z opcją o wysokiej wartości oczekiwanej, a wysoka ryzykowność dałaby opcję o wysokim wyniku. Dokładne równanie było

Functional_EV = EV + (upshot-EV) * riskiness

gdzie wynik jest najwyższą wypłatą, jaką można uzyskać z decyzji, a ryzyko waha się od 0 do 1.

Tyler Barron
źródło
0

players.py

Są to niezwykle głupie boty, aby rozpocząć turniej. Nie mają prawie żadnej logiki, ale działają jako ramy dla ludzi

import random
import math
from playerinterface import PlayerInterface

class Player0(PlayerInterface):
    def move(player,g):
        #This dumb player always moves a camel
        return [0]

class Player1(PlayerInterface):
    def move(player,g):
        #This player is less dumb. If they have the least amount of money they'll make a round winner bet
        #If they aren't in last then they'll place a trap on a random square. Still p dumb though
        if min(g.player_money_values) == g.player_money_values[player]:
            return [2,random.randint(0,len(g.camels)-1)]
        return [1,math.floor(2*random.random())*2-1,random.randint(1,10)]

class Player2(PlayerInterface):
    def move(player,g):
        #This dumb player always makes a round winner bet
        return [2,random.randint(0,len(g.camels)-1)]
Tyler Barron
źródło