Задать вопрос
  • Как на node js (express) обрабатывать и логировать ошибки?

    lastuniverse
    @lastuniverse
    hOtRush, иди дальше ковыряй PHP. Дивергентное мышление, не твой конек!
  • Чем заменить eval для простых выражений?

    lastuniverse
    @lastuniverse
    dollar, подправил код:

    код
    const Splitter = require("split-tools");
    
    var text = "x > 5 && (y == 7.5) || sin(PI*a/360) || isNumber(y) && true ";
    // var text = "x+-y"; // это тоже работает
    
    
    const splitter = new Splitter({
        matchers: {
            function: /\s*([a-z]\w*)\(\s*(.*)\s*\)/g,
            bracket: /\(\s*(.*)\s*\)/g,
            operator: /\s*(\!|\*|\/|\%|\+|\-|\=\=\=|\!\=\=|\<\=|\<|\>\=|\>|\=\=|\!\=|\&\&|\|\||\&|\|)\s*/g,
            boolean: /\s*(true|false)\s*/gi,
            sting: /\s*\"(.*?)\"\s*/gi,
            variable: /\s*([a-z][\w\.]*)\s*/gi,
            value: /\s*(\d[\d\.]*)\s*/gi
        }
    });
    
    const tree = {
        "brackets": ["function", "bracket", "operator", "boolean", "variable", "sting", "value"]
    };
     
    function subSplit(id, text) {
        console.log("subSplit:", id, "[", text, "]");
        if(tree[id] && tree[id].length)
            return splitter.process(text, tree[id]);
        return text;
    }
     
     
    splitter.addParser("function",(match,name,body)=>{
        return {
            type: "function",
            name: name,
            body: subSplit("brackets", body)
        };
    });
    
    splitter.addParser("bracket",(match,body)=>{
        return {
            type: "bracket",
            body: subSplit("brackets", body)
        };
    });
    
    splitter.addParser("operator",(match,body)=>{
        return {
            type: "operator",
            body: body
        };
    });
    
    splitter.addParser("variable",(match,body)=>{
        return {
            type: "variable",
            body: body
        };
    });
    
    splitter.addParser("string",(match,body)=>{
        return {
            type: "string",
            body: body
        };
    });
    
    splitter.addParser("boolean",(match,body)=>{
        return {
            type: "boolean",
            body: body==="true"?true:false
        };
    });
    
    splitter.addParser("value",(match,body)=>{
        return {
            type: "value",
            body: +body
        };
    });
     
     
    const list = splitter.process(text, tree.brackets);
     
    console.log("\n\nresult:\n",JSON.stringify(list, null, '  '));
    
    
    
    
    
    
    
    // тут я не придумал ничего умнее :)))
    var OPERATOR_PRIORITY = {
        '!': (src, dst)=>{    dst.push({type: "value", body: !src.shift()}) },
        '*': (src, dst)=>{    dst[dst.length-1] = {type: "value",     body: dst[dst.length-1].body*src.shift().body} },
        '/': (src, dst)=>{    dst[dst.length-1] = {type: "value",     body: dst[dst.length-1].body/src.shift().body} },
        '%': (src, dst)=>{    dst[dst.length-1] = {type: "value",     body: dst[dst.length-1].body%src.shift().body} },
        '-': (src, dst)=>{    dst[dst.length-1] = {type: "operator",  body: "+" }; dst.push({type: "value", body: 0-src.shift().body}) },
        '+': (src, dst)=>{    dst[dst.length-1] = {type: "value",     body: dst[dst.length-1].body+src.shift().body} },
        '<': (src, dst)=>{    dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body<src.shift().body?true:false) } },
        '<=': (src, dst)=>{   dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body<=src.shift().body?true:false) } },
        '>': (src, dst)=>{    dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body>src.shift().body?true:false) } },
        '>=': (src, dst)=>{   dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body>=src.shift().body?true:false) } },
        '==': (src, dst)=>{   dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body==src.shift().body?true:false) } },
        '!=': (src, dst)=>{   dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body!=src.shift().body?true:false) } },
        '===': (src, dst)=>{  dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body===src.shift().body?true:false) } },
        '!==': (src, dst)=>{  dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body!==src.shift().body?true:false) } },
        '&': (src, dst)=>{    dst[dst.length-1] = {type: "value",     body: dst[dst.length-1].body&src.shift().body} },
        '|': (src, dst)=>{    dst[dst.length-1] = {type: "value",     body: dst[dst.length-1].body|src.shift().body} },
        '&&': (src, dst)=>{   dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body&&src.shift().body) } },
        '||': (src, dst)=>{   dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body||src.shift().body) } }
    };
    
    
    // это набор разрешенных функций
    var ALLOWED_FUNCTIONS = {
        "sin": (v)=>{ return {type: "value", body: Math.sin(v)} },
        "cos": (v)=>{ return {type: "value", body: Math.cos(v)} },
        "isNumber": (v)=>{ return {type: "boolean", body: !isNaN(parseFloat(v)) && isFinite(v) } }
    };
    // это набор разрешенных переменных
    var ALLOWED_VARIABLES = {
        "PI": Math.PI,
        "x": 6,
        "y": 7.5,
        "a": 180
    };
    
    
    // парсер результатов разбора строки
    function resCalc(src){
    	
        src = src
    	// 	заменяем переменные на их значения
        .map(item=>{
            // если не переменная возвращаем как есть
            if(item.type !== "variable")
                return item;
                
            // иначе преобразуем переменную в ее значение
            // тут надо еще сделать проверку на наличие переменной в списке разрешенных
            const value = ALLOWED_VARIABLES[item.body];
            let type = "value";
            if( typeof value !== "number" ) type = typeof value;
            return {
                type: type,
                body: ALLOWED_VARIABLES[item.body]
            };
        })
    	// 	заменяем функции на их значения
        .map(item=>{
            // если не функция возвращаем как есть
            if(item.type !== "function")
                return item;
            // иначе преобразуем функции в ее значение
            // тут надо еще сделать проверку на наличие функции в списке разрешенных
            return ALLOWED_FUNCTIONS[item.name]( resCalc(item.body).body );
        })
    	// 	заменяем скобки на их значения
        .map(item=>{
            // если не переменная возвращаем как есть
            if(item.type !== "bracket")
                return item;
            // иначе преобразуем содержимое скобки в ее значение
            return resCalc(item.body);
        });
    
        let dst;
        Object.keys(OPERATOR_PRIORITY).forEach(operator=>{
            const _calc = OPERATOR_PRIORITY[operator];
            dst = [];
            while( src.length ){
                const item = src.shift();
                
        		 if(item.type === "operator" && item.body === operator){
                    // если оператор
                    // тут надо еще сделать проверку на наличие обработчика оператора
                    _calc(src, dst);
                }else{
                    // если все остальное
                    dst.push(item);
                }
                
            }
            src = dst;
        });
        return src[0];
    }
    
    console.log("\n\nresult:\n",JSON.stringify(resCalc(list), null, '  '));
    • унарный минус - реализован
    • добавление кастомных функций - реализовано
    • добавление кастомных переменных - реализовано
  • Чем заменить eval для простых выражений?

    lastuniverse
    @lastuniverse
    dollar, Вроде победил, правда для этого пошел путем обхода массива с результатами парсинга строки

    тестовая строка:
    "x > 5 && (y == 7.5) || sin(PI*a/360) || isNumber(y) && true "


    код
    const Splitter = require("split-tools");
    
    var text = "x > 5 && (y == 7.5) || sin(PI*a/360) || isNumber(y) && true ";
    // var text = "x > 5 && (y == 7.5) || sin(PI*a/360)";
    
    const splitter = new Splitter({
        matchers: {
            function: /\s*([a-z]\w*)\(\s*(.*)\s*\)/g,
            bracket: /\(\s*(.*)\s*\)/g,
            operator: /\s*(\!|\*|\/|\%|\+|\-|\=\=\=|\!\=\=|\<\=|\<|\>\=|\>|\=\=|\!\=|\&\&|\|\||\&|\|)\s*/g,
            boolean: /\s*(true|false)\s*/gi,
            sting: /\s*\"(.*?)\"\s*/gi,
            variable: /\s*([a-z][\w\.]*)\s*/gi,
            value: /\s*(\d[\d\.]*)\s*/gi
        }
    });
    
    const tree = {
        "brackets": ["function", "bracket", "operator", "boolean", "variable", "sting", "value"]
    };
     
    function subSplit(id, text) {
        console.log("subSplit:", id, "[", text, "]");
        if(tree[id] && tree[id].length)
            return splitter.process(text, tree[id]);
        return text;
    }
     
     
    splitter.addParser("function",(match,name,body)=>{
        return {
            type: "function",
            name: name,
            body: subSplit("brackets", body)
        };
    });
    
    splitter.addParser("bracket",(match,body)=>{
        return {
            type: "bracket",
            body: subSplit("brackets", body)
        };
    });
    
    splitter.addParser("operator",(match,body)=>{
        return {
            type: "operator",
            body: body
        };
    });
    
    splitter.addParser("variable",(match,body)=>{
        return {
            type: "variable",
            body: body
        };
    });
    
    splitter.addParser("string",(match,body)=>{
        return {
            type: "string",
            body: body
        };
    });
    
    splitter.addParser("boolean",(match,body)=>{
        return {
            type: "boolean",
            body: body==="true"?true:false
        };
    });
    
    splitter.addParser("value",(match,body)=>{
        return {
            type: "value",
            body: +body
        };
    });
     
     
    const list = splitter.process(text, tree.tags);
     
    console.log("\n\nresult:\n",JSON.stringify(list, null, '  '));
    
    
    
    
    // тут я не придумал ничего умнее :)))
    var OPERATOR_PRIORITY = {
        '!': (src, dst)=>{    dst.push({type: "value", body: !src.shift()}) },
        '*': (src, dst)=>{    dst[dst.length-1] = {type: "value",     body: dst[dst.length-1].body*src.shift().body} },
        '/': (src, dst)=>{    dst[dst.length-1] = {type: "value",     body: dst[dst.length-1].body/src.shift().body} },
        '%': (src, dst)=>{    dst[dst.length-1] = {type: "value",     body: dst[dst.length-1].body%src.shift().body} },
        '-': (src, dst)=>{    dst[dst.length-1] = {type: "operator",  body: "+" }; dst.push({type: "value", body: 0-src.shift().body}) },
        '+': (src, dst)=>{    dst[dst.length-1] = {type: "value",     body: dst[dst.length-1].body+src.shift().body} },
        '<': (src, dst)=>{    dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body<src.shift().body?true:false) } },
        '<=': (src, dst)=>{   dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body<=src.shift().body?true:false) } },
        '>': (src, dst)=>{    dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body>src.shift().body?true:false) } },
        '>=': (src, dst)=>{   dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body>=src.shift().body?true:false) } },
        '==': (src, dst)=>{   dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body==src.shift().body?true:false) } },
        '!=': (src, dst)=>{   dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body!=src.shift().body?true:false) } },
        '===': (src, dst)=>{  dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body===src.shift().body?true:false) } },
        '!==': (src, dst)=>{  dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body!==src.shift().body?true:false) } },
        '&': (src, dst)=>{    dst[dst.length-1] = {type: "value",     body: dst[dst.length-1].body&src.shift().body} },
        '|': (src, dst)=>{    dst[dst.length-1] = {type: "value",     body: dst[dst.length-1].body|src.shift().body} },
        '&&': (src, dst)=>{   dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body&&src.shift().body) } },
        '||': (src, dst)=>{   dst[dst.length-1] = {type: "boolean",   body: (dst[dst.length-1].body||src.shift().body) } }
    };
    
    
    // это набор разрешенных функций
    var ALLOWED_FUNCTIONS = {
        "sin": (v)=>{ return {type: "value", body: Math.sin(v)} },
        "cos": (v)=>{ return {type: "value", body: Math.cos(v)} },
        "isNumber": (v)=>{ return {type: "boolean", body: !isNaN(parseFloat(v)) && isFinite(v) } }
    };
    // это набор разрешенных переменных
    var ALLOWED_VARIABLES = {
        "PI": Math.PI,
        "x": 6,
        "y": 7.5,
        "a": 180
    };
    
    
    // парсер результатов разбора строки
    function resCalc(src){
    	// 	заменяем переменные на их значения
        src = src.map(item=>{
            // если не переменная возвращаем как есть
            if(item.type !== "variable")
                return item;
                
            // иначе преобразуем переменную в ее значение
            // тут надо еще сделать проверку на наличие переменной в списке разрешенных
            const value = ALLOWED_VARIABLES[item.body];
            let type = "value";
            if( typeof value !== "number" ) type = typeof value;
            return {
                type: type,
                body: ALLOWED_VARIABLES[item.body]
            };
        });
    
        let dst;
        Object.keys(OPERATOR_PRIORITY).forEach(operator=>{
            const _calc = OPERATOR_PRIORITY[operator];
            dst = [];
            while( src.length ){
                const item = src.shift();
    
                
                if(item.type === "function"){
                    // если функция
                    // тут надо еще сделать проверку на наличие функции в списке разрешенных
                    dst.push(ALLOWED_FUNCTIONS[item.name]( resCalc(item.body).body ) );
                }else if(item.type === "bracket"){
                    // если скобки
                    dst.push( resCalc(item.body).body );
                }else if(item.type === "operator" && item.body === operator){
                    // если оператор
                    // тут надо еще сделать проверку на наличие обработчика оператора
                    _calc(src, dst);
                }else{
                    // если все остальное
                    dst.push(item);
                }
                
            }
            src = dst;
        });
        return src[0];
    }
    
    
    console.log("\n\nresult:\n",JSON.stringify(resCalc(list), null, '  '));
    результат разбора
    [
      { "type": "variable", "body": "x" },
      { "type": "operator", "body": ">" },
      { "type": "value", "body": 5 },
      { "type": "operator", "body": "&&" },
      { "type": "bracket", "body": [
          { "type": "variable", "body": "y" },
          { "type": "operator", "body": "==" },
          { "type": "value", "body": 7.5 }
        ]
      },
      { "type": "operator", "body": "||" },
      { "type": "function", "name": "sin", "body": [
          { "type": "variable", "body": "PI" },
          { "type": "operator", "body": "*" },
          { "type": "variable",  "body": "a" },
          { "type": "operator", "body": "/" },
          { "type": "value", "body": 360 },
          { "type": "operator", "body": "||" },
          { "type": "variable", "body": "isNumber" },
          { "type": "variable", "body": "y" }
        ]
      },
      { "type": "operator", "body": "&&" },
      { "type": "boolean", "body": true }
    ]
    результат вычисления значения
    {
      "type": "boolean",
      "body": true
    }
  • Чем заменить eval для простых выражений?

    lastuniverse
    @lastuniverse
    dollar, еще немного подправил, добавил функции строки и булиевы значения
    Над обходом сейчас думаю, чтобы создало структуру, удобную для обхода с точки зрения приоритета операторов
  • Чем заменить eval для простых выражений?

    lastuniverse
    @lastuniverse
    dollar, Немного изменил свой ответ, вернее добавил в него способ решения Вашей задачи. Посмотрите все что после PS:
  • Можно ли при создании объекта использовать его же свойства?

    lastuniverse
    @lastuniverse
    При желании можно делать примерно так:

    let o = {
        x: 2
    };
    
    o.y = o.x;


    Но это уже не при создании)
  • Как сделать 2.5D игру html5?

    lastuniverse
    @lastuniverse
    Алексей Лебедев, вопрос с целевой аудиторией успешно решают единицы игровых стартапов из сотен а то и тысяч. Но по непроверенным данным )))) нынче народ склонен к играм, не привязывающим их к компу или телефону на длительное время (короткие катки, длительностью до 5 минут). Режим выживания идеально для этого подходит)
    Геймплей же, таких игр как один на все нарастающую, прущую на тебя толпу всегда очарователен, проверено такими монстрами как SeriosSam, тем же AlienShooter и их многочисленными клонами. Видимо основная масса игроков с удовольствием отказывается во время игры от каких либо проявлений мыслительного процесса, но при этом не прочь почувствовать себя супер героями ))))
  • Как отрисовать bullet, что-бы каждый клитент видел его?

    lastuniverse
    @lastuniverse
    Недавно на тостере уже спрашивали что-то такое Полёт пули в игре html5+js?

    Прочитав Ваш вопрос, до меня так и не дошло, что же Вы хотите узнать. Извините.
    На всякий случай, вот мой пример (покликайте по листу), он конечно совершенно не сетевой, но возможно поможет вам найти ответы на часть вопросов. Вся логика расчета и отрисовки пуль в этом файле
  • Маштабируемые графики без библиотек: SVG или Canvas?

    lastuniverse
    @lastuniverse
    Делал как то забавы ради на canvas: https://game.lastuniverse.ru/graph.01/

    Масштабируется:
    колесиком мыши (пропорционально)
    alt+колесиком мыши (по вертикали)
    Перетаскивается мышкой

    картинки
    5c8f64a9ab23d265628305.png5c8f64c3e7211482234549.png5c8f64cb9481d503846658.png
  • Построение 3D модели человека на основании фото. Как сделать быстро и удобно?

    lastuniverse
    @lastuniverse
    Несколько лет назад (может даже и более 10 лет назад) компанией autodesk был анонсирован сервис 1234 catch (ныне является частью сервиса 123D apps, который достаточно качественно решает вашу задачу.
    Работало это так:
    1. Объект сканирования устанавливался неподвижно (если это человек, то он мог быть одет во что угодно, никаких размалеваных квадратами футболок и сканирующих лазерных лучей)
    2. Пользователь делал видеозапись путем перемещения камеры по окружности в 360 гр. вокруг.
    3. данная видеозапись заливалась на сервис
    4. сервис обрабатывал видеозапись, строя 3D модель

    Вот видеоролик, показывающий как это работает сейчас
  • Как найти соответствие ключ-значение = значение ключ в массиве?

    lastuniverse
    @lastuniverse
    Без энтузиазма


    Так как известный мне JavaScript считает синтаксически неверными записи типа
    [21: 31, 22: 14, 23: 1, 24: 35, 25: 6, 26: 16, 27: 13, 28: 78, 29: 1,30: 42, 31: 21, 32: 31, 33: 15,34: 20, 35: 24]
    и [[24: 35], [21: 31]]

    взял на себя смелость заменить на
    {"21":31,"22":14,"23":1,"24":35,"25":6,"26":16,"27":13,"28":78,"29":1,"30":42,"31":21,"32":31,"33":15,"34":20,"35":24}
    и {"21":31,"24":35} соответственно.
  • Что толкового можно написать опираясь на модуль Net (Nodejs)?

    lastuniverse
    @lastuniverse
    Да что угодно, опирающееся на сетевой стэк. Например свой FTP, minecraft server, proxy и другие сервера и клиенты, включая узкоспециализированные такие как vnc клиент с последующей трансляцией управления в браузер. Перечислять можно бесконечно.
    Лично я, как любитель изобретать велосипеды, написал для собственных нужд 2 класса, позволяющих достаточно легко обмениваться служебными json сообщениями:
    детский трехколесный велик

    сам недомодуль (красоты не ждите:):
    const net = require("net");
    
    function send(event, data){
    	this.write(
    		JSON.stringify({
    			event: event,
    			data: data
    		})+"\n"
    	);
    }
    
    class Server extends EventEmitter {
    	constructor(options={}){
    		super();
    		this.clients = {};
    		this.host=options.host||'0.0.0.0';
    		this.port=options.port||'8020';
    		this.server = net.createServer ((client)=>{
    			client.send = send;
    			client.on('data', data=>{
    				try{
    					const str = data.toString();
    					const json = JSON.parse(""+str);
    					if( json && json.event && json.data!==undefined){
    						this.emit(json.event, json.data, client);
    					}
    				}catch(err){
    					console.log('\n\nError parse json', err);
    				}
    			});
    
    			client.on('close', data=>{
    				// ...
    			});
    		});
    	}
    
    	listen(host, port){
    		this.host=host||this.host;
    		this.port=port||this.port;
    		this.server.listen(this.port, this.host);
    		console.log('Server was ben started as ' + this.host + ':' + this.port);
    	}
    }
    module.exports.Server = Server;
    
    
    class Client extends EventEmitter {
    	constructor(options={}){
    		super();
    		this.host=options.host||'192.168.0.1';
    		this.port=options.port||'8020';
    		this.client = new net.Socket();
    		this.client.send = send;
    		this.client.on('data', data=>{
    			data.toString().split(/[\n\r]+/).forEach(str=>{
    				if( !str || str.search(/^[\s\n\r]+$/)+1 ) return;
    				try{
    					const json = JSON.parse(""+str);
    					if( json && json.event && json.data!==undefined){
    						this.emit(json.event, json.data, this.client);
    					}
    				}catch(err){
    					console.log('\n\nError parse json ', err);
    				}
    			});
    		});
    
    		this.client.on('close', ()=>{
    			console.log('Connection closed');
    			this.emit("disconnect", {});
    			setTimeout(()=>{
    				this.connect()
    			}, 6000);
    		});
    
    		this.client.on('error', ()=>{
    			console.log('Connection error');
    			this.emit("disconnect", {});
    			this.client.destroy();
    			
    		});		
    	}
    
    	
    	connect(host, port){
    		this.host=host||this.host;
    		this.port=port||this.port;
    		this.client.connect(this.port, this.host, (err)=>{
    			this.emit('connect', {}, this.client);
    			if(err) reject(err);
    		});
    	}
    }
    module.exports.Client = Client;


    узкоспециализированный сервер на его базе:
    const storrage = require("./modules/storrage.js");
    const users = storrage("../config/users.json",{});
    const config = storrage("../config/config.server.json",{});
    
    const NU = require("./modules/net-union.js");
    const server = new NU.Server();
    const clients = {};
    
    function getUser(data){
        if( !data || !data.login || !data.password )
            return false;
        const user = users[data.login];
        if( !user || user.password != data.password)
            return false;
        return user;
    }
    
    server.on("avance", (data, client )=>{
        const user = getUser(data.auth);
        if( !user ) return client.end();
        
        const username = data.auth.login;
        clients[username] = client;
        user.points-=data.avance;
        client.send("points", user.points);
    });
    
    server.on("unlock", (data, client )=>{
        console.log("unlock", data);
        const user = getUser(data);
        if( !user ) return client.end();
    
        const username = data.login;
        clients[username] = client;
        user.points--;
        client.send("points", user.points);
    });
    
    function update_points(username,amount) {
        if( !amount ) return;
        
        const user = users[username];
        if( !user ) return;
    
        const client = clients[username];
        if( !client ) return;
    
        client.send("points", user.points);
        client.send("message", "Количество минут "+(amount<0?"уменьшено":"увеличено")+" на "+amount+".\nОсталось "+user.points+" минут");
    }
    
    server.listen(config.url.host, config.url.port);
    
    module.exports.server = server;
    module.exports.update_points = update_points;


    ну и клиент)
    const manage = require("./modules/manage.js");
    const storrage = require("./modules/storrage.js");
    const config = storrage("./config/config.client.json",{});
    
    
    const NU = require("./modules/net-union.js");
    const client = new NU.Client();
    
    var count = 0;
    var avance = 0;
    var server;
    var isConnect = false;
    
    // при подключении к серверу отправить запрос на авторизацию
    client.on("connect", (data, serv )=>{
    	if(isConnect) return;
    	isConnect = true;
    	server = serv;
        console.log('\n\nПодключился к ' + client.host + ":" + client.port);
        if(avance)
        	server.send("avance", {auth: config.auth, avance: avance});
    });
    
    // при отключении к серверу переходим в автономный режим
    client.on("disconnect", (data)=>{
    	console.log("client.on disconnect");
    	isConnect = false;
    });
    
    
    // при получении количества баллов обновить счетчик
    client.on("points", (points, serv )=>{
    	console.log("client.on points", points);
    	count = points;
    	notify();
    });
    
    // при получении сообщения - вывести уведомление
    client.on("message", (message, serv )=>{
    	console.log("client.on message", message);
    	manage.notify("Таймер", message);
    });
    
    client.connect(config.url.host, config.url.port);
    
    function notify() {
    	if(count>8 && count%10===0){
    		manage.notify("Таймер", "Осталось "+count+" минут");
    	}else if(count==5){
    		manage.notify("Таймер", "Осталось "+count+" минут");
    	}else if(count>1 && count<5){
    		manage.notify("Таймер", "Осталось "+count+" минуты");
    	}else if(count==1){
    		manage.notify("Таймер", "Осталась 1 минута");
    	}else if(count<1){
    		manage.notify("Таймер", "ВРЕМЯ ВЫШЛО");
    		lock()
    	}
    }
    
    function lock() {
    	setTimeout(function() {
    		manage.lock(config.auth.login);
    	}, 20000);
    }
    
    function observe_session() {
    	console.log("next time");
    	manage.isLocked(config.auth.login, isLocked=>{
    		if(isLocked) return;
    
    		if( isConnect ){
    			server.send("unlock", config.auth);
    		}else{
    			count--;
    			avance++;
    			notify();
    		}
    	});
    	setTimeout( observe_session , 60000 );
    }
    setTimeout( observe_session , 10000 );

  • Нейронная сеть под мою задачу с чего начать?

    lastuniverse
    @lastuniverse
    Гораздо более подходящая задача для начинабщего в ИНС - создание и обучение ИНС дающей оценку например опасности ситуации на шашечном поле (игра в шашки) всего будет 256 входов и один выход, количество скрытых слоев и колличество нейронов в них подбираете сами. Обучающие, тестовые и контрольные выборки составляются на основе сыгранных партий, записей которых в инете множество.

    Решив эту задачу вы более или менее поймете что такое ИНС, их слабые и сильные стороны, что и как влияет на количество скрытых слоев и колличество нейронов в них и многое другое.

    Далее уже можно изучать рекуррентные ИНС и различные их вариации (lstm и прочие)
  • Поиск программы для изменение изображения?

    lastuniverse
    @lastuniverse
    Очевидно, что данное изображение не является результатом програмной обработки фотографии а нарисованно человеком. Об этом говорит наложение теней штрихами. Штрихи имеют произвольные направления на всем пространстве изображения, но при этом в местах где тени бросают относительно ровные геометрические объекты, такие как скосы крыш, направления штрихов выбраны так, как это сделал бы человек. Любому алгоритму, предназначенному для обработки изображений достаточно сложно объяснить, чем отличаются грани скоса крыш от тех же скосов колон или деревьев.
    Так же обратите внимание на штрихрвку большого дерева слева. Штрихи выполнены группами с различным направлением штриховки, при этом некоторые из групп имеют незначительные наложения в зонах контакта с соседними группами, а концы штрихов имеют характерные закругления, возникающие когда штриховка делается рукой (не программно).
    Так же обратите внимание на вертикаль коллон. Они кривые, не вертикальные и не параллельные. Это также указывает на руку художника а не на програмную обработку фотографии.
    Конечно вполне возможно написать алголитм преобразования фотографий в подобную картинку, но такой алгоритм будет очень узкоспециализированным, и на мой узгляд вкладывать много времени в его разработку, написание и отладку нецелесообразно.

    Само изображение скорее всего рисовалось с использованием графического планшета и программы для рисования типа krita
    https://ru.m.wikipedia.org/wiki/Krita
  • Как сделать 2.5D игру html5?

    lastuniverse
    @lastuniverse
    однозначно надо делать что то типа алиеншутера да еще и с сетевой игрой)))
  • Как сделать 2.5D игру html5?

    lastuniverse
    @lastuniverse
    Дмитрий Петров, надо бы обменятся контактами, но не хочу светить ту мыло и телефон)
  • Как сделать 2.5D игру html5?

    lastuniverse
    @lastuniverse
    profesor08, и я о том же. С точки зрения мерности пространства никаких дробных D в принципе существовать не может. Это не более чем пиар термин. И соответственно под него можно подвести все, что хоть чуть выбивается из классического 2D но не дотягивает до полноценного 3D