3
를 사용할 수 있다고 생각
내 작은 축구 게임의 AI 코드는 기본적으로 다음과 같이 작동하스켈 : 내가 정말 여기에 리스프와 같은 매크로
deriveFacts :: GameState -> [Fact]
: 피치의 현재 상황을 설명하는 사실을 생성하는 기능이 있습니다 사실이 같은 종류의 볼
... :
data Fact =
FactCanIntercept ObjId ObjId
| FactBestPosition Team Spot Spot
| FactKickOff
| FactBallCarrier ObjId
| FactBestShootingVector Velocity3
| FactBestPassingVector Velocity3
| ...
...와 같이 균일하게 보이는 규칙이 있습니다 :
rule_shoot facts = do
FactBallCarrier ballCarrier <- checkBallCarrier facts
FactBestShootingVector goalVector <- checkBestShootingVector facts
return [message (ballCarrier, shoot goalVector)]
그리고 나서 모든 규칙을 실행하고 결과 메시지를 수집하는 규칙 엔진이 있습니다.
지금까지는 문제가 없었으며 아주 잘 작동합니다. 뭐, 그래도 가지 짜증나 :이 방법에서, 나는 모든 사실이 같은 "접근"기능이 필요합니다
checkBestShootingVector :: [Fact] -> Maybe Fact
checkBestShootingVector facts =
listToMaybe [e | [email protected](FactBestShootingVector {}) <- facts]
이 방법은 추한 상용구 코드의 많은 리드. 내 질문 : 수동으로 이러한 접근 자 함수를 만들지 않아도되는 우아한 솔루션이 있습니까? 당신은 bulti-에 접근 기능을 제공하는 레코드 객체
data FactRec = FR {
canIntercept :: [(ObjId,ObjId)], -- use lists for things you previously had multiple times
factBestPosition :: [(Team,Spot,Spot)], -- not sure about this one, maybe two entries not one list
kickOff :: Bool,
ballCarrier :: ObjID,
factBestShootingVector :: Velocity3,
factBestPassingVector :: Velocity3,
.....
}
로 사실 대부분의 데이터를 리팩토링 수
감사합니다. 내 생각에 대해 생각해보세요. 왜 사실 목록을 사용합니까? 처음에는 사실 목록을 사용했습니다 ... 그렇다면 그럴듯한 느낌이 들었습니다. 그러나 그 이유를 실제로 말할 수는 없습니다. – martingw
OP의 'rule_shoot'에 대한 원래 코드는 'Maybe'모나드를 사용하고 ' listToMaybe'는 목록의 첫 번째 요소를 반환 할 것이기 때문에 아마도'FR' 레코드는리스트와'Bool' 대신'Maybe' 타입으로 정의되어야합니다. 이 모든 것은'rule_shoot'가 어떻게 동작하는지에 달려 있습니다. – ErikR
@ user5402 일반적으로 - 나는 아마도 "아마도"그 물건이 그 목록에 당신이 있던 자료를 포함하지 않을 수도 있다는 사실을 다룰 것이라고 생각합니다. 어쨌든, 나는 이미 그 가능성과 그 일반화를 다루었 다. "진실로 그곳에 있을지 모를 수도있는 사실이 있다면, 그들은 아마도 뭔가 있을지 모릅니다. 거기에있을 수있는 사실이 있다면 목록 일 수 있습니다. " – AndrewC