Если вы когда-нибудь играли в Spacewar! Знаешь, это была веселая игра. Если нет, знайте: это была (и есть) одна из самых первых и самых важных компьютерных игр. И это все еще весело! Клон, на котором я вырос, - это , по-видимому, и, к сожалению, только Windows. Так я его воссоздал!
KotH находится здесь: PPCG - Spacewar! Король горы . Я призываю вас играть как человек против хотя бы одного другого бота, чтобы понять, как работает игра.
Игра
- Один кадр составляет 30 миллисекунд (таким образом, около 33 кадров в секунду).
- Поле имеет ширину 800 пикселей и высоту 600 пикселей.
- Поле является тороидальным, что означает, что космические корабли и ракеты, которые движутся за пределами поля, вновь появляются на противоположной стороне.
- Есть два космических корабля, красный и синий.
- Красный расположен при x = 50, а случайный y между 50 (высота поля - 50) пикселей.
- Синий расположен в точке x = (ширина поля - 50) и случайным образом y между 50 (высота поля - 50) пикселей.
- Обе грани х = (ширина поля) / 2.
- Доступные элементы управления:
- Поверните налево - 5 градусов на кадр против часовой стрелки.
- Поверните направо - 5 градусов на кадр по часовой стрелке.
- Ракета огня - движется с дополнительными 10 пикселями на кадр в дополнение к скорости корабля, в направлении, которое указывал корабль.
- Пожарная машина - ускоряет космический корабль со скоростью 0,30 пикселя за кадр в направлении, указанном космическим кораблем.
- Гиперпространственный прыжок - телепортируется на случайные координаты в поле с вероятностью взрыва 25%. Эти случайные координаты могут быть на вершине солнца.
- Максимальная скорость для кораблей составляет 15 пикселей на кадр при мощности двигателя и 40 пикселей на кадр при усилении силы тяжести.
- При движении быстрее 15 пикселей на кадр, тяга двигателя может только изменить направление или замедлить.
- Что касается ракет:
- Ракеты движутся по прямой.
- Ракеты могут быть запущены с максимальной скоростью 1 за 0,1 секунды.
- Срок службы ракеты составляет 2,25 секунды.
- Корабли имеют максимум 20 ракет каждая.
- Ракеты - это точечные частицы внутри.
- В самом центре есть солнце, которое чрезвычайно опасно для вашего корабля. Малейший контакт со смертельным исходом. Это солнце также уничтожает ракеты.
- Солнце имеет гравитацию. Результирующее ускорение составляет 5000 / (расстояние ^ 2) пикселей / кадр ^ 2, где расстояние в пикселях. Космические корабли и ракеты пострадали.
- Оба корабля имеют три зоны удара: нос, левое крыло и правое крыло.
- Удар по носу - это мгновенная смерть.
- Удар по любому из крыльев уменьшает скорость поворота космического корабля и ускорение двигателя вдвое.
- Если оба крыла уничтожены, космический корабль не может маневрировать и может стрелять только ракетами.
- Корабли могут сталкиваться друг с другом.
- Удар нос-нос смертелен для обоих кораблей.
- Удар носового крыла разрушает крыло.
- Удар крыло уничтожает оба крыла.
- Мертвые корабли тверды и заморожены, пока не взорвутся через 1 секунду.
- После того, как погиб хотя бы один корабль, поле сбрасывается через 3 секунды. До тех пор солнце и любые оставшиеся ракеты все еще опасны.
У оригинальной игры также есть смертельные и неразрушимые астероиды, но я не буду включать те.
Правила
- Ваш бот должен быть написан на JavaScript.
- Ваш бот должен ограничить свое решение до 10 миллисекунд. Если я замечу постоянное отставание из-за вашего бота , я дисквалифицирую его и дам вам знать, чтобы вы могли это исправить.
- Боты будут иметь доступ к следующему:
- Ширина поля и высота поля
- Положение и радиус Солнца
- Положение, вращение, скорость, форма, запас ракет и статус в гиперпространстве обоих кораблей
- Положение и скорость всех ракет
- При появлении запроса ваш бот должен вернуть список строк.
- Эти строки должны быть один из следующих:
turn left
,turn right
,fire engine
,fire missile
,hyperspace
. Любая другая строка будет проигнорирована. - Если есть какие-либо дубликаты, будет отмечен только первый.
hyperspace
имеет приоритет над всеми остальными.turn left
иturn right
в то же время не будет иметь никакого эффекта.fire engine
не будет иметь никакого эффекта, если у корабля только нос или он мертв.fire missile
не будет иметь эффекта, если ракета будет запущена слишком недавно.
- Эти строки должны быть один из следующих:
- В отличие от обычного, ваш бот может использовать поведение других ботов. Я хочу поощрять метагейм.
- Боты не могут эмулировать других ботов. (Т.е. нет чтения мыслей.)
- Боты не могут устанавливать переменные, используемые в игровом и физическом коде. (Т.е. без обмана.)
Детали реализации бота
Я буду хранить вашего бота в его собственном файле JavaScript, который автоматически включается вместе с именем файла bot_<name>.js
. Так что не ставьте пробелы или символы, которые мешали бы этому или именовали функцию в JavaScript. Это потому, что вы должны определить следующие функции: <name>_setup(team)
и <name>_getActions(gameInfo, botVars)
. Далее вниз по странице есть текстовые области для userbot , которые вы можете редактировать для проверки своего кода.
<name>_setup(team)
Эта функция предназначена для определения любых переменных, которые вы хотите сохранить. team
будет либо "red"
или "blue"
. Эта функция должна возвращать объект. Определите переменные следующим образом:
var vars = {};
vars['example'] = "example";
return vars;
Этот vars
объект будет передан другой функции:
<name>_getActions(gameInfo, botVars)
botVars
это объект , возвращаемый <name>_setup(team)
. gameInfo
является объектом, содержащим следующие переменные:
redScore
blueScore
timeLeft
fieldWidth
fieldHeight
sun_x
sun_y
sun_r //sun's radius
gravityStrength //acceleration in pixels/frame^2 at 1 pixel away from the sun's center
engineThrust //acceleration in pixels/frame^2
speedLimit //maximum speed under engine power
maxSpeed //maximum speed from gravity boosts
red_x
red_y
red_rot //rotation in degrees
red_xv //x velocity
red_yv //y velocity
red_shape //one of "full ship", "left wing", "right wing", "nose only"
red_missileStock //the number of missiles red has left
red_inHyperspace //true if red is in hyperspace
red_exploded //until red explodes, it is still solid and hazardous
red_alive
// likewise for blue //
numMissiles
missiles //this is a list of objects, each with the following variables
x
y
xv
yv
Ваш бот имеет полный доступ к ним. Я уверен, что вы можете писать в них и не влиять на исходные переменные, но все равно не делайте этого. Примечание о поворотах: точка корабля в направлении + y вниз, поэтому все, что вы хотите выровнять с кораблем, должно быть смещено на 90 градусов. Кроме того, положительное вращение по часовой стрелке.
Эта функция должна возвращать список строк, представляющих действия вашего бота. Например, ["turn right","thrust"]
. Подробнее об этом в разделе « Правила ».
дополнительные детали
Вы также можете использовать следующее:
LineIntersection(L1, L2)
L1 и L2 - двухэлементные массивы из двухэлементных массивов. То есть L1 := [[x1,y1],[x2,y2]]
и L2 := [[u1,v1],[u2,v2]]
. Эта функция вычисляет пересечение двух линий и возвращает это: [[x,y], [a,b]]
. [x,y]
являются координатами точки пересечения и [a,b]
представляют собой пару соотношений, которые выражают, как далеко вдоль каждой линии находится точка пересечения. Как и в, a = 0.25
будет означать, что точка пересечения четверть пути от [x1,y1]
к [x2,y2]
, и также для b
. Если пересечения нет, возвращается пустой массив.
window["shipShapes"]
var shipShapes = {
'full ship': [[-8,16],[0,-8],[8,16]],
'left wing': [[-8,16],[0,-8],[4,4],[0,8],[0,16]],
'right wing':[[-4,4],[0,-8],[8,16],[0,16],[0,8]],
'nose only': [[-4,4],[0,-8],[4,4],[0,8]]
};
Это координаты полигонов кораблей. Чтобы упростить получение текущих координат, вы также можете использовать ...
getShipCoords(<color>)
getShipCoords("red")
вернет текущие координаты вершин корабля Красного, а также для getShipCoords("blue")
и Blue. Эти координаты в списке , как так: [[x1,y1],[x2,y2],[x3,y3],...]
. Полигоны неявно замкнуты, поэтому между первой и последней парами координат есть линия.
Вы не можете получить доступ или изменять любые другие переменные или функции, используемые игрой / веб-сайтом. И определенно не называйте ваши функции одинаковыми. Я не предвижу, что это будет проблемой, но если ваш бот нарушает код игры, это одна из возможностей. Нет регистрации или отлова исключений.
выигрыш
- Каждое соединение ботов должно быть сыграно не менее 10 раз в обе стороны. (Итого минимум 20 игр.)
- Старайтесь иметь самые высокие коэффициенты выигрыша / проигрыша в целом . Если ваш бот отлично справляется с одним другим ботом, но проигрывает против трех других, это не так хорошо, как выигрывать против двух и проигрывать против двух (как общее правило).
- Для каждого бота будут рассчитаны соотношения (выигрыши + 1) / (проигрыши + 1), а затем будет вычислено среднее и стандартное отклонение этих соотношений. Более высокое среднее значение будет иметь приоритет, и если средние значения находятся в пределах 1 единицы друг от друга, более низкая дисперсия будет иметь приоритет.
- Оценка начнется либо через неделю с сегодняшнего дня, либо через три дня после новых заявок. Это так, что мне не нужно повторять спаривание ботов.
Прежде всего, получайте удовольствие!
Таблица лидеров (2016-01-08 05:15):
# Name Mean StdDev
1. Helios 13.625 6.852
2. EdgeCase 8.335 8.155
3. OpponentDodger 8.415 8.186
4. OrbitBot 5.110 6.294
5. SunAvoider 5.276 6.772
6. DangitBobby 3.320 4.423
7. SprayAndPray 3.118 4.642
8. Engineer 3.903 6.315
9. RighthandedSpasms 1.805 2.477
10. AttackAndComeBack 2.521 2.921
11. PanicAttack 2.622 3.102
12. FullSpeedAhead 2.058 3.295
13. UhhIDKWhatToCallThisBot 2.555 3.406
14. MissilesPlusScore 0.159 0.228
15. Hyper 0.236 0.332
16. RandUmmm 0.988 1.329
17. Kamikaze 0.781 1.793
Примечание: это может измениться, поскольку я запускаю больше игр. Кроме того, порядок рангов 9-13 беспокоит меня, поэтому я могу настроить метод подсчета очков, чтобы он лучше соответствовал интуиции о том, как их оценивать.
(Значения и стандартные отклонения были округлены до трех десятичных цифр. Кроме того, Hyper
должно быть, HYPER
но это портит подсветку.: P)
LineIntersection
непересекающихся сегментов возвращает пустой массив.