Задать вопрос
@ffff567

Как можно еще уменьшить количество комбинаций в игре крестики нолики?

на поле 3 на 4 где надо составить 3 в ряд 48000 комбинаций примерно

на поле 4 на 4 где надо составить 4 в ряд не хватает оперативной памяти компьютера
только с 5 хода можно проанализировать до конца и то комбинаций с 5 хода оклло 12 миллионов.
Может я что то неправильно сделал в коде 4 на 4
на доске 3 на 4 было 1.2 миллирна комбинаций но после того как я ввел в алгоритм проверку на вилку то количество комбинаций уменьшилось до 48000

на доске 4 на 4 я использую тот же самый алгоритм как и на досках меньшего размера.
если есть на доске 2 выигрыша то компьютер сделает ход там где вилка.
68a8d82f47c89725094009.jpeg
def вилка(позиция, hist, zero_index): 
    for num in zero_index:
        поб=0
        rr=позиция.copy()
        rr[num]=глубина
        for num2 in zero_index:
            if num2!=num:
                rr2=rr.copy()
                rr2[num2]=глубина
                for b in адреса[num2]:
                    if all(rr2[ind]%2==очередь and rr2[ind] for ind in b):
                        поб+=1
                        break
        if поб==2: 
            temp_словарь[tuple(rr)]=hist+[num]
            return True
  • Вопрос задан
  • 232 просмотра
Подписаться 1 Простой 9 комментариев
Решения вопроса 1
wataru
@wataru Куратор тега Алгоритмы
Разработчик на С++, экс-олимпиадник.
Состояний сильно больше не из-за 4-х лишних клеток, а потому что теперь для завершения надо собрать не 3 в ряд, а 4 а ряд. Поэтому состояний без вилок/выигрышных ситуаций становится сильно больше, ведь раньше только 2 фишки рядом поставить надо и все, а теперь 3, да еще и в ряд.

Но вообще, какая-то фигня у вас с кодом. Всего различных состояний для поля 3*4: 3^12 = 531441. Это включая невозможные состояния после завершения игры и те, где крестиков сильно больше чем ноликов например. Потому что каждая клетка может иметь 3 варианта (пустая, крестик, нолик). Вот 12 клеток дают 3^12. Вы же там как-то 1.2 миллиона насчитали - более чем в 2 раза больше. На самом деле это раз в 10 больше чем должно быть, если считать только допустимые состояния.

Для 4x4 всего состояний меньше 3^16 = 43миллиона. Это никак не может переполнить память, даже если на каждое состояние выделять по все 16 байт, то это займет едва 700 мегабайт. Даже если в 2 раза умножить на любые дополнительные расходы питоновских словарей, то будет полтора гига.

На таких мелких полях вам вообще никакие эвристики не нужны, все 43 миллиона можно сгенерировать меньше чем за секунду на стареньком процессоре.

А если еще и поле хранить в виде битовой маски, по 2 бита на клетку, то все поле 4x4 займет у вас 32 бита, поместится в обычную интовую переменную. И манипуляциями с битами можно быстро проверять, если где-то 3 в ряд.

Возможно вы не сохраняете вообще найденные поля и поэтому одно и тоже поле обрабатываете кучу раз, если разной последовательностью ходов пришли в него? Вам надо в функции проверки выигрышности сначала проверить, а не обработали ли вы это поле уже, а в конце подсчитанный результат сохранить.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@EDIsaev
Зачем кранить все возможные состояния, если достаточно простенькой эвристики и уже устанешь его обыгрывать?
если очень хочется, можно хранить дерево по 2 бита на всё поле, не зависимо от его размера. Но когда-то всё равно упрёшься в ограничение по памяти
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы