Skip to content

Instantly share code, notes, and snippets.

@bigomega
Last active March 23, 2016 22:27
Show Gist options
  • Save bigomega/86c67796b032f8fc74e6 to your computer and use it in GitHub Desktop.
Save bigomega/86c67796b032f8fc74e6 to your computer and use it in GitHub Desktop.

Revisions

  1. bigomega revised this gist Mar 23, 2016. 1 changed file with 4 additions and 11 deletions.
    15 changes: 4 additions & 11 deletions tic-tac-toe.js
    Original file line number Diff line number Diff line change
    @@ -34,14 +34,9 @@ function end(game) {

    function print(game) {
    console.log('\x1B[2J\x1B[0f') // Clear screen
    // x index
    console.log([' '].concat(_utils.range(game.width)).join(' '));

    _boardUtil.getRows(game).forEach((row, i) => {
    console.log(
    i + ' ', // y index
    row.map(value => coin[value || 0] ).join(' ')
    )
    console.log(i + ' ', row.map(value => coin[value] ).join(' '))
    })
    console.log('')
    }
    @@ -69,11 +64,9 @@ function getInput(message, game) {
    }

    function switchPlayer(game, reverse) {
    if(reverse) {
    game.currentPlayer -= 1
    } else {
    game.currentPlayer += 1
    }
    if(reverse) game.currentPlayer -= 1
    else game.currentPlayer += 1

    return game.currentPlayer = game.currentPlayer < 1 ? game.playerCount : 1
    }

  2. bigomega revised this gist Mar 23, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tic-tac-toe.js
    Original file line number Diff line number Diff line change
    @@ -11,7 +11,7 @@ function initiateBoard(game) {
    }

    function end(game) {
    const checkWin = (Arr2D) => Arr2D.some(list => {
    const checkWin = Arr2D => Arr2D.some(list => {
    const max = { p: 0, val: 0 }
    return list.some(value => {
    if (value && value === max.p) max.val++
  3. bigomega revised this gist Mar 23, 2016. 1 changed file with 2 additions and 4 deletions.
    6 changes: 2 additions & 4 deletions tic-tac-toe.js
    Original file line number Diff line number Diff line change
    @@ -27,11 +27,9 @@ function end(game) {
    const diagonalNE = checkWin(_boardUtil.getNEDiagonals(game))

    const coinCount = _boardUtil.getItems(game).reduce((mem, value) => mem + Boolean(value))
    const staleMate = coinCount >= game.width * game.height

    if(coinCount >= game.width * game.height)
    return 'draw'
    else
    return verticalEnd || horizontalEnd || diagonalNW || diagonalNE
    return (staleMate && 'draw') || verticalEnd || horizontalEnd || diagonalNW || diagonalNE
    }

    function print(game) {
  4. bigomega revised this gist Mar 23, 2016. 1 changed file with 17 additions and 18 deletions.
    35 changes: 17 additions & 18 deletions tic-tac-toe.js
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@ const _boardUtil = require('./_board-utils')
    function initiateBoard(game) {
    _utils.range(game.width).forEach(i => {
    game.board[i] = []
    _utils.range(game.width).forEach(j => game.board[i][j] = 0)
    _utils.range(game.height).forEach(j => game.board[i][j] = 0)
    })
    }

    @@ -53,32 +53,30 @@ function printEnd(state, currentPlayer) {
    else console.log(`Game over. Player "${coin[currentPlayer]}" won.\n`)
    }

    function place(i, j, game) {
    if (isNaN(i) || isNaN(j)) return false
    if (i < 0 || i > game.width - 1) return false
    if (j < 0 || j > game.height - 1) return false
    if (game.currentPlayer < 1) return false
    function place(position, game) {
    const x = position[0]
    const y = position[1]
    if (isNaN(x) || isNaN(y)) return false
    if (x < 0 || x > game.width - 1) return false
    if (y < 0 || y > game.height - 1) return false
    if (game.currentPlayer < 1 || game.board[x][y]) return false

    if (!game.board[i]) game.board[i] = []

    if (game.board[i][j]) return false

    return game.board[i][j] = game.currentPlayer
    return game.board[x][y] = game.currentPlayer
    }

    function parse(text, game) {
    function getInput(message, game) {
    const text = _utils.readLineSync(message)
    const split = text.split(',').length < 2 ? text.split(' ') : text.split(',')
    return split.map(v => parseInt(v))
    }

    function switchPlayer(game, reverse) {
    if(reverse) {
    game.currentPlayer--
    if (game.currentPlayer < 1) game.currentPlayer = game.playerCount
    game.currentPlayer -= 1
    } else {
    game.currentPlayer++
    if (game.currentPlayer > game.playerCount) game.currentPlayer = 1
    game.currentPlayer += 1
    }
    return game.currentPlayer = game.currentPlayer < 1 ? game.playerCount : 1
    }

    const coin = { 0: '_', 1: 'X', 2: 'O', 3: '#' }
    @@ -97,8 +95,9 @@ const coin = { 0: '_', 1: 'X', 2: 'O', 3: '#' }
    initiateBoard(game)
    print(game)
    while(!(endState = end(game))) {
    const position = parse(_utils.readLineSync(`Player "${coin[game.currentPlayer]}" (x y):`), game)
    if(place(position[0], position[1], game)) {
    const position = getInput(`Player "${coin[game.currentPlayer]}" (x y):`, game)

    if (place(position, game)) {
    print(game)
    switchPlayer(game)
    } else {
  5. bigomega revised this gist Mar 23, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tic-tac-toe.js
    Original file line number Diff line number Diff line change
    @@ -105,6 +105,6 @@ const coin = { 0: '_', 1: 'X', 2: 'O', 3: '#' }
    console.log('Invalid move')
    }
    }
    switchPlayer(game, false)
    switchPlayer(game, true)
    printEnd(endState, game.currentPlayer)
    })()
  6. bigomega revised this gist Mar 23, 2016. 3 changed files with 94 additions and 82 deletions.
    49 changes: 49 additions & 0 deletions _board-utils.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,49 @@
    'use strict'

    const _utils = require('./_utils')

    function getColumns(game) { return game.board }

    function getRows(game) { return _utils.inverse2D(game.board) }

    function getNWDiagonals(game) {
    return _utils.range(game.width + game.height - 1).map(edge => {
    // taking top and left edge
    let i = edge < game.width ? edge : 0
    let j = edge < game.width ? 0 : edge - game.width + 1
    const arr = []

    while(i < game.width && j < game.height) {
    arr.push(game.board[i][j])
    i++, j++
    }
    return arr
    })
    }

    function getNEDiagonals(game) {
    return _utils.range(game.width + game.height - 1).map(edge => {
    // taking top and right edge
    let i = edge < game.width ? edge : game.width - 1
    let j = edge < game.width ? 0 : edge - game.width + 1
    const arr = []

    while(i >= 0 && j < game.height) {
    arr.push(game.board[i][j])
    i--, j++
    }
    return arr
    })
    }

    function getItems(game) {
    return getColumns(game).reduce((mem, column) => mem.concat(column), [])
    }

    module.exports = {
    getColumns,
    getRows,
    getItems,
    getNWDiagonals,
    getNEDiagonals,
    }
    27 changes: 27 additions & 0 deletions _utils.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    'use strict'

    const fs = require('fs')

    // util function modified from github.com/bucaran/sget
    module.exports.readLineSync = function(message) {
    message = message || ''
    const win32 = () => 'win32' === process.platform
    const readSync = function(buffer) {
    var fd = win32() ? process.stdin.fd : fs.openSync('/dev/stdin', 'rs')
    var bytes = fs.readSync(fd, buffer, 0, buffer.length)
    if (!win32()) fs.closeSync(fd)
    return bytes
    }
    return (function(buffer) {
    try {
    process.stdout.write(message + ' ')
    return buffer.toString(null, 0, readSync(buffer))
    } catch (e) {
    throw e
    }
    }(new Buffer(256)))
    }

    module.exports.range = n => Array(n + 1).join(1).split('').map((x, i) => i)

    module.exports.inverse2D = Arr => Arr[0].map((val, j) => Arr.map(column => column[j]))
    100 changes: 18 additions & 82 deletions tic-tac-toe.js
    Original file line number Diff line number Diff line change
    @@ -1,78 +1,16 @@
    'use strict'

    const fs = require('fs')

    // util function modified from github.com/bucaran/sget
    const readLineSync = function(message) {
    message = message || ''
    const win32 = () => 'win32' === process.platform
    const readSync = function(buffer) {
    var fd = win32() ? process.stdin.fd : fs.openSync('/dev/stdin', 'rs')
    var bytes = fs.readSync(fd, buffer, 0, buffer.length)
    if (!win32()) fs.closeSync(fd)
    return bytes
    }
    return (function(buffer) {
    try {
    process.stdout.write(message + ' ')
    return buffer.toString(null, 0, readSync(buffer))
    } catch (e) {
    throw e
    }
    }(new Buffer(256)))
    }

    const range = n => Array(n + 1).join(1).split('').map((x, i) => i)

    const inverse2D = Arr => Arr[0].map((val, j) => Arr.map(column => column[j]))
    const _utils = require('./_utils')
    const _boardUtil = require('./_board-utils')

    function initiateBoard(game) {
    range(game.width).forEach(i => {
    _utils.range(game.width).forEach(i => {
    game.board[i] = []
    range(game.width).forEach(j => game.board[i][j] = 0)
    })
    }

    function getColumns(game) { return game.board }

    function getRows(game) { return inverse2D(game.board) }

    function getNWDiagonals(game) {
    return range(game.width + game.height - 1).map(edge => {
    // taking top and left edge
    let i = edge < game.width ? edge : 0
    let j = edge < game.width ? 0 : edge - game.width + 1
    const arr = []

    while(i < game.width && j < game.height) {
    arr.push(game.board[i][j])
    i++, j++
    }
    return arr
    _utils.range(game.width).forEach(j => game.board[i][j] = 0)
    })
    }

    function getNEDiagonals(game) {
    return range(game.width + game.height - 1).map(edge => {
    // taking top and right edge
    let i = edge < game.width ? edge : game.width - 1
    let j = edge < game.width ? 0 : edge - game.width + 1
    const arr = []

    while(i >= 0 && j < game.height) {
    arr.push(game.board[i][j])
    i--, j++
    }
    return arr
    })
    }

    function getItems(game) {
    return getColumns(game).reduce((mem, column) => mem.concat(column), [])
    }

    function end(game) {

    const checkWin = (Arr2D) => Arr2D.some(list => {
    const max = { p: 0, val: 0 }
    return list.some(value => {
    @@ -83,15 +21,12 @@ function end(game) {
    })
    })

    const verticalEnd = checkWin(getColumns(game))

    const horizontalEnd = checkWin(getRows(game))

    const diagonalNW = checkWin(getNWDiagonals(game))

    const diagonalNE = checkWin(getNEDiagonals(game))
    const verticalEnd = checkWin(_boardUtil.getColumns(game))
    const horizontalEnd = checkWin(_boardUtil.getRows(game))
    const diagonalNW = checkWin(_boardUtil.getNWDiagonals(game))
    const diagonalNE = checkWin(_boardUtil.getNEDiagonals(game))

    const coinCount = getItems(game).reduce((mem, value) => mem + Boolean(value))
    const coinCount = _boardUtil.getItems(game).reduce((mem, value) => mem + Boolean(value))

    if(coinCount >= game.width * game.height)
    return 'draw'
    @@ -102,12 +37,12 @@ function end(game) {
    function print(game) {
    console.log('\x1B[2J\x1B[0f') // Clear screen
    // x index
    console.log([' '].concat(range(game.width)).join(' '));
    console.log([' '].concat(_utils.range(game.width)).join(' '));

    range(game.height).map(j => {
    _boardUtil.getRows(game).forEach((row, i) => {
    console.log(
    j + ' ', // y index
    range(game.width).map(i => coin[(game.board[i] || [])[j] || 0] ).join(' ')
    i + ' ', // y index
    row.map(value => coin[value || 0] ).join(' ')
    )
    })
    console.log('')
    @@ -139,14 +74,14 @@ function parse(text, game) {
    function switchPlayer(game, reverse) {
    if(reverse) {
    game.currentPlayer--
    if (game.currentPlayer < 1) game.currentPlayer = 2
    if (game.currentPlayer < 1) game.currentPlayer = game.playerCount
    } else {
    game.currentPlayer++
    if (game.currentPlayer > 2) game.currentPlayer = 1
    if (game.currentPlayer > game.playerCount) game.currentPlayer = 1
    }
    }

    const coin = { 0: '_', 1: 'X', 2: 'O' }
    const coin = { 0: '_', 1: 'X', 2: 'O', 3: '#' }

    ;(function(){
    let endState;
    @@ -155,13 +90,14 @@ const coin = { 0: '_', 1: 'X', 2: 'O' }
    width: 3,
    height: 3,
    win: 3,
    playerCount: 2,
    currentPlayer: 1,
    }

    initiateBoard(game)
    print(game)
    while(!(endState = end(game))) {
    const position = parse(readLineSync(`Player "${coin[game.currentPlayer]}" (x y):`), game)
    const position = parse(_utils.readLineSync(`Player "${coin[game.currentPlayer]}" (x y):`), game)
    if(place(position[0], position[1], game)) {
    print(game)
    switchPlayer(game)
  7. bigomega revised this gist Mar 23, 2016. 1 changed file with 62 additions and 48 deletions.
    110 changes: 62 additions & 48 deletions tic-tac-toe.js
    Original file line number Diff line number Diff line change
    @@ -24,72 +24,79 @@ const readLineSync = function(message) {

    const range = n => Array(n + 1).join(1).split('').map((x, i) => i)

    function end(game) {

    const verticalEnd = range(game.width).some(i => {
    const column = game.board[i] || []
    const max = { p: 0, val: 0 }

    return range(game.height).some(j => {
    const value = column[j]
    if (value && value === max.p) max.val++
    else max.p = value, max.val = 1
    const inverse2D = Arr => Arr[0].map((val, j) => Arr.map(column => column[j]))

    return max.p && max.val >= game.win
    })
    function initiateBoard(game) {
    range(game.width).forEach(i => {
    game.board[i] = []
    range(game.width).forEach(j => game.board[i][j] = 0)
    })
    }

    const horizontalEnd = range(game.height).some(j => {
    const max = { p: 0, val: 0 }
    function getColumns(game) { return game.board }

    return range(game.width).some(i => {
    const value = (game.board[i] || [])[j]
    if (value && value === max.p) max.val++
    else max.p = value, max.val = 1

    return max.p && max.val >= game.win
    })
    })
    function getRows(game) { return inverse2D(game.board) }

    const diagonalNW = range(game.width + game.height - 1).some(k => {
    function getNWDiagonals(game) {
    return range(game.width + game.height - 1).map(edge => {
    // taking top and left edge
    let i = k < game.width ? k : 0
    let j = k < game.width ? 0 : k - game.width + 1
    const max = { p: 0, val: 0 }
    let i = edge < game.width ? edge : 0
    let j = edge < game.width ? 0 : edge - game.width + 1
    const arr = []

    while(i < game.width && j < game.height) {
    const value = (game.board[i] || [])[j]
    if (value && value === max.p) max.val++
    else max.p = value, max.val = 1

    if (max.p && max.val >= game.win) return true
    arr.push(game.board[i][j])
    i++, j++
    }
    return arr
    })
    }

    const diagonalNE = range(game.width + game.height - 1).some(k => {
    function getNEDiagonals(game) {
    return range(game.width + game.height - 1).map(edge => {
    // taking top and right edge
    let i = k < game.width ? k : game.width - 1
    let j = k < game.width ? 0 : k - game.width + 1
    const max = { p: 0, val: 0 }
    let i = edge < game.width ? edge : game.width - 1
    let j = edge < game.width ? 0 : edge - game.width + 1
    const arr = []

    while(i >= 0 && j < game.height) {
    const value = (game.board[i] || [])[j]
    arr.push(game.board[i][j])
    i--, j++
    }
    return arr
    })
    }

    function getItems(game) {
    return getColumns(game).reduce((mem, column) => mem.concat(column), [])
    }

    function end(game) {

    const checkWin = (Arr2D) => Arr2D.some(list => {
    const max = { p: 0, val: 0 }
    return list.some(value => {
    if (value && value === max.p) max.val++
    else max.p = value, max.val = 1

    if (max.p && max.val >= game.win) return true
    i--, j++
    }
    return max.p && max.val >= game.win
    })
    })

    const coinCount = range(game.width).reduce((mem, i) => (
    mem + range(game.height).reduce((deepMem, j) => (
    deepMem + Boolean((game.board[i] || [])[j])
    ), 0)
    ), 0)
    const verticalEnd = checkWin(getColumns(game))

    return (coinCount >= game.width * game.height && 'draw') || verticalEnd || horizontalEnd || diagonalNW || diagonalNE
    const horizontalEnd = checkWin(getRows(game))

    const diagonalNW = checkWin(getNWDiagonals(game))

    const diagonalNE = checkWin(getNEDiagonals(game))

    const coinCount = getItems(game).reduce((mem, value) => mem + Boolean(value))

    if(coinCount >= game.width * game.height)
    return 'draw'
    else
    return verticalEnd || horizontalEnd || diagonalNW || diagonalNE
    }

    function print(game) {
    @@ -129,9 +136,14 @@ function parse(text, game) {
    return split.map(v => parseInt(v))
    }

    function switchPlayer(game) {
    game.currentPlayer++
    if (game.currentPlayer > 2) game.currentPlayer = 1
    function switchPlayer(game, reverse) {
    if(reverse) {
    game.currentPlayer--
    if (game.currentPlayer < 1) game.currentPlayer = 2
    } else {
    game.currentPlayer++
    if (game.currentPlayer > 2) game.currentPlayer = 1
    }
    }

    const coin = { 0: '_', 1: 'X', 2: 'O' }
    @@ -146,6 +158,7 @@ const coin = { 0: '_', 1: 'X', 2: 'O' }
    currentPlayer: 1,
    }

    initiateBoard(game)
    print(game)
    while(!(endState = end(game))) {
    const position = parse(readLineSync(`Player "${coin[game.currentPlayer]}" (x y):`), game)
    @@ -156,5 +169,6 @@ const coin = { 0: '_', 1: 'X', 2: 'O' }
    console.log('Invalid move')
    }
    }
    switchPlayer(game, false)
    printEnd(endState, game.currentPlayer)
    })()
  8. bigomega revised this gist Mar 23, 2016. 1 changed file with 48 additions and 27 deletions.
    75 changes: 48 additions & 27 deletions tic-tac-toe.js
    Original file line number Diff line number Diff line change
    @@ -22,11 +22,10 @@ const readLineSync = function(message) {
    }(new Buffer(256)))
    }

    const coin = ['_', 'X', 'O']

    const range = n => Array(n + 1).join(1).split('').map((x, i) => i)

    function end() {
    function end(game) {

    const verticalEnd = range(game.width).some(i => {
    const column = game.board[i] || []
    const max = { p: 0, val: 0 }
    @@ -84,10 +83,16 @@ function end() {
    }
    })

    return verticalEnd || horizontalEnd || diagonalNW || diagonalNE
    const coinCount = range(game.width).reduce((mem, i) => (
    mem + range(game.height).reduce((deepMem, j) => (
    deepMem + Boolean((game.board[i] || [])[j])
    ), 0)
    ), 0)

    return (coinCount >= game.width * game.height && 'draw') || verticalEnd || horizontalEnd || diagonalNW || diagonalNE
    }

    function print() {
    function print(game) {
    console.log('\x1B[2J\x1B[0f') // Clear screen
    // x index
    console.log([' '].concat(range(game.width)).join(' '));
    @@ -101,39 +106,55 @@ function print() {
    console.log('')
    }

    function place(i, j, p) {
    function printEnd(state, currentPlayer) {
    if(state === 'draw') console.log('Game over. The game ended in a draw.\n')
    else console.log(`Game over. Player "${coin[currentPlayer]}" won.\n`)
    }

    function place(i, j, game) {
    if (isNaN(i) || isNaN(j)) return false
    if (i < 0 || i > game.width - 1) return false
    if (j < 0 || j > game.height - 1) return false
    if (p < 1) return false
    if (game.currentPlayer < 1) return false

    if (!game.board[i]) game.board[i] = []

    if (game.board[i][j]) return false

    return game.board[i][j] = p
    return game.board[i][j] = game.currentPlayer
    }

    const game = {
    board: [],
    width: 3,
    height: 3,
    win: 3,
    function parse(text, game) {
    const split = text.split(',').length < 2 ? text.split(' ') : text.split(',')
    return split.map(v => parseInt(v))
    }

    let currentPlayer = 1;
    while(!end()) {
    print()
    let i, j
    do {
    const inp = readLineSync(`Player "${coin[currentPlayer]}" (x y):`)
    const split = inp.split(',').length < 2 ? inp.split(' ') : inp.split(',')
    i = parseInt(split[0]), j = parseInt(split[1])
    function switchPlayer(game) {
    game.currentPlayer++
    if (game.currentPlayer > 2) game.currentPlayer = 1
    }

    } while(!place(i, j, currentPlayer) && (console.log('Invalid move'), true))
    const coin = { 0: '_', 1: 'X', 2: 'O' }

    currentPlayer++
    if (currentPlayer > 2) currentPlayer = 1
    }
    print()
    console.log(`\nGame over. Player "${coin[currentPlayer]}" won.\n`)
    ;(function(){
    let endState;
    const game = {
    board: [],
    width: 3,
    height: 3,
    win: 3,
    currentPlayer: 1,
    }

    print(game)
    while(!(endState = end(game))) {
    const position = parse(readLineSync(`Player "${coin[game.currentPlayer]}" (x y):`), game)
    if(place(position[0], position[1], game)) {
    print(game)
    switchPlayer(game)
    } else {
    console.log('Invalid move')
    }
    }
    printEnd(endState, game.currentPlayer)
    })()
  9. bigomega revised this gist Mar 23, 2016. 1 changed file with 139 additions and 1 deletion.
    140 changes: 139 additions & 1 deletion tic-tac-toe.js
    Original file line number Diff line number Diff line change
    @@ -1 +1,139 @@
    console.log('test')
    'use strict'

    const fs = require('fs')

    // util function modified from github.com/bucaran/sget
    const readLineSync = function(message) {
    message = message || ''
    const win32 = () => 'win32' === process.platform
    const readSync = function(buffer) {
    var fd = win32() ? process.stdin.fd : fs.openSync('/dev/stdin', 'rs')
    var bytes = fs.readSync(fd, buffer, 0, buffer.length)
    if (!win32()) fs.closeSync(fd)
    return bytes
    }
    return (function(buffer) {
    try {
    process.stdout.write(message + ' ')
    return buffer.toString(null, 0, readSync(buffer))
    } catch (e) {
    throw e
    }
    }(new Buffer(256)))
    }

    const coin = ['_', 'X', 'O']

    const range = n => Array(n + 1).join(1).split('').map((x, i) => i)

    function end() {
    const verticalEnd = range(game.width).some(i => {
    const column = game.board[i] || []
    const max = { p: 0, val: 0 }

    return range(game.height).some(j => {
    const value = column[j]
    if (value && value === max.p) max.val++
    else max.p = value, max.val = 1

    return max.p && max.val >= game.win
    })
    })

    const horizontalEnd = range(game.height).some(j => {
    const max = { p: 0, val: 0 }

    return range(game.width).some(i => {
    const value = (game.board[i] || [])[j]
    if (value && value === max.p) max.val++
    else max.p = value, max.val = 1

    return max.p && max.val >= game.win
    })
    })

    const diagonalNW = range(game.width + game.height - 1).some(k => {
    // taking top and left edge
    let i = k < game.width ? k : 0
    let j = k < game.width ? 0 : k - game.width + 1
    const max = { p: 0, val: 0 }

    while(i < game.width && j < game.height) {
    const value = (game.board[i] || [])[j]
    if (value && value === max.p) max.val++
    else max.p = value, max.val = 1

    if (max.p && max.val >= game.win) return true
    i++, j++
    }
    })

    const diagonalNE = range(game.width + game.height - 1).some(k => {
    // taking top and right edge
    let i = k < game.width ? k : game.width - 1
    let j = k < game.width ? 0 : k - game.width + 1
    const max = { p: 0, val: 0 }

    while(i >= 0 && j < game.height) {
    const value = (game.board[i] || [])[j]
    if (value && value === max.p) max.val++
    else max.p = value, max.val = 1

    if (max.p && max.val >= game.win) return true
    i--, j++
    }
    })

    return verticalEnd || horizontalEnd || diagonalNW || diagonalNE
    }

    function print() {
    console.log('\x1B[2J\x1B[0f') // Clear screen
    // x index
    console.log([' '].concat(range(game.width)).join(' '));

    range(game.height).map(j => {
    console.log(
    j + ' ', // y index
    range(game.width).map(i => coin[(game.board[i] || [])[j] || 0] ).join(' ')
    )
    })
    console.log('')
    }

    function place(i, j, p) {
    if (isNaN(i) || isNaN(j)) return false
    if (i < 0 || i > game.width - 1) return false
    if (j < 0 || j > game.height - 1) return false
    if (p < 1) return false

    if (!game.board[i]) game.board[i] = []

    if (game.board[i][j]) return false

    return game.board[i][j] = p
    }

    const game = {
    board: [],
    width: 3,
    height: 3,
    win: 3,
    }

    let currentPlayer = 1;
    while(!end()) {
    print()
    let i, j
    do {
    const inp = readLineSync(`Player "${coin[currentPlayer]}" (x y):`)
    const split = inp.split(',').length < 2 ? inp.split(' ') : inp.split(',')
    i = parseInt(split[0]), j = parseInt(split[1])

    } while(!place(i, j, currentPlayer) && (console.log('Invalid move'), true))

    currentPlayer++
    if (currentPlayer > 2) currentPlayer = 1
    }
    print()
    console.log(`\nGame over. Player "${coin[currentPlayer]}" won.\n`)
  10. bigomega created this gist Mar 23, 2016.
    1 change: 1 addition & 0 deletions tic-tac-toe.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    console.log('test')