2017-02-14 2 views
0

Я пытаюсь создать Netlogo для моделирования игры 2048 года. Я реализовал три эвристические функции, определяемые параметрами веса, и хочу использовать пространство поведения для запуска моделирования и проверить, какая стратегия является лучшей для победы в этой игре.NetLogo: 2048 bot optimization

Процедура поиск использует примитивы export/import-world для поиска возможных ходов и выбирает ход, для которого эвристическая функция имеет наибольшее значение.

Проблема в том, что эта процедура выполняется очень медленно (из-за функции import-world, которая называется четыре раза за каждый ход). Есть ли у вас какие-либо идеи, как реализовать это без экспорта и импорта мира так часто?

Это проект для моего введения в класс AI. Это происходит через пару дней, и я не могу найти никаких решений.

Соответствующая часть кода приведена ниже. Процедуры move- (direction) все исправно и изменено подвижное? истинно, если квадрат может двигаться в указанном направлении и false в противном случае. Он проверяется в процедуре подвижный чек по телефону переезд- (направление).

Я был бы очень признателен за вашу помощь. :)

to search 

    let x 0 
    let direction "down" 

    export-world "state.csv" 
    move-up 
    ifelse not any? squares with [moveable?] 
    [set h-value -5000] 
    [set x h-value 
    set direction "up" 
    import-world "state.csv"] 


    export-world "state.csv" 
    move-down 
    ifelse not any? squares with [moveable?] 
    [set h-value -5000] 
    [if h-value > x 
     [set x h-value 
     set direction "down"] 
    import-world "state.csv"] 


    export-world "state.csv" 
    move-left 
    ifelse not any? squares with [moveable?] 
    [set h-value -5000] 
    [if h-value > x 
     [set x h-value 
     set direction "left"] 
    import-world "state.csv"] 

    export-world "state.csv" 
    move-right 
    ifelse not any? squares with [moveable?] 
    [set h-value -5000] 
    [if h-value > x 
     [set x h-value 
     set direction "right"] 
    import-world "state.csv"] 

    ifelse direction = "up" 
    [move-up 
     print "up"] 
    [ifelse direction = "down" 
     [move-down 
     print "down"] 
     [ifelse direction = "right" 
     [move-right 
      print "right"] 
     [move-left 
      print "left"]]] 
    if not any? squares with [moveable?] 
    [ 
     ask squares [set heading heading + 90] 
     moveable-check 
     if not any? squares with [moveable?] 
      [ask squares [set heading heading + 90] 
      moveable-check 
      if not any? squares with [moveable?] 
       [ask squares [set heading heading + 90] 
       moveable-check 
       if not any? squares with [moveable?] 
        [stop]]] 
     ] 
end 

ответ

0

Самая важная и сложная информация, которую вы должны сохранить и восстановить, - это квадраты. Это довольно легко сделать без import-world и export-world (обратите внимание, что следующий синтаксис использует NetLogo 6, если вы все еще на NetLogo 5, вы должны будете использовать старый синтаксис задачи в foreach):

to-report serialize-state 
    report [(list xcor ycor value)] of squares 
end 

to restore-state [ state ] 
    clear-squares 
    foreach state [ [sq] -> 
    create-squares 1 [ 
     setxy (item 0 sq) (item 1 sq) 
     set heading 0 ;; or whatever 
     set value item 2 sq 
    ] 
    ] 
end 

value выше показывает, как хранить произвольные переменные ваших квадратов. Я не уверен, какие данные вы связали с ними или вам нужно восстановить. Идея этого кода заключается в том, что вы сохраняете информацию о квадратах в списке списков, где каждый внутренний список содержит данные для одного квадрата. Таким образом, вы используете это:

let state serialize-state 
;; make changes to state that you want to investigate 
restore-state state 

Возможно, вам потребуется хранить некоторые глобалы и такие, как хорошо. Они могут храниться в локальных переменных или в списке state (что более общее, но сложнее реализовать).

Несколько другие идеи:

  • Прямо сейчас это выглядит как будто вы только ищете одно состояние вперед, и только в одном возможном положении на новой площади, который будет размещен (убедитесь, что вы не обманывая, знаете, где именно будет новый квадрат). В конце концов, вы можете сделать произвольный взгляд вперед, используя вид дерева поиска. Это дерево становится действительно очень быстрым. Если вы это сделаете, вы захотите использовать стратегии обрезки, такие как: https://en.wikipedia.org/wiki/Alpha%E2%80%93beta_pruning. Кроме того, это делает процесс восстановления состояния более сложным, но все же выполнимым. Вы будете хранить стек состояний, а не одно состояние.
  • Вместо set heading heading + 90 вы можете просто сделать right 90 или rt 90.