void ALEAgentHost::sendCommand()

in Malmo/src/ALEAgentHost.cpp [246:374]


    void ALEAgentHost::sendCommand(std::string command)
    {
        /*
            PLAYER_A_NOOP           = 0,
            PLAYER_A_FIRE           = 1,
            PLAYER_A_UP             = 2,
            PLAYER_A_RIGHT          = 3,
            PLAYER_A_LEFT           = 4,
            PLAYER_A_DOWN           = 5,
            PLAYER_A_UPRIGHT        = 6,
            PLAYER_A_UPLEFT         = 7,
            PLAYER_A_DOWNRIGHT      = 8,
            PLAYER_A_DOWNLEFT       = 9,
            PLAYER_A_UPFIRE         = 10,
            PLAYER_A_RIGHTFIRE      = 11,
            PLAYER_A_LEFTFIRE       = 12,
            PLAYER_A_DOWNFIRE       = 13,
            PLAYER_A_UPRIGHTFIRE    = 14,
            PLAYER_A_UPLEFTFIRE     = 15,
            PLAYER_A_DOWNRIGHTFIRE  = 16,
            PLAYER_A_DOWNLEFTFIRE   = 17,
         */
        Action a = (Action)::atoi(command.c_str());

        boost::posix_time::ptime ts = boost::posix_time::microsec_clock::universal_time();
        std::string timestamp = boost::posix_time::to_iso_string(ts);
        this->commands_stream << timestamp << " " << command << std::endl;
        float reward = this->ale_interface->act(a);
        onReward( ts, reward );

        // Get the video frame:
        const ALEScreen& screen = this->ale_interface->getScreen();

        // Create a TimestampedVideoFrame for our own use:
        TimestampedVideoFrame tsframe;
        tsframe.timestamp = ts;
        tsframe.channels = 3;
        tsframe.width = this->requested_width;
        tsframe.height = this->requested_height;

        int actual_width = screen.width();
        int actual_height = screen.height();

        int pixels = requested_width * requested_height;
        tsframe.pixels.resize(3 * pixels);
        // AleInterfrace.getScreenRGB has a stupid bug whereby it only returns the top third of the screen,
        // so we need to do this manually.
        // We also do the scaling at the same time, using nearest-neighbour for speed.
        double actual_to_requested_height = (double)requested_height / (double)actual_height;
        double actual_to_requested_width = (double)requested_width / (double)actual_width;
        double requested_to_actual_height = (double)actual_height / (double)requested_height;
        double requested_to_actual_width = (double)actual_width / (double)requested_width;

        if (actual_height < requested_height)
        {
            // Scaling up:
            for (int dsty = 0; dsty < requested_height; dsty++)
            {
                int srcy = (int)((double)dsty * requested_to_actual_height);

                if (actual_width < requested_width)
                {
                    // Scaling up:
                    for (int dstx = 0; dstx < requested_width; dstx++)
                    {
                        int srcx = (int)((double)dstx * requested_to_actual_width);
                        unsigned int pix = this->ale_interface->theOSystem->colourPalette().getRGB(screen.getArray()[srcx + srcy * actual_width]);
                        int i = 3 * (dstx + dsty* requested_width);
                        tsframe.pixels[i] = (unsigned char)(pix >> 16);     // red
                        tsframe.pixels[i + 1] = (unsigned char)(pix >> 8);  // green
                        tsframe.pixels[i + 2] = (unsigned char)pix;         // blue
                    }
                }
                else
                {
                    // Scaling down:
                    for (int srcx = 0; srcx < actual_width; srcx++)
                    {
                        int dstx = (int)((double)srcx * actual_to_requested_width);
                        unsigned int pix = this->ale_interface->theOSystem->colourPalette().getRGB(screen.getArray()[srcx + srcy * actual_width]);
                        int i = 3 * (dstx + dsty* requested_width);
                        tsframe.pixels[i] = (unsigned char)(pix >> 16);     // red
                        tsframe.pixels[i + 1] = (unsigned char)(pix >> 8);  // green
                        tsframe.pixels[i + 2] = (unsigned char)pix;         // blue
                    }
                }
            }
        }
        else
        {
            // Scaling down:
            for (int srcy = 0; srcy < actual_height; srcy++)
            {
                int dsty = (int)((double)srcy * actual_to_requested_height);

                if (actual_width < requested_width)
                {
                    // Scaling up:
                    for (int dstx = 0; dstx < requested_width; dstx++)
                    {
                        int srcx = (int)((double)dstx * requested_to_actual_width);
                        unsigned int pix = this->ale_interface->theOSystem->colourPalette().getRGB(screen.getArray()[srcx + srcy * actual_width]);
                        int i = 3 * (dstx + dsty* requested_width);
                        tsframe.pixels[i] = (unsigned char)(pix >> 16);     // red
                        tsframe.pixels[i + 1] = (unsigned char)(pix >> 8);  // green
                        tsframe.pixels[i + 2] = (unsigned char)pix;         // blue
                    }
                }
                else
                {
                    // Scaling down:
                    for (int srcx = 0; srcx < actual_width; srcx++)
                    {
                        int dstx = (int)((double)srcx * actual_to_requested_width);
                        unsigned int pix = this->ale_interface->theOSystem->colourPalette().getRGB(screen.getArray()[srcx + srcy * actual_width]);
                        int i = 3 * (dstx + dsty* requested_width);
                        tsframe.pixels[i] = (unsigned char)(pix >> 16);     // red
                        tsframe.pixels[i + 1] = (unsigned char)(pix >> 8);  // green
                        tsframe.pixels[i + 2] = (unsigned char)pix;         // blue
                    }
                }
            }
        }
        onVideo(tsframe);

        // Is the game still running, or did we just die?
        if (this->ale_interface->game_over())
            this->close();
    }