16-状态模式
16-状态模式
1.分支判断法实现状态机
public enum State {
SMALL(0),
SUPER(1),
FIRE(2),
CAPE(3);
private final int value;
private State(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
public class MarioStateMachine {
private int score;
private State currentState;
public MarioStateMachine() {
this.score = 0;
this.currentState = State.SMALL;
}
// 吃了蘑菇,分数加100,状态变为SUPER。
public void obtainMushRoom() {
if (this.currentState.equals(State.SMALL)) {
this.currentState = State.SUPER;
this.score += 100;
}
}
// 获得斗篷,分数加200,状态变为CAPE。
public void obtainCape() {
if (this.currentState.equals(State.SMALL) || this.currentState.equals(State.SUPER)) {
this.currentState = State.CAPE;
this.score += 200;
}
}
// 获得火焰,分数加300,状态变为FIRE。
public void obtainFireFlower() {
if (this.currentState.equals(State.SMALL) || this.currentState.equals(State.SUPER)) {
this.currentState = State.FIRE;
this.score += 300;
}
}
// 遇到怪物。
public void meetMonster() {
if (this.currentState.equals(State.SUPER)) {
this.currentState = State.SMALL;
this.score -= 100;
return;
}
if (this.currentState.equals(State.CAPE)) {
this.currentState = State.SMALL;
this.score -= 200;
return;
}
if (this.currentState.equals(State.FIRE)) {
this.currentState = State.SMALL;
this.score -= 300;
}
}
public int getScore() {
return score;
}
public State getCurrentState() {
return currentState;
}
}
2.查表法实现状态机
public enum State {
SMALL(0),
SUPER(1),
FIRE(2),
CAPE(3);
private final int value;
private State(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
public enum Event {
OBTAIN_MUSHROOM(0),
OBTAIN_CAPE(1),
OBTAIN_FIRE(2),
MEET_MONSTER(3);
private final int value;
private Event(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
public class MarioStateMachine {
private int score;
private State currentState;
/*
obtainMushRoom(吃蘑菇) obtainCape(遇到斗篷) obtainFireFlower(遇到火) meetMonster(遇到怪物)
SMALL SUPER CAPE FIRE SMALL
SUPER SUPER CAPE FIRE SMALL
CAPE CAPE CAPE CAPE SMALL
FIRE FIRE FIRE FIRE SMALL
*/
private static final State[][] transitionTable = {
{State.SUPER, State.CAPE, State.FIRE, State.SMALL},
{State.SUPER, State.CAPE, State.FIRE, State.SMALL},
{State.CAPE, State.CAPE, State.CAPE, State.SMALL},
{State.FIRE, State.FIRE, State.FIRE, State.SMALL},
};
private static final int[][] actionTable = {
{+100, +200, +300, +0},
{+0, +200, +300, -100},
{+0, +0, +0, -200},
{+0, +0, +0, -300},
};
public MarioStateMachine() {
this.score = 0;
this.currentState = State.SMALL;
}
// 吃了蘑菇,分数加100,状态变为SUPER。
public void obtainMushRoom() {
executeEvent(Event.OBTAIN_MUSHROOM);
}
// 获得斗篷,分数加200,状态变为CAPE。
public void obtainCape() {
executeEvent(Event.OBTAIN_CAPE);
}
// 获得火焰,分数加300,状态变为FIRE。
public void obtainFireFlower() {
executeEvent(Event.OBTAIN_FIRE);
}
// 遇到怪物。
public void meetMonster() {
executeEvent(Event.MEET_MONSTER);
}
private void executeEvent(Event event) {
int stateValue = currentState.getValue();
int eventValue = event.getValue();
this.currentState = transitionTable[stateValue][eventValue];
this.score += actionTable[stateValue][eventValue];
}
public int getScore() {
return score;
}
public State getCurrentState() {
return currentState;
}
}
3.状态模式实现状态机
public enum State {
SMALL(0),
SUPER(1),
FIRE(2),
CAPE(3);
private final int value;
private State(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
// 所有状态类接口
public interface IMario {
State getName();
void obtainMushRoom();
void obtainCape();
void obtainFireFlower();
void obtainMonster();
}
public class SmallMario implements IMario {
private final MarioStateMachine stateMachine;
public SmallMario(MarioStateMachine stateMachine) {
this.stateMachine = stateMachine;
}
@Override
public State getName() {
return State.SMALL;
}
@Override
public void obtainMushRoom() {
stateMachine.setCurrentState(new SuperMario());
stateMachine.setScore(stateMachine.getScore() + 100);
}
@Override
public void obtainCape() {
stateMachine.setCurrentState(new CapeMario());
stateMachine.setScore(stateMachine.getScore() + 200);
}
@Override
public void obtainFireFlower() {
stateMachine.setCurrentState(new FireMario());
stateMachine.setScore(stateMachine.getScore() + 300);
}
@Override
public void obtainMonster() {
// 游戏结束
}
}
// 省略SuperMario、CapeMario和FireMario
public class MarioStateMachine {
private int score;
private IMario currentState;
public MarioStateMachine() {
this.score = 0;
this.currentState = new SmallMario(this);
}
// 吃了蘑菇,分数加100,状态变为SuperMario。
public void obtainMushRoom() {
this.currentState.obtainMushRoom();
}
// 获得斗篷,分数加200,状态变为CapeMario。
public void obtainCape() {
this.currentState.obtainCape();
}
// 获得火焰,分数加300,状态变为FireMario。
public void obtainFireFlower() {
this.currentState.obtainFireFlower();
}
// 遇到怪物。
public void meetMonster() {
this.currentState.obtainMonster();
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public IMario getCurrentState() {
return currentState;
}
public void setCurrentState(IMario currentState) {
this.currentState = currentState;
}
}
4.状态模式总结
- 状态机的实现有三种方式:分支判断法、查表法和状态模式。
- 分支法适用于简单的状态机,对于复杂的状态机使用分支法会出现大量冗余的代码。
- 查表法适用于复制的状态机。
- 状态模式适用于每种状态的处理包含复制的逻辑,并且有较少的状态,如果状态较多,这产生较多的状态类。
- 对于游戏类应用,包含的状态比较多,状态模式会引入非常多的状态类,将导致代码比较难维护,因此可以优先使用查表法;对于电商下单、外卖下单类应用,包含的状态较少,但是状态触发执行的业务逻辑可能比较复杂,因此可以优先使用状态模式。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗