<commit_before># coffeelint: disable=max_line_length
{MAX, MIN} = require 'aye-aye'

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

# empty board
empty = [
  _, _, _, _, _, _, _
  _, _, _, _, _, _, _
  _, _, _, _, _, _, _
  _, _, _, _, _, _, _
  _, _, _, _, _, _, _
  _, _, _, _, _, _, _
]

flatten = (a) -> a.reduce (l, r) -> l.concat r

winnableRows = (a) ->
  flatten (a[i+j...i+j+4] for i in [0...4] for j in [0...6*7] by 7)

winnableColumns = (a) ->
  flatten ([a[i+j*7],a[i+7+j*7],a[i+7*2+j*7],a[i+7*3+j*7]] for i in [0...7] for j in [0...3])

winnableDiagonalsL = (a) ->
  flatten ([a[i+j*7],a[i+7+1+j*7],a[i+7*2+2+j*7],a[i+7*3+3+j*7]] for i in [0...4] for j in [0...3])

winnableDiagonalsR = (a) ->
  flatten ([a[i+j*7],a[i+7-1+j*7],a[i+7*2-2+j*7],a[i+7*3-3+j*7]] for i in [3...7] for j in [0...3])

winnableLines = (a) ->
  [(winnableRows a)..., (winnableColumns a)..., (winnableDiagonalsL a)..., (winnableDiagonalsR a)...]

isWin = (a, W) ->
  (winnableLines a).some (r) -> r.every (e) -> e is W

isFull = (a) ->
  not a.some (e) -> e is _

isTerminal = (a) ->
  (isFull a) or (isWin a, X) or (isWin a, O)

openColumns = (a) ->
  i for e, i in a[0...7] when e is _

freePositions = (a) ->
  res = []
  for columnIndex in openColumns a
    for rowIndex in [5..0]
      index = rowIndex*7+columnIndex
      res.push index if a[index] is _
  res

play = (a, columnIndex, W) ->
  for rowIndex in [5..0]
    index = rowIndex*7+columnIndex
    break if a[index] is _
  [a[0...index]..., W, a[index+1..]...]

evaluate = (a) ->
  score = 0
  for l in winnableLines a
    [x, o] = [0, 0]
    for w in l
      ++x if w is X
      ++o if w is O
    score += 10**x - 10**o if x is 0 or o is 0
  score

class ConnectFour
  constructor: (@a = empty, @nextPlayer = X, @depth = 0) ->
  isWin: (W) -> isWin @a, W
  isTerminal: -> isTerminal @a
  nextAgent: -> if @nextPlayer is X then MAX else MIN
  utility: -> evaluate @a
  openPositions: -> openPositions @a
  possibleActions: -> openColumns @a
  play: (columnIndex) ->
    new @constructor (play @a, columnIndex, @nextPlayer), @opponent(), @depth + 1
  opponent: -> if @nextPlayer is X then O else X

module.exports = {
  _, X, O
  empty
  isWin, isFull, isTerminal
  freePositions, openColumns, play, evaluate
  ConnectFour
}<commit_msg>freePositions on ConnectFour<commit_after># coffeelint: disable=max_line_length
{MAX, MIN} = require 'aye-aye'

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

# empty board
empty = [
  _, _, _, _, _, _, _
  _, _, _, _, _, _, _
  _, _, _, _, _, _, _
  _, _, _, _, _, _, _
  _, _, _, _, _, _, _
  _, _, _, _, _, _, _
]

flatten = (a) -> a.reduce (l, r) -> l.concat r

winnableRows = (a) ->
  flatten (a[i+j...i+j+4] for i in [0...4] for j in [0...6*7] by 7)

winnableColumns = (a) ->
  flatten ([a[i+j*7],a[i+7+j*7],a[i+7*2+j*7],a[i+7*3+j*7]] for i in [0...7] for j in [0...3])

winnableDiagonalsL = (a) ->
  flatten ([a[i+j*7],a[i+7+1+j*7],a[i+7*2+2+j*7],a[i+7*3+3+j*7]] for i in [0...4] for j in [0...3])

winnableDiagonalsR = (a) ->
  flatten ([a[i+j*7],a[i+7-1+j*7],a[i+7*2-2+j*7],a[i+7*3-3+j*7]] for i in [3...7] for j in [0...3])

winnableLines = (a) ->
  [(winnableRows a)..., (winnableColumns a)..., (winnableDiagonalsL a)..., (winnableDiagonalsR a)...]

isWin = (a, W) ->
  (winnableLines a).some (r) -> r.every (e) -> e is W

isFull = (a) ->
  not a.some (e) -> e is _

isTerminal = (a) ->
  (isFull a) or (isWin a, X) or (isWin a, O)

openColumns = (a) ->
  i for e, i in a[0...7] when e is _

freePositions = (a) ->
  res = []
  for columnIndex in openColumns a
    for rowIndex in [5..0]
      index = rowIndex*7+columnIndex
      res.push index if a[index] is _
  res

play = (a, columnIndex, W) ->
  for rowIndex in [5..0]
    index = rowIndex*7+columnIndex
    break if a[index] is _
  [a[0...index]..., W, a[index+1..]...]

evaluate = (a) ->
  score = 0
  for l in winnableLines a
    [x, o] = [0, 0]
    for w in l
      ++x if w is X
      ++o if w is O
    score += 10**x - 10**o if x is 0 or o is 0
  score

class ConnectFour
  constructor: (@a = empty, @nextPlayer = X, @depth = 0) ->
  isWin: (W) -> isWin @a, W
  isTerminal: -> isTerminal @a
  nextAgent: -> if @nextPlayer is X then MAX else MIN
  utility: -> evaluate @a
  freePositions: -> freePositions @a
  possibleActions: -> openColumns @a
  play: (columnIndex) ->
    new @constructor (play @a, columnIndex, @nextPlayer), @opponent(), @depth + 1
  opponent: -> if @nextPlayer is X then O else X

module.exports = {
  _, X, O
  empty
  isWin, isFull, isTerminal
  freePositions, openColumns, play, evaluate
  ConnectFour
}
{'fraction_non_alphanumeric': 0.20883710705649594, 'fraction_numerical': 0.03209496592657727, 'mean_word_length': 2.7082314588427057, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1653665', 'n_tokens_mistral': 2037, 'n_tokens_neox': 1996, 'n_words': 532}