(ns challenge-0155.core
  (:require [clojure.string :refer [split]]
            [clojure.java.io :refer [reader]]))

(def initial-positions {:a {:1 :rook, :2 :pawn, :7 :pawn :8 :rook}
                        :b {:1 :knight, :2 :pawn, :7 :pawn :8 :knight}
                        :c {:1 :bishop, :2 :pawn, :7 :pawn :8 :bishop}
                        :d {:1 :queen, :2 :pawn, :7 :pawn :8 :queen}
                        :e {:1 :king, :2 :pawn, :7 :pawn :8 :king}
                        :f {:1 :bishop, :2 :pawn, :7 :pawn :8 :bishop}
                        :g {:1 :knight, :2 :pawn, :7 :pawn :8 :knight}
                        :h {:1 :rook, :2 :pawn, :7 :pawn :8 :rook}})

(def initial-score 39)

(def piece-values {:pawn 1, :knight 3, :bishop 3, :rook 5, :queen 9})

(def piece-name {"K" :king, "N" :knight, "Q" :queen, "R" :rook, "B" :bishop, "" :pawn})

(defn other-player [player]
  (case player
    :white :black
    :black :white))

(defn board-position
  "Translates a move (e.g. e5) to a board position (e.g. [:e :5])"
  [move]
  (map #(-> % str keyword) move))

(defn score-capture [player move board scores]
  (update-in scores [(other-player player)] - (piece-values (get-in board move))))

(defn score-en-passant [player scores]
  (update-in scores [(other-player player)] - 1))

(defn analyze-move [player move board scores]
  (let [[_ piece capture move promotion en-passant]
        (re-find #"([KNQRB]?)[a-h1-8]?(x?)([a-h][1-8])([KNQRB]?)((?:e.p.)?)" move)
        position (board-position move)
        piece (if (and (= "" piece) (not= "" promotion)) promotion piece)
        new-scores (or (when-not (= "" en-passant)
                         (score-en-passant player scores))
                       (when-not (= "" capture)
                         (score-capture player position board scores))
                       scores)]
    {:board (assoc-in board position (piece-name piece))
     :scores new-scores}))

(defn process-move [player move board scores]
  (cond
    (= move "O-O") (let [rank (if (= player :white) :1 :8)]
                     {:board  (assoc-in (assoc-in board [:g rank] :king) [:f rank] :rook)
                      :scores scores})
    (= move "O-O-O") (let [rank (if (= player :white) :1 :8)]
                       {:board  (assoc-in (assoc-in board [:c rank] :king) [:d rank] :rook)
                        :scores scores})
    :else (analyze-move player move board scores)))

(defn process-round [round board scores]
  (let [[_ wmove bmove] (split round #" ")
        {:keys [board scores]} (process-move :white wmove board scores)]
    (process-move :black bmove board scores)))

(defn process-input [lines]
  (loop [line (first lines)
         xs (next lines)
         board initial-positions
         scores {:white initial-score :black initial-score}]
    (let [{:keys [scores board]} (process-round line board scores)]
      (if xs
        (recur (first xs) (next xs) board scores)
        {:board board :scores scores}))))

(let [{:keys [scores]} (process-input (line-seq (reader *in*)))]
  (println (format "%d-%d" (:white scores) (:black scores))))