gpt4 book ai didi

haskell - 回合制游戏中用户可扩展移动效果的一般方法?

转载 作者:行者123 更新时间:2023-12-02 03:13:32 24 4
gpt4 key购买 nike

回合制游戏的简单形式可以用函数式语言抽象为:

data Player 
= PlayerA
| PlayerB
deriving Show

data Game state move = Game {
start :: state,
turn :: (move, move)
-> state
-> Either Player state}

play :: [(m, m)] -> Game s m -> Maybe Player
play moves game
= either Just (const Nothing)
$ foldr tick (Right (start game)) moves where
tick move (Right state) = turn game move state
tick move p = p

在该设置中,游戏有一个初始状态、一种有效移动,以及一个根据每个玩家在该回合选择的移动计算下一个状态(或获胜者)的函数。这个定义足以创建任何类型的回合制游戏——从简单的剪刀石头布到功能齐全的战斗角色扮演游戏。这是一个简单的决斗游戏:

data DuelMove = Punch | Guard | Rest

data DuelState = DuelState {
p1hp :: Int,
p2hp :: Int}
deriving Show

duel :: Game DuelState DuelMove
duel = Game start turn where

start = DuelState 4 4

turn (ma,mb) (DuelState p1 p2)
| p1 <= 0 = Left PlayerB
| p2 <= 0 = Left PlayerA
| otherwise = attack ma mb where
attack Punch Punch = Right (DuelState (p1-1) (p2-1))
attack Punch Guard = Right (DuelState (p1-2) (p2+0))
attack Punch Rest = Right (DuelState (p1+0) (p2-2))
attack Guard Punch = Right (DuelState (p1+0) (p2-2))
attack Guard Guard = Right (DuelState (p1+0) (p2+0))
attack Guard Rest = Right (DuelState (p1+0) (p2+2))
attack Rest Punch = Right (DuelState (p1-2) (p2+0))
attack Rest Guard = Right (DuelState (p1+0) (p2+2))
attack Rest Rest = Right (DuelState (p1+2) (p2+2))

main :: IO ()
main = print $ play moves duel where
moves = [
(Punch, Punch),
(Punch, Guard),
(Guard, Punch),
(Rest, Rest),
(Punch, Guard),
(Guard, Punch),
(Punch, Rest)]

不过,这种抽象存在一个问题:添加新 Action 需要编辑类型的定义,因此需要编辑 turn 的源代码。如果您想让您的用户定义他们自己的 Action ,这还不够。是否有类似回合制游戏的抽象,优雅地允许在不修改原始代码的情况下添加新 Action ?

最佳答案

一个简单的技巧是参数化 turn 函数。因此:

type DuelMovePlus = Either DuelMove

turn :: (a -> DuelMove -> Either Player DuelState)
-> (DuelMove -> a -> Either Player DuelState)
-> (a -> a -> Either Player DuelState)
-> DuelMovePlus a -> DuelMovePlus a -> Either Player DuelState
turn userL userR userLR = \case
(Left l, Left r) -> {- same code as before -}
(Left l, Right r) -> userR l r
(Right l, Left r) -> userL l r
(Right l, Right r) -> userLR l r

关于haskell - 回合制游戏中用户可扩展移动效果的一般方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38423611/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com