mishelen
2/9/2017 - 12:09 AM

Node Test Task

Node Test Task

const WebSocket = require('ws');

const ws = new WebSocket('ws://nuclear.t.javascript.ninja');

const coincidences = {};
const states = {};
const historyLimit = 5;

ws.on('open', () => console.log('Launched'));
ws.on('error', e => console.log(e));
ws.on('message', data => {
    const response = JSON.parse(data);
    console.log(response);

    if (response.action == "check") initiateCoincedense(response.stateId, response.lever2, response.same);

    if (Number.isInteger(response.pulled)) {
        if (Object.keys(states).length) {
            updateState(response.stateId, response.pulled);
        } else {
            updateCoincedense(response.stateId, response.pulled);
            let fillUp = coincidences[response.stateId].indexOf(null);
            fillUp !== -1 && requestCoincedense(response.stateId, fillUp + 1);
        }
    }

    if (response.newState == "poweredOff") ws.close();
});

function powerOff(stateId) {
    if (Object.keys(states).length === 0) {
        // other data structure initiation for probable next switch
        states[stateId] = [false, false, false, false];
    }

    ws.send(JSON.stringify({action: "powerOff", stateId}));
}

function check(hash, stateId) {
    if (hash[stateId].every(i => i === true)) powerOff(stateId);
}

function requestCoincedense(stateId, lever2) {
    // 1th leverage is determinant
    ws.send(JSON.stringify({action: "check", "lever1": 0, lever2, stateId}));
}

function initiateCoincedense(stateId, lever2, same) {
    coincidences[stateId][lever2 - 1] = same;
    if (Object.keys(coincidences[stateId]).length === 3) check(coincidences, stateId);
}

function updateCoincedense(stateId, pulled) {
    let newState;

    if (Object.keys(coincidences).length === 0) {
        // initiation
        coincidences[stateId] = [null, null, null];
        return;
    } else {
        newState = coincidences[stateId - 1].slice();
        delete coincidences[stateId - historyLimit];
    }

    if (pulled == 0) {
        coincidences[stateId] = newState.map(i => i === null ? null : !i);
    } else {
        newState[pulled - 1] = newState[pulled - 1] === null ? null : !newState[pulled - 1];
        coincidences[stateId] = newState;
        check(coincidences, stateId);
    }
}

function updateState(stateId, pulled) {
    const newState = states[stateId - 1].slice();
    newState[pulled] = !newState[pulled];
    delete states[stateId - historyLimit];
    states[stateId] = newState;
    check(states, stateId);
}