간결한 자바스크립트?
일상 업무에서는 아직 사용하지 않지만(아직?) 에 관해 Haskell에서 했던 것과 같은 방식으로 다른 언어가 문제에 접근하는 방식을 보고 해당 아이디어를 TypeScript에 다시 적용하는 것을 좋아합니다.
지난 주에 저는 Game of pure strategy problem 을 가지고 놀았고 Clojure에서 가능한 솔루션을 구현하려고 했습니다.
Clojurians Slack 채널에서 앞뒤로 몇 가지 좋은 피드백을 받은 후 다음과 같은 다음 상태 함수를 만들었습니다.
(def initial-state "Initial game state"
{:first-player {:deck #{1 2 3 4 5 6 7 8 9 10 11 12 13} :score 0}
:second-player {:deck #{1 2 3 4 5 6 7 8 9 10 11 12 13} :score 0}
:bounty-deck #{1 2 3 4 5 6 7 8 9 10 11 12 13}})
(defn random-card-strategy [deck] (rand-nth (seq deck)))
(defn highest-card-strategy [deck] (apply max (seq deck)))
(def draw-card random-card-strategy)
(defn game-step [current-state]
(let [{:keys [bounty-deck first-player second-player]} current-state
drawn-card (draw-card bounty-deck)
first-player-card (random-card-strategy (:deck first-player))
second-player-card (highest-card-strategy (:deck second-player))
match-winner (if (> first-player-card second-player-card) :first-player :second-player)]
(-> current-state
(update-in [match-winner :score] inc)
(update-in [:bounty-deck] disj drawn-card)
(update-in [:first-player :deck] disj first-player-card)
(update-in [:second-player :deck] disj second-player-card))))
LISP는 일반적으로 매우 밀집된 언어로 알려져 있습니다. Clojure의 풍부한 seq 함수 및 매크로 세트도 고려하면 작은 코드 덩어리가 Clojure에서 많은 작업을 수행할 수 있습니다.
저는 (여전히) 주로 JavaScript/TypeScript 개발자이며 "동일한 최종 결과를 얻기 위해 작성할 수 있는 가장 간결한 코드는 무엇입니까?
나는 가능한 한 빨리 몇 가지 코드를 자갈로 만들었으며 이것이 내가 시작한 기준선입니다.
const initialState: State = {
bountyDeck: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
firstPlayer: {
score: 0,
deck: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
},
secondPlayer: {
score: 0,
deck: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
}
}
const randomCardStrategy = (deck: number[]) => deck[Math.floor(Math.random() * deck.length)];
const highestCardStrategy = (deck: number[]) => Math.max.apply(null, deck);
const drawCard = randomCardStrategy;
const gameStep = (currentState: State): State => {
const drawnCard = drawCard(currentState.bountyDeck);
const firstPlayerCard = randomCardStrategy(currentState.firstPlayer.deck);
const secondPlayerCard = highestCardStrategy(currentState.firstPlayer.deck);
const matchWinner = firstPlayerCard > secondPlayerCard ? 'firstPlayer' : 'secondPlayer'
return {
bountyDeck: currentState.bountyDeck.splice(currentState.bountyDeck.indexOf(drawnCard), 1),
firstPlayer: {
deck: currentState.firstPlayer.deck.filter(c => c >== firstPlayerCard),
score: matchWinner === 'firstPlayer' ? currentState.firstPlayer.score++ : currentState.firstPlayer.score
},
secondPlayer: {
deck: currentState.secondPlayer.deck.filter(c => c >== firstPlayerCard),
score: matchWinner === 'secondPlayer' ? currentState.firstPlayer.score++ : currentState.firstPlayer.score
},
}
}
이 스니펫에서 유형 정의는 실제 코드의 일부가 아니므로 생략했습니다.
여기에서 문제는 JavaScript에 변경 사항을 적용할 수 있는 훌륭한 스토리가 없다는 것이 분명하지만 Lens 라이브러리를 사용하여 더 나은 작업을 수행할 수 있습니다. monocle-ts
보일러 플레이트가 없으면 고려해야 할 최종 코드는 다음과 같습니다.
const gameStep = (currentState: State): State => {
const drawnCard = drawCard(currentState.bountyDeck);
const firstPlayerCard = randomCardStrategy(currentState.firstPlayer.deck);
const secondPlayerCard = highestCardStrategy(currentState.firstPlayer.deck);
const matchWinner = firstPlayerCard > secondPlayerCard ? "firstPlayer" : "secondPlayer";
return pipe(
currentState,
matchWinner === "firstPlayer" ? incrementFirstPlayerScore : incrementSecondPlayerScore,
removeBountyDeckCard(drawnCard),
removeFirstPlayerDrawnCard(firstPlayerCard),
removeSecondPlayerDrawnCard(secondPlayerCard)
);
};
… 이는 Clojure의 대응물과 그리 멀지 않습니다.
<올>
a.b.c
)이 없으면 구조화 및 스레딩 매크로가 Clojure에서 매우 중요해집니다. 그들 없이는 : (-> structure :first-player :deck :card :somethingelse)
다음과 같을 것입니다:(:somethingelse (:card (:deck (:first-player structure))))
별로 좋지 않은 것 같아요.
P.S: 알고 있습니다ImmutableJS . 그러나 타이핑에 대한 그들의 이야기는 monocle-ts가 제공하는 것만큼 세련되지 않았기 때문에 선택에서 일찍 제거했습니다.
Reference
이 문제에 관하여(간결한 자바스크립트?), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/vncz/succinct-javascript-4ob7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)