Java 如何正确设计具有内部条件转换的游戏状态机
我有以下的状态是为了模拟游戏状态而设计的Java 如何正确设计具有内部条件转换的游戏状态机,java,state,state-machine,Java,State,State Machine,我有以下的状态是为了模拟游戏状态而设计的 enum GameStates{ Bet, CompleteBet, Bonus,CompleteBonus, Jackpot, CompleteJackpot } 只有Bet状态是游戏的外部状态(可以从外部触发)。其他所有状态都是内部状态,由游戏本身触发 如果我处于CompleteBet状态,游戏可以进入Bonus状态,但也可以返回到Bet状态(这是每个游戏的配置) 当处于CompleteBonus状态时,会重复相同的情况。游戏可以转换为下注或头奖
enum GameStates{ Bet, CompleteBet, Bonus,CompleteBonus, Jackpot, CompleteJackpot }
只有Bet
状态是游戏的外部状态(可以从外部触发)。其他所有状态都是内部状态,由游戏本身触发
如果我处于CompleteBet
状态,游戏可以进入Bonus
状态,但也可以返回到Bet
状态(这是每个游戏的配置)
当处于CompleteBonus
状态时,会重复相同的情况。游戏可以转换为下注
或头奖
状态
现在我用以下if-else
逻辑来处理这种情况
// In CompleteBet state
if (bonus.isEnabled) {
setState(Bonus);
} else {
if (jackpot.isEnabled) {
setState(Jackpot);
} else {
setState(Bet);
}
// in CompleteBonus state
if (jackpot.isEnabled) {
setState(Jackpot);
} else {
setState(Bet);
}
}
但显然这不是一个好的解决方案。也许我需要重新设计我的状态机?如有任何建议,我们将不胜感激
编辑:
实际上,GameState
enum的定义如下:
enum GameState implements TransferState {
WITHDRAW {
@Override
public void initiateStep(final GameContext context) {
//some logic which triggers complete transfer
}
},
COMPLETE_WITHDRAW {
@Override
public void completeTransfer(final GameContext context) {
// if bonus is enabled;
if (true) {
context.setState(BONUS);
} else {
// if remote gaming is on
if (true) {
context.setState(REMOTE_GAME);
} else {
context.setState(WITHDRAW);
}
}
}
}
// ...
}
initiateTransfer
和completTransfer
被定义为TransferState
界面中的默认方法。在这种情况下,我会将状态模式与责任链模式一起使用,并为您的案例提供示例
这是你的游戏
public class Game{
private IState state = new StateReady();
public void play(){
state.play(this);
}
public void setState(IState state){
this.state = state;
}
}
州
public StateReady implements IState{
private List<IGameHeadler> headler = new ArrayList<>();
public StateReady(){
headler.add(new BonusHeadler());
headler.add(new JackpotHeadler());
}
public void play(Game game){
//Your operation
//an example the operation is
Iterator iterator = headler.iterator();
boolean flag = false;
while(iterator.hasNext() && !flag){
IGameHeadler headler = (IGameHeadler)iterator.next();
flag = headler.doChain();
}
game.setState(new WaitState(game));
}
}
但游戏的状态将改变为
外螺纹
游戏课
另一个国家
对于任何对象,模式都是一种为已知问题提供解决方案的想法,但这种想法可以根据具体情况进行扩展
此外,责任链模式是一种很酷的模式,用于将逻辑划分为多个标题,在您的情况下,一个标题是If()
另外,我更喜欢使用另一种模式来创建一个状态,一个状态是唯一的,flyweight模式解决此问题我会删除枚举在这种情况下,我会使用状态模式和责任链模式,并为您的案例提供示例
这是你的游戏
public class Game{
private IState state = new StateReady();
public void play(){
state.play(this);
}
public void setState(IState state){
this.state = state;
}
}
州
public StateReady implements IState{
private List<IGameHeadler> headler = new ArrayList<>();
public StateReady(){
headler.add(new BonusHeadler());
headler.add(new JackpotHeadler());
}
public void play(Game game){
//Your operation
//an example the operation is
Iterator iterator = headler.iterator();
boolean flag = false;
while(iterator.hasNext() && !flag){
IGameHeadler headler = (IGameHeadler)iterator.next();
flag = headler.doChain();
}
game.setState(new WaitState(game));
}
}
但游戏的状态将改变为
外螺纹
游戏课
另一个国家
对于任何对象,模式都是一种为已知问题提供解决方案的想法,但这种想法可以根据具体情况进行扩展
此外,责任链模式是一种很酷的模式,用于将逻辑划分为多个标题,在您的情况下,一个标题是If()
另外,我更喜欢使用另一种模式来创建状态,一种状态是唯一的,flyweight模式解决此问题我会删除枚举我会使用状态模式,看这引用了我正在使用它。我有一个游戏上下文,它将其操作委托给我的状态。代码摘录自我的状态处理方法。你不使用模式状态,因为状态是一个对象而不是枚举。好了,责任链模式解决了你的问题。我更新了我的答案。我会使用状态模式,看这引用了我正在使用它。我有一个游戏上下文,它将其操作委托给我的状态。代码摘录自my States的处理方法。您不使用模式状态,因为状态是对象而不是枚举。现在可以了,责任链模式解决了您的问题。我更新我的答案