Простая игра

Более интересной задачей для генетического программирования является создание искусственного интеллекта для игры. Программы можно заставить эволюционировать, принудив их состязаться между собой или с людьми, причем победителям предоставляются более высокие шансы перейти в следующее поколение. В этом разделе мы создадим симулятор для очень простой игры «Погоня» (рис. 11.6).

Два игрока по очереди делают ходы на небольшой расчерченной на клеточки доске. Можно перейти на любую из четырех соседних клеток, но размеры доски ограничены, поэтому игрок, пытающийся выйти за ее пределы, пропускает ход. Цель игры – взять соперника в плен, перейдя в свой ход на ту же клетку, где он сейчас стоит. Налагается лишь одно ограничение – нельзя два раза подряд ходить в одном и том же направлении, иначе будет засчитано поражение. Игра очень простая, но, поскольку в ней сталкиваются интересы двух участников, на ее примере можно изучить конкурентные аспекты эволюции.

Рис. 11.6. Игра «Погоня»

Прежде всего напишем функцию, которая имитирует игру двух участников. Функция попеременно передает каждой программе текущее положение ходящего игрока и его противника, а также последний сделанный ходящим игроком ход и возвращает в качестве результата новый ход.

Ход представляется числом от 0 до 3, обозначающим одно из четырех возможных направлений. Но так как случайные программы могут вернуть любое целое число, функция должна как-то привести результат к допустимому диапазону. Для этого она возвращает остаток от деления полученного числа на 4. Случайная программа может также создать игрока, который будет ходить по кругу, поэтому число ходов ограничивается – после 50 ходов объявляется ничья. Добавьте в файл gp.py функцию gridgame: def gridgame(p):

#       Размер доски max=(3,3)

#       Запоминаем последний ход каждого игрока lastmove=[-1,-1]

#       Запоминаем положения игроков location=[[randint(0,max[0]),randint(0,max[1])]]

#       Располагаем второго игрока на достаточном удалении от первого location.append([(location[0][0]+2)%4,(location[0][1]+2)%4])

#       Не более 50 ходов до объявления ничьей for o in range(50):

# Для каждого игрока for i in range(2):

locs=location[i][:]+location[1-i][:]

locs.append(lastmove[i])

move=p[i].evaluate(locs)%4

#         Если игрок два раза подряд ходит в одном направлении, ему

#         засчитывается проигрыш

if lastmove[i]==move: return 1-i lastmove[i]=move if move==0: location[i][0]-=1 # Доска ограничена

if location[i][0]<0: location[i][0]=0 if move==1: location[i][0]+=1

if location[i][0]>max[0]: location[i][0]=max[0] if move==2: location[i][1]-=1

if location[i][1]<0: location[i][1]=0 if move==3: location[i][1]+=1

if location[i][1]>max[1]: location[i][1]=max[1]

# Если противник захвачен в плен, вы выиграли if location[i]==location[1-i]: return i return -1

Программа возвращает 0, если выиграл первый игрок, 1 – если второй, и -1 – в случае ничьей. Попробуем создать две случайные программы и заставим их сыграть между собой: >>> reload(gp)

<module ‘gp’ from ‘gp.py’> >>> p1=gp.makerandomtree(5) >>> p2=gp.makerandomtree(5) >>> gp.gridgame([p1,p2])

1

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

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100