uchcode
9/2/2017 - 4:18 AM

nodejs_process_stdin_on_example

nodejs_process_stdin_on_example

process.stdin.setEncoding('utf8')
process.stdout.setEncoding('utf8')
process.stderr.setEncoding('utf8')

EVENT = {
    DEFAULT : Symbol('default'),
    ALL     : Symbol('all'),
}

EventTable = []

function data_listener(pattern, listener, data, once) {
    let text = data.replace(/\n$/,'')
    switch (pattern) {
    case EVENT.DEFAULT:
        var trigger = true
        for (let e of EventTable.filter(e=>typeof e.pattern!='symbol')) {
            let p = e.pattern
            trigger = typeof p == 'string' ? p != text : !p.test(text)
            if (!trigger) break
        }
        break
    case EVENT.ALL:
        var trigger = true
        break
    default:
        var trigger = typeof pattern == 'string' ? pattern == text : pattern.test(text)
        break
    }
    if (trigger) {
        listener(data)
        if (once) {
            process.stdin.removeListener('data', once)
            EventTable = EventTable.filter(e=>e.dataListener!=once)
        }
    }
}

function process_stdin_on(pattern, listener) {
    let event = {
        pattern  : pattern,
        listener : listener,
        dataListener : (data) => {
            data_listener(event.pattern, event.listener, data)
        },
    }
    EventTable.push(event)
    process.stdin.on('data', event.dataListener)
}

function process_stdin_once(pattern, listener) {
    let event = {
        pattern  : pattern,
        listener : listener,
        dataListener : (data) => {
            data_listener(event.pattern, event.listener, data, event.dataListener)
        },
    }
    EventTable.push(event)
    process.stdin.on('data', event.dataListener)
}

////////////////////////////////////////////////////////////////////////////////

function output(data, terminator='\n') {
    process.stdout.write(data + terminator)
}

function error(data, terminator='\n') {
    process.stderr.write(data + terminator)
}

answer = Math.floor( Math.random() * (100) )
output('数当てゲーム!!')
output('0 〜 100 の間の整数を当ててください')
output('答え:', '')

process_stdin_on(answer.toString(), (data) => {
    output(`正解!! ${answer}`)
    process.exit(0)
})

process_stdin_on('', (data) => {
    error('ゲームを中止しました。')
    error(`答えは ${answer} でした。`)
    process.exit(1)
})

process_stdin_once('hint', (data) => {
    if (answer > 50) {
        output('答えは50より大きいです。','')
    } else {
        output('答えは50以下です。','')
    }
    output('hintは一回だけ!')
})

process_stdin_on(/[^0-9]+/, (data) => {
    error('半角数字の正数でお願いします')
})

process_stdin_on(EVENT.DEFAULT, (data) => {
    let d = data.trim()
    if (d > 100 || d < 0) {
        output(`答えは 0 〜 100 の間で!`)
    } else if (d > answer) {
        output(`${d}は大きい`)
    } else if (d < answer) {
        output(`${d}は小さい`)
    } else {
        error('===EVENT.DEFAULTが発火しました。文字列と正規表現のパターンにマッチしませんでした。=== d:' + d)
    }
})

process_stdin_on(EVENT.ALL, (data) => {
    output('答え:', '')
})