Бот для Spacewar PPCG KotH

Я написал бота для программирующих головоломок & Код Gold Задача типа «Кинг Хилл» называется «Spacewar!» . Задача была написана @ El'endiaStarman. Бот называется «Шпион».

Контроллер размещен здесь , поэтому взгляните на ощущение. API немного длиннее, поэтому вот ссылка.

Логика бота:

  

Он убегает от другого бота с 70-процентной вероятностью стрельбы ракетой и гиперпространствами, когда он близок к солнцу.

Он еще не в сети у отдельного бота; поэтому вы можете скопировать код здесь в текстовую область контроллера KotH внизу, чтобы протестировать это из.

Я просто просто обезглавил этот бот вместе без IDE, поэтому код не так уж хорош. Серьезно, есть даже дополнительная функция, которую я не использовал.

Код

function Spy_setup(team) {
  // Typical setup. Nothing to see here. ;)
  var botVars = {};
  botVars["color"] = team;
  return botVars;
}


function Spy_getActions(gameInfo, botVars) {
    var actions = [];
    var us, them, red = {
            rotation: gameInfo.red_rot,
            x: gameInfo.red_x,
            y: gameInfo.red_y,
            alive: gameInfo.blue_alive
        },
        blue = {
            rotation: gameInfo.blue_rot,
            x: gameInfo.blue_x,
            y: gameInfo.blue_y,
            alive: gameInfo.blue_alive
        };
    if (botVars.color == "red") {
        us = red;
        them = blue;
    } else if (botVars.color == "blue") {
        us = blue;
        them = red;
    }

    function distance(x1, y1, x2, y2) {
        return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    }

    // Get our ship's position
    var rotation, x, y, opponentAlive;
    if (botVars.color == "red") {
        rotation = gameInfo.red_rot;
        x = gameInfo.red_x;
        y = gameInfo.red_y;
        opponentAlive = gameInfo.blue_alive;
    } else if (botVars.color == "blue") {
        rotation = gameInfo.blue_rot;
        x = gameInfo.blue_x;
        y = gameInfo.blue_y;
        opponentAlive = gameInfo.red_alive;
    }

    // Calculate our rotation compared to the sun in degrees
    var sunX = gameInfo.sun_x,
        sunY = gameInfo.sun_y,
        angle = Math.atan2(sunY - y, sunX - x) * 180 / Math.PI,
        rotationToSun = (rotation - angle + 360) % 360;

    // Check if we need to hyperspace to avoid the sun
    var rX = x - sunX,
        rY = y - sunY,
        distanceFromSun = Math.sqrt(rX * rX + rY * rY) - gameInfo.sun_r;
    if (distanceFromSun < 30) {
        actions.push("hyperspace");
        console.log("Command Module is Hyperspacing.")
    }
    if (gameInfo[botVars["color"] + "_alive"]) {
        var angle = Math.degrees(Math.atan2(them.y - us.y, them.x - us.x)),
            rotationToOpponent = (us.rotation - angle + 360) % 360;
        if (rotationToOpponent > 90 && rotationToOpponent < 270) {
            actions.push("turn right");
        } else {
            actions.push("turn left");
        };
        actions.push("fire engine");
        if (Math.random() > 0.3) {
            actions.push("fire missile")
        }
    }
}
8 голосов | спросил noɥʇʎԀʎzɐɹƆ 18 J000000Monday16 2016, 17:13:06

1 ответ


12

Ошибки

var us, them, red = {
        rotation: gameInfo.red_rot,
        x: gameInfo.red_x,
        y: gameInfo.red_y,
        alive: gameInfo.blue_alive
    },
    blue = {
        rotation: gameInfo.blue_rot,
        x: gameInfo.blue_x,
        y: gameInfo.blue_y,
        alive: gameInfo.blue_alive
    };

Красный и синий используют одну и ту же переменную alive.

Также ...

if (distanceFromSun < 30) {
    actions.push("hyperspace");
    console.log("Command Module is Hyperspacing.")
}
if (gameInfo[botVars["color"] + "_alive"]) {

Я не думаю, что мертвые корабли должны быть гиперпространства.

Licensing

Когда вы используете код из StackExchange, например, этот ответ на PPCG , вы должны как минимум добавить комментарий, ссылающийся на исходный источник.

Дублирование

Не глядя на код подробно, я вижу этот бит дублирования:

var rotation, x, y, opponentAlive;
if (botVars.color == "red") {
    rotation = gameInfo.red_rot;
    x = gameInfo.red_x;
    y = gameInfo.red_y;
    opponentAlive = gameInfo.blue_alive;
} else if (botVars.color == "blue") {
    rotation = gameInfo.blue_rot;
    x = gameInfo.blue_x;
    y = gameInfo.blue_y;
    opponentAlive = gameInfo.red_alive;
}
if (gameInfo[botVars["color"] + "_alive"]) {

Вы должны выбрать один стиль и придерживаться его. Я думаю, вы могли бы избавиться от большого количества дублирования, используя второй стиль:

var rotation, x, y, opponentAlive;
rotation = gameInfo[botVars.color + "_rot"];
x = gameInfo[botVars.color + "_x"];
y = gameInfo[botVars.color + "_y"];

Останавливает нас с переменной opponentAlive.

Для этого я бы просто пошел с функцией getOppositeColor:

function getOppositeColor(ownColor){
    return ownColor === "blue" ? "red" : "blue";
}

И тогда мы можем получить opponentAlive через

opponentAlive = gameInfo[getOppositeColor(botVars.color) + "_alive"];

Другие странные вещи в вашем коде - это то, что вы явно объявляете функцию distance ... и тогда вы ее не используете. Вы создаете объекты для red и blue, но вы не используете их, а затем извлекаете значения из gameInfo второй раз ...

Вы должны получить переменные один раз. Затем используйте их. Сделайте один поток таким образом.

var actions = [];
var us, them, red = {
        rotation: gameInfo.red_rot,
        x: gameInfo.red_x,
        y: gameInfo.red_y,
        alive: gameInfo.red_alive
    },
    blue = {
        rotation: gameInfo.blue_rot,
        x: gameInfo.blue_x,
        y: gameInfo.blue_y,
        alive: gameInfo.blue_alive
    };
if (botVars.color == "red") {
    us = red;
    them = blue;
} else if (botVars.color == "blue") {
    us = blue;
    them = red;
}

Эта часть в этом отношении совершенно прекрасна.

var rotation, x, y, opponentAlive;
if (botVars.color == "red") {
    rotation = gameInfo.red_rot;
    x = gameInfo.red_x;
    y = gameInfo.red_y;
    opponentAlive = gameInfo.blue_alive;
} else if (botVars.color == "blue") {
    rotation = gameInfo.blue_rot;
    x = gameInfo.blue_x;
    y = gameInfo.blue_y;
    opponentAlive = gameInfo.red_alive;
}

Вся эта часть может идти. Это не нужно. У вас уже есть все эти переменные как us.rotation, us.x, us.y и them.alive .


    if (rotationToOpponent > 90 && rotationToOpponent < 270) {
        actions.push("turn right");
    } else {
        actions.push("turn left");
    };

Кроме того, вам не нужна точка с запятой, чтобы закончить этот if-statement здесь.

ответил Pimgd 18 J000000Monday16 2016, 17:29:12

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132