Advertisement
finalmail

tictactoev1

Nov 24th, 2019
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const readline = require("readline").createInterface({
  2.   input: process.stdin,
  3.   output: process.stdout
  4. })
  5.  
  6. let PLAYER = "X"
  7. let CPU = "O"
  8.  
  9. // cpu is with max
  10.  
  11. const decr = x => x - 1
  12.  
  13. const parseWinner = w => {
  14.   if (w === PLAYER) {
  15.     return "PLAYER wins"
  16.   }
  17.  
  18.   if (w === CPU) {
  19.     return "CPU wins"
  20.   }
  21.  
  22.   return "Tie."
  23. }
  24.  
  25. const generateBoard = () => {
  26.   const brd = []
  27.   for (let i = 0; i < 3; i++) {
  28.     brd.push(Array.from({ length: 3 }, () => "_"))
  29.   }
  30.   return brd
  31. }
  32.  
  33. const printBoard = board => {
  34.   board.forEach(row => {
  35.     console.log(row.join(" "))
  36.   })
  37.   console.log()
  38. }
  39.  
  40. const isValid = (board, row, col) =>
  41.   0 <= row && row <= 2 && 0 <= col && col <= 2 && board[row][col] === "_"
  42.  
  43. const getWinner = board => {
  44.   for (let i = 0; i < 3; i++) {
  45.     if (
  46.       board[0][i] !== "_" &&
  47.       board[0][i] === board[1][i] &&
  48.       board[1][i] === board[2][i]
  49.     ) {
  50.       return board[0][i]
  51.     }
  52.   }
  53.  
  54.   for (let i = 0; i < 3; i++) {
  55.     if (
  56.       board[i][0] !== "_" &&
  57.       board[i][0] === board[i][1] &&
  58.       board[i][1] === board[i][2]
  59.     ) {
  60.       return board[i][0]
  61.     }
  62.   }
  63.  
  64.   if (
  65.     board[0][0] !== "_" &&
  66.     board[0][0] === board[1][1] &&
  67.     board[1][1] === board[2][2]
  68.   ) {
  69.     return board[0][0]
  70.   }
  71.  
  72.   if (
  73.     board[0][2] !== "_" &&
  74.     board[0][2] === board[1][1] &&
  75.     board[1][1] === board[2][0]
  76.   ) {
  77.     return board[0][2]
  78.   }
  79.  
  80.   // _ if tie, undefined if still no winner
  81.   return board.every(row => row.every(el => el !== "_")) ? "_" : undefined
  82. }
  83.  
  84. function min(board, level = 0, alphaIn = -Infinity, betaIn = Infinity) {
  85.   let minValue = Infinity
  86.   let minRow = undefined
  87.   let minCol = undefined
  88.  
  89.   let alpha = alphaIn
  90.   let beta = betaIn
  91.  
  92.   const winner = getWinner(board)
  93.   if (winner === PLAYER) {
  94.     return [-1 * (10 - level)]
  95.   }
  96.   if (winner === CPU) {
  97.     return [1 * (10 - level)]
  98.   }
  99.   if (winner === "_") {
  100.     return [0]
  101.   }
  102.  
  103.   for (let i = 0; i < 3; i++) {
  104.     for (let j = 0; j < 3; j++) {
  105.       if (board[i][j] === "_") {
  106.         board[i][j] = PLAYER
  107.         let [maxValue] = max(board, level + 1, alpha, beta)
  108.         if (maxValue < minValue) {
  109.           minValue = maxValue
  110.           minRow = i
  111.           minCol = j
  112.         }
  113.         board[i][j] = "_"
  114.  
  115.         if (minValue <= alpha) {
  116.           return [minValue, minRow, minCol]
  117.         }
  118.  
  119.         if (minValue < beta) {
  120.           beta = minValue
  121.         }
  122.       }
  123.     }
  124.   }
  125.  
  126.   return [minValue, minRow, minCol]
  127. }
  128.  
  129. function max(board, level = 0, alphaIn = -Infinity, betaIn = Infinity) {
  130.   let maxValue = -Infinity
  131.   let maxRow = undefined
  132.   let maxCol = undefined
  133.  
  134.   let alpha = alphaIn
  135.   let beta = betaIn
  136.  
  137.   const winner = getWinner(board)
  138.   if (winner === PLAYER) {
  139.     return [-1 * (10 - level)]
  140.   }
  141.   if (winner === CPU) {
  142.     return [1 * (10 - level)]
  143.   }
  144.   if (winner === "_") {
  145.     return [0]
  146.   }
  147.  
  148.   for (let i = 0; i < 3; i++) {
  149.     for (let j = 0; j < 3; j++) {
  150.       if (board[i][j] === "_") {
  151.         board[i][j] = CPU
  152.         let [minValue] = min(board, level + 1, alpha, beta)
  153.         if (minValue > maxValue) {
  154.           maxValue = minValue
  155.           maxRow = i
  156.           maxCol = j
  157.         }
  158.         board[i][j] = "_"
  159.  
  160.         if (maxValue >= beta) {
  161.           return [maxValue, maxRow, maxCol]
  162.         }
  163.  
  164.         if (maxValue > alpha) {
  165.           alpha = maxValue
  166.         }
  167.       }
  168.     }
  169.   }
  170.  
  171.   return [maxValue, maxRow, maxCol]
  172. }
  173.  
  174. // main
  175. const board = generateBoard()
  176. printBoard(board)
  177.  
  178. let linesRead = 0
  179. let firstPlayer = "PLAYER"
  180.  
  181. readline.on("line", line => {
  182.   if (linesRead++ === 0) {
  183.     firstPlayer = line
  184.     if (firstPlayer === "CPU") {
  185.       CPU = "X"
  186.       PLAYER = "O"
  187.     } else {
  188.       const [_, i, j] = min(board)
  189.       console.log(`The algorithm suggests you pick ${i + 1} ${j + 1}`)
  190.       return
  191.     }
  192.   }
  193.  
  194.   // player
  195.   if (linesRead > 1 || firstPlayer !== "CPU") {
  196.     const [row, col] = line
  197.       .split(" ")
  198.       .map(Number)
  199.       .map(decr)
  200.  
  201.     const valid = isValid(board, row, col)
  202.     if (!valid) {
  203.       console.log("Invalid move, try again.")
  204.       return
  205.     }
  206.  
  207.     board[row][col] = PLAYER
  208.     printBoard(board)
  209.   }
  210.  
  211.   const winner = getWinner(board)
  212.   if (winner) {
  213.     console.log(parseWinner(winner))
  214.     readline.close()
  215.     return
  216.   } else {
  217.     // CPU
  218.     const [_, i, j] = max(board)
  219.     board[i][j] = CPU
  220.     printBoard(board)
  221.  
  222.     const winnerAfterCpu = getWinner(board)
  223.     if (winnerAfterCpu) {
  224.       console.log(parseWinner(winnerAfterCpu))
  225.       readline.close()
  226.       return
  227.     }
  228.   }
  229.  
  230.   const [_, i, j] = min(board)
  231.   console.log(`The algorithm suggests you pick ${i + 1} ${j + 1}`)
  232. })
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement