Wyzwanie polega na napisaniu funkcji minimaksa w wybranym języku, aby wygenerować następny najlepszy ruch w grze kółko i krzyżyk NxN, biorąc pod uwagę bieżący stan planszy . Dane wejściowe na planszy można zaakceptować jako Matrycę, kolekcję 2D lub cokolwiek innego, co ma dla ciebie sens, ale jest zgodne z zasadami . Wyjście jest kolejnym najlepszym ruchem dla każdej tury , w której aktualnie się znajduje , gdzie X uważa się za rozpoczęty .
Szybkie wprowadzenie do algorytmu minimax
Podstawową ideą algorytmu minimax jest wyliczenie wszystkich możliwych wyników jako DAG, a następnie zważenie ich według korzyści, jaką sekwencja ruchów ma dla gracza, kluczowana przez pierwszy wykonany ruch. Wszystkie możliwe wyniki są następnie „przenoszone” przez pierwszy ruch i są oceniane na podstawie sumy wszystkich wyników (-1 dla przegranej, 0 dla remisu i 1 dla wygranej). W implementacjach wymagających gry wielu graczy, wyliczasz wszystkie możliwe ruchy gracza oraz wszystkie możliwe reakcje przeciwników. Na przykład w grze w kółko i krzyżyk (po pierwszym ruchu) istnieje 8 możliwych pierwszych ruchów, które można wykonać, i wszystkie mogą wydawać się równe, gdy analizuje się tylko kolejną turę. Ale powtarzając wszystkie możliwe wyniki dla każdego możliwego zestawu ruchów, które dają wynik końcowy i sumując je wszystkie,
Aby uzyskać lepsze, bardziej szczegółowe i kontekstowe podsumowanie algorytmu mini-max w kategoriach kółko i krzyżyk, przeczytaj więcej tutaj: http://neverstopbuilding.com/minimax
XKCD (tylko rozwiązanie 3x3)
Zasady
- Można użyć dowolnego języka, ale nie są dozwolone żadne zewnętrzne biblioteki minimax.
- Wyjściem może być współrzędna (0-n, 0-n) lub liczba (1-n * n) wskazująca najlepszy następny ruch.
- Oprócz tego musisz być w stanie określić, kiedy najlepszym scenariuszem jest przegrana lub remis zamiast wygranej.
- Sposób, w jaki określasz stratę lub remis, zależy od Ciebie.
- Dane wejściowe muszą wykorzystywać tradycyjne X i O, a najpierw musisz założyć X ruchów; puste miejsca mogą być reprezentowane przez dowolne.
- Możesz założyć, że wszelkie dane wejściowe do twojego programu mają n O i n + 1 X, innymi słowy możesz założyć, że otrzymujesz dobrze uformowaną płytę.
- Obecny stan płytki musi być jedynym wejściem do twojego programu, jeśli używasz rekurencji, musisz zastosować metody pomocnicze, aby ułatwić wprowadzenie danych. Zobacz /codegolf//a/92851/59376 o wyjaśnienie.
- Każda wartość 10> = n> = 1 musi być obsługiwana; jeśli twój program „przekroczy limit czasu” dla n> 10, uważam to również za dopuszczalne, ponieważ niektóre języki mają znacznie niższą moc przetwarzania (szczególnie przy użyciu konsol obsługujących strony internetowe).
Osądzać
- Jest to gra w golfa kodowego, więc najniższa liczba bajtów w programie wygrywa, a standardowe luki są ogólnie zabronione.
- W przypadku remisu wygrywa program obsługujący największe „n”.
Przykładowe dane wejściowe
2x2
[[X,O]
[-,-]]
Dane wyjściowe: 2 lub [0,1] (3 lub [1,1] również byłyby prawdopodobnie poprawne) (Pewna forma wskazania lokalizacji, dowolna, o ile można łatwo wyjaśnić użyty format)
3x3
[[X,O,X]
[O,X,-]
[-,-,-]]
Wyjście: -1 (strata)
Ponownie dozwolony jest dowolny żądany format wejściowy, ale należy użyć znaków X i O, podane przykłady nie miały ograniczać się do tego formatu, a jedynie inspirować.
źródło
Odpowiedzi:
Perl,
10198 bajtówObejmuje
+4
dla-0p
Uruchom z wejściem na STDIN
Wyjście jest tym samym diagramem, ale przy każdym ruchu aktualizowanym o swój status,
1
reprezentuje wygraną,2
reprezentuje remis i3
reprezentuje stratę. W tym przypadku byłoby towięc 3 ruchy losują, 1 wygrywają i 1 przegrywają (zaktualizuję rozwiązanie, jeśli ten format wyjściowy jest niedopuszczalny, ale podstawowy kod pozostanie taki sam)
tictactoe.pl
:Jest to już boleśnie powolne i zużywa dużo pamięci dla pustej płyty 3 * 3 (dlaczego tak naprawdę rekurencja nie jest tak głęboka. Musi być jakiś wyciek pamięci). Dodanie zapamiętywania kosztuje 6 bajtów, ale jest znacznie rozsądniejsze:
źródło
do$0
spowodowałoby zużycie 10 razy mniej pamięci. Pamiętaj, że ten przypadek jest tak ekstremalny, że może to być prawdziwy wyciek pamięci.JavaScript (ES6),
320294 bajtówWejście
1) Tablica tablic znaków opisujących aktualną planszę, takich jak:
2) Liczba całkowita opisująca aktualny zwrot: 1 =
X
, -1 =O
Wynik
Tablica wykonana z:
[x, y]
formaciePrzykład
W poniższym przykładzie
X
wygrana jest gwarantowana poprzez grę[1, 2]
.Dziwna gra. JEDYNIE WYGRYWAJĄCE RUCHY NIE SĄ GRAĆ.
JAK O ŁADNEJ SZACHY?
źródło
The current state of the board must be the only input to your program
. Twój kod wymaga dwóch danych wejściowych, co łamie tę zasadę.