Рассмотрим простую игру для двух игроков, в которую играют следующим образом: в ряд выложено четное количество монет. По очереди каждый игрок убирает монету на одном из концов ряда. Цель состоит в том, чтобы иметь наибольшее значение в монетах, когда все монеты были взяты.
Игрок один находит сумму всех монет с четным номером и всех монет с нечетным номером. Если сумма монет с нечетным номером выше, игрок один берет самую левую монету; в противном случае он берет самое правое.
У второго игрока теперь есть выбор с нечетным количеством монет. Взятие первой или последней монеты приведет к несколько другому списку монет для первого игрока. Второй игрок использует результат рекурсивного поиска, чтобы определить, выбрать первую или последнюю монету.
И я хочу иметь возможность каким-то образом реализовать многопоточность в рекурсивной функции p2-helper
, только теперь убедитесь, как это сделать. Любые предложения или идеи будут с благодарностью, спасибо!
(ns game.core
(:gen-class))
; function that returns the vector of a string (split up by spaces)
(defn vector-from-string [s]
(drop 1 (map read-string (clojure.string/split (clojure.string/trim-newline s) #" "))))
; function that returns the slurped string of a read-in file
(defn string-from-file [f]
(slurp f))
; function that returns the sum of all the odd-indexed items in a vector
(defn sum-of-evens [v]
(reduce + (take-nth 2 (rest v))))
; function that returns the sum of all the odd-indexed items in a vector
(defn sum-of-odds [v]
(reduce + (take-nth 2 v)))
; function that returns the vector that is left after player one moves, and then the coin that player one took
(defn p1 [v]
(if (> (sum-of-odds v) (sum-of-evens v))
[(drop 1 v) (first v)]
[(drop-last v) (last v)]))
; nearly identical to 'p1' but this function only returns the affected vector after player 1 has moved
(defn p2-p1 [v]
(if (even? (count v))
(if (> (sum-of-odds v) (sum-of-evens v))
(drop 1 v)
(drop-last v))
(drop 0 v)))
; recursive search for player two
(defn p2-helper [v]
(if (or (= (count v) 1) (= (count v) 0))
(reduce + v)
(max (+ (p2-helper (drop 1 (p2-p1 v))) (first (p2-p1 v))) (+ (p2-helper (drop-last (p2-p1 v))) (last (p2-p1 v))))))
; function that returns the vector that is left after player two moves, and then the coin that player two took
(defn p2 [v]
(if (> (+ (p2-helper (drop 1 (p2-p1 v))) (first (p2-p1 v))) (+ (p2-helper (drop-last (p2-p1 v))) (last (p2-p1 v))))
[(drop 1 v) (first v)]
[(drop-last v) (last v)]))
; function to play the game out until no coins are left
(defn play-game [v]
(def coins v)
(def p1score 0)
(def p2score 0)
(while (not (empty? coins))
(do
(let [[new-vec score] (p1 coins)]
(def coins new-vec)
(def p1score (+ p1score score)))
(let [[new-vec score] (p2 coins)]
(def coins new-vec)
(def p2score (+ p2score score)))))
(println "player 1 score:" p1score)
(println "player 2 score:" p2score))
; main
(defn -main [& args]
(let [v (vector-from-string (string-from-file "10.txt")) ]
(play-game v)))