private void step()

in Minecraft/src/main/java/com/microsoft/Malmo/Client/MalmoEnvServer.java [359:483]


    private void step(String command, Socket socket, DataInputStream din) throws IOException {

        String actions = command.substring(stepTagLength, command.length() - (stepTagLength + 2));
        int options =  Character.getNumericValue(command.charAt(stepTagLength - 2));
        boolean withTurnkey = options < 2;
        boolean withInfo = options == 0 || options == 2;
        // TCPUtils.Log(Level.FINE,"Command (step action): " + actionCommand + " options " + options);

        byte[] stepTurnKey;
        if (withTurnkey) {
            int hdr;
            hdr = din.readInt();
            stepTurnKey = new byte[hdr];
            din.readFully(stepTurnKey);
        } else {
            stepTurnKey = new byte[0];
        }

        DataOutputStream dout = new DataOutputStream(socket.getOutputStream());
        double reward = 0.0;
        boolean done;
        byte[] obs;
        String info = "";
        byte[] currentTurnKey;
        byte[] nextTurnKey;
        boolean sent = false;

        lock.lock();
        try {

            done = envState.done;

            obs = getObservation(done);

            // If done or we have new observation and it's our turn then submit command and pick up rewards.

            currentTurnKey = envState.turnKey.getBytes();
            boolean outOfTurn = true;
            nextTurnKey = currentTurnKey;

            if (!done && obs.length > 0 && actions != "") {
                // CurrentKey   StepKey     Action (WithKey)    nextTurnKey     outOfTurn
                // ""           ""          Y                   Current         N
                // ""           X           N                   Step            Y
                // X            0           N                   Current         Y
                // X            X           Y (WK)              Current         N
                // X            Y           N                   Current         Y

                // TCPUtils.Log(Level.FINE, "current TK " + envState.turnKey + " step TK " + new String(stepTurnKey));
                if (currentTurnKey.length == 0) {
                    if (stepTurnKey.length == 0) {
                        if (actions.contains("\n")) {
                            String[] cmds = actions.split("\\n");
                            for(String cmd : cmds) {
                                envState.commands.add(cmd);
                            }
                        } else {
                            if (!actions.isEmpty())
                                envState.commands.add(actions);
                        }
                        outOfTurn = false;
                        sent = true;
                    } else {
                        nextTurnKey = stepTurnKey;
                    }
                } else {
                    if (stepTurnKey.length != 0) {
                        if (Arrays.equals(currentTurnKey, stepTurnKey)) {
                            // The step turn key may later still be stale when picked up from the command queue.
                            envState.commands.add(new String(stepTurnKey) + " " + actions);
                            outOfTurn = false;
                            envState.turnKey = "";
                            envState.lastTurnKey = new String(stepTurnKey);
                            sent = true;
                        }
                    }
                }
            }

            if (done || (obs.length > 0 && !outOfTurn)) {
                // Pick up rewards.
                reward = envState.reward;
                envState.reward = 0.0;
                if (withInfo) {
                    info = envState.info;
                    envState.info = "";
                    if (info.isEmpty() && !done) {
                        try {
                            cond.await(COND_WAIT_SECONDS, TimeUnit.SECONDS);
                        } catch (InterruptedException ie) {
                        }
                        info = envState.info;
                        envState.info = "";
                        if (envState.obs != null && envState.obs != obs) {
                            // Later observation.
                            obs = envState.obs;
                        }
                    }
                }
                envState.obs = null;
            }
        } finally {
            lock.unlock();
        }

        dout.writeInt(obs.length);
        dout.write(obs);

        dout.writeInt(BYTES_DOUBLE + 2);
        dout.writeDouble(reward);
        dout.writeByte(done ? 1 : 0);
        dout.writeByte(sent ? 1 : 0);

        if (withInfo) {
            byte[] infoBytes = info.getBytes(utf8);
            dout.writeInt(infoBytes.length);
            dout.write(infoBytes);
        }

        if (withTurnkey) {
            dout.writeInt(nextTurnKey.length);
            dout.write(nextTurnKey);
        }
        dout.flush();
    }