Advertisement
finalmail

tic final

Jan 23rd, 2020
131
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.         // const newBoard = setCell(board, i, j, CPU)
  153.         let [minValue] = min(board, level + 1, alpha, beta)
  154.         if (minValue > maxValue) {
  155.           maxValue = minValue
  156.           maxRow = i
  157.           maxCol = j
  158.         }
  159.         board[i][j] = "_"
  160.  
  161.         if (maxValue >= beta) {
  162.           return [maxValue, maxRow, maxCol]
  163.         }
  164.  
  165.         if (maxValue > alpha) {
  166.           alpha = maxValue
  167.         }
  168.       }
  169.     }
  170.   }
  171.  
  172.   return [maxValue, maxRow, maxCol]
  173. }
  174.  
  175. // main
  176. const board = generateBoard()
  177. printBoard(board)
  178.  
  179. let linesRead = 0
  180. let firstPlayer = "PLAYER"
  181.  
  182. readline.on("line", line => {
  183.   if (linesRead++ === 0) {
  184.     firstPlayer = line
  185.     if (firstPlayer === "CPU") {
  186.       // CPU = "X"
  187.       // PLAYER = "O"
  188.     } else {
  189.       const [_, i, j] = min(board)
  190.       console.log(`The algorithm suggests you pick ${i + 1} ${j + 1}`)
  191.       return
  192.     }
  193.   }
  194.  
  195.   // player
  196.   if (linesRead > 1 || firstPlayer !== "CPU") {
  197.     const [row, col] = line
  198.       .split(" ")
  199.       .map(Number)
  200.       .map(decr)
  201.  
  202.     const valid = isValid(board, row, col)
  203.     if (!valid) {
  204.       console.log("Invalid move, try again.")
  205.       return
  206.     }
  207.  
  208.     board[row][col] = PLAYER
  209.     printBoard(board)
  210.   }
  211.  
  212.   const winner = getWinner(board)
  213.   if (winner) {
  214.     console.log(parseWinner(winner))
  215.     readline.close()
  216.     return
  217.   } else {
  218.     // CPU
  219.     const [_, i, j] = max(board)
  220.     board[i][j] = CPU
  221.     printBoard(board)
  222.  
  223.     const winnerAfterCpu = getWinner(board)
  224.     if (winnerAfterCpu) {
  225.       console.log(parseWinner(winnerAfterCpu))
  226.       readline.close()
  227.       return
  228.     }
  229.   }
  230.  
  231.   const [_, i, j] = min(board)
  232.   console.log(`The algorithm suggests you pick ${i + 1} ${j + 1}`)
  233. })
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement