221226有限狀態(tài)機(jī)

參考文檔:

https://www.cnblogs.com/double12gzh/p/13621445.html

有限狀態(tài)機(jī)(FSM)是一個抽象的機(jī)器纹烹,任何時刻該機(jī)器都處于某個狀態(tài),且狀態(tài)總數(shù)有限钦无。該機(jī)器可以根據(jù)輸入晒衩,從一個狀態(tài)轉(zhuǎn)換到另一個狀態(tài)中歹颓。
三個關(guān)鍵要素:初始狀態(tài),可能狀態(tài)列表番官,觸發(fā)狀態(tài)變化的輸入

第一種實(shí)現(xiàn)思路

package main

import(
    "bufio"
    "fmt"
    "log"
    "os"
    "strings"
)

type State uint32

const (
    Locked State = iota
    Unlocked
)

const (
    dzToubi = "coin"
    dzTuiGan = "push"
)

func main() {
    state := Locked //初始狀態(tài),鎖定
    prompt(state)
    
    reader := bufio.NewReader(os.Stdin)
    for {
        cmd, err := reader.ReadString('\n')
        if err != nil {
            log.Fatalln(err)
        }
        cmd = strings.TrimSpace(cmd)
        
        switch state {
            case Locked:
                if cmd == dzToubi {
                    fmt.Println("解鎖,請通行")
                    state = Unlocked
                } else if cmd == dzTuiGan {
                    fmt.Println("禁止通行裆蒸,請先解鎖")
                } else {
                    fmt.Println("無效命令,請重新輸入")
                }
            case Unlocked:
                if cmd == dzToubi {
                    fmt.Println("門已開蚂四,投幣算是慈善了")                  
                } else if cmd == dzTuiGan {
                    fmt.Println("請通行光戈,隨后道閘關(guān)閉")
                    state = Locked
                } else {
                    fmt.Println("無效命令哪痰,請重新輸入")
                }
        }
        
    }
    
}

func prompt(s State) {
    m := map[State]string {
        Locked: "關(guān)閉",
        Unlocked: "開通",
    }
    fmt.Printf("當(dāng)前閘機(jī)狀態(tài)為:[%s]遂赠,你下一步的動作是:[ coin | push ]\n", m[s])
}

優(yōu)化后的解法

package main

import(
    "bufio"
    "fmt"
    "log"
    "os"
    "strings"
)

type State uint32

const (
    Locked State = iota
    Unlocked
)

const (
    CmdCoin = "coin"
    CmdPush = "push"
)

type Turnstile struct {
    s State
}

func (p *Turnstile) ExecuteCmd( cmd string ) {
    //以當(dāng)前狀態(tài)和收到的命令構(gòu)成一個二元組
    tupple := StateCmdTupple{p.s, strings.TrimSpace(cmd)}
    
    //通過二元組查詢狀態(tài)轉(zhuǎn)換表,獲得一個轉(zhuǎn)換函數(shù)
    //本例中晌杰,這個表是通過map實(shí)現(xiàn)的跷睦,二元組是Key
    if f := StateTransitionTable[tupple]; f == nil {
        fmt.Println("無效命令,請重試")
    } else {
        f(&p.s)
    }   
}


type StateCmdTupple struct {
    s State
    c string
}

type TransitionFunc func(s *State)

var StateTransitionTable = map[StateCmdTupple]TransitionFunc {
    {Locked, CmdCoin}: func(s *State){
        fmt.Println("已解鎖肋演,請通行抑诸。")
        *s = Unlocked
    },
    {Locked, CmdPush}: func(s *State){
        fmt.Println("禁止通行烂琴,請先投幣。")
    },
    {Unlocked, CmdCoin}: func(s *State){
        fmt.Println("多投的幣會捐給國家蜕乡。")
    },
    {Unlocked, CmdPush}: func(s *State){
        fmt.Println("請盡快通行奸绷,通過后閘機(jī)鎖定。")
        *s = Locked
    },
} 

func prompt(s State) {
    m := map[State]string{
        Locked: "鎖定",
        Unlocked: "解鎖",
    }
    fmt.Printf("閘機(jī)當(dāng)前的狀態(tài)是: [%s], 請輸入命令(coin或push)\n", m[s])
}


func main() {
    machine := &Turnstile{Locked}
    prompt(machine.s)
    
    r := bufio.NewReader(os.Stdin)
    for {
        cmd, err := r.ReadString('\n')
        if err != nil {
            log.Fatalln(err)
        }
        machine.ExecuteCmd(cmd)
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末层玲,一起剝皮案震驚了整個濱河市号醉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辛块,老刑警劉巖畔派,帶你破解...
    沈念sama閱讀 223,126評論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異润绵,居然都是意外死亡线椰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評論 3 400
  • 文/潘曉璐 我一進(jìn)店門尘盼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來憨愉,“玉大人,你說我怎么就攤上這事卿捎±绸茫” “怎么了?”我有些...
    開封第一講書人閱讀 169,941評論 0 366
  • 文/不壞的土叔 我叫張陵娇澎,是天一觀的道長笨蚁。 經(jīng)常有香客問我,道長趟庄,這世上最難降的妖魔是什么括细? 我笑而不...
    開封第一講書人閱讀 60,294評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮戚啥,結(jié)果婚禮上奋单,老公的妹妹穿的比我還像新娘。我一直安慰自己猫十,他們只是感情好览濒,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,295評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拖云,像睡著了一般贷笛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宙项,一...
    開封第一講書人閱讀 52,874評論 1 314
  • 那天乏苦,我揣著相機(jī)與錄音,去河邊找鬼。 笑死汇荐,一個胖子當(dāng)著我的面吹牛洞就,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掀淘,決...
    沈念sama閱讀 41,285評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼旬蟋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了革娄?” 一聲冷哼從身側(cè)響起咖为,我...
    開封第一講書人閱讀 40,249評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎稠腊,沒想到半個月后躁染,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,760評論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡架忌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,840評論 3 343
  • 正文 我和宋清朗相戀三年吞彤,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叹放。...
    茶點(diǎn)故事閱讀 40,973評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡饰恕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出井仰,到底是詐尸還是另有隱情埋嵌,我是刑警寧澤,帶...
    沈念sama閱讀 36,631評論 5 351
  • 正文 年R本政府宣布俱恶,位于F島的核電站雹嗦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏合是。R本人自食惡果不足惜了罪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,315評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望聪全。 院中可真熱鬧泊藕,春花似錦、人聲如沸难礼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛾茉。三九已至讼呢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間臀稚,已是汗流浹背吝岭。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評論 1 275
  • 我被黑心中介騙來泰國打工三痰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吧寺,地道東北人窜管。 一個月前我還...
    沈念sama閱讀 49,431評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像稚机,于是被迫代替她去往敵國和親幕帆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,982評論 2 361