iT邦幫忙

DAY 24
0

蠻可愛的 Golang系列 第 24

油達大師 vs 玉面飛鷹

在前面的例子中,我們已經探討了Concurrent Programming
的一些案例.
Golang是屬於使用訊息交換的方式,來處理processes之間交換資料的需求.
也就是前面介紹過的channel.

今天來看看整合起來的範例.讓油達大師與玉面飛鷹打一下模擬的交戰.

程式大致上就是由Main()先建立一個channel,傳給兩個goroutine,
當作攻擊的計數器,兩個goroutine都從Main()接收了一個badluck的數字,
每次都會自己產生一個小於20亂數整數,當亂數與badluck相等時,就失敗,
會關閉channel,自己脫離;所以只要判斷channel是否被關閉,就知道對方是否出包,
然後宣佈自己獲勝,脫離.
我們也在goroutine應用了defer來通知workgroup,當兩個goroutine都脫離時,
Main()就能正常關閉.

// hello76
package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

var wg sync.WaitGroup

func init() {
	rand.Seed(time.Now().UnixNano())
}

func main() {
	hitcount := make(chan int)

	wg.Add(2)

	go 油達大師(hitcount, 13)
	go 玉面飛鷹(hitcount, 7)

	hitcount <- 1

	wg.Wait()

}

func 油達大師(hitcount chan int, badluck int) {
	name := "油達大師"
	defer wg.Done()

	for {
		mycount, ok := <-hitcount
		if !ok {
			fmt.Printf("%s贏了!!\n", name)
			return
		}
		n := rand.Intn(20)
		if n%badluck == 0 {
			fmt.Printf("%s內力耗盡!\n", name)
			close(hitcount)
			return
		}
		fmt.Printf("%s出了第%d招!\n", name, mycount)
		mycount++
		hitcount <- mycount
	}
}

func 玉面飛鷹(hitcount chan int, badluck int) {
	name := "玉面飛鷹"
	defer wg.Done()

	for {
		mycount, ok := <-hitcount
		if !ok {
			fmt.Printf("%s贏了!!\n", name)
			return
		}
		n := rand.Intn(20)
		if n%badluck == 0 {
			fmt.Printf("%s羽毛脫落!\n", name)
			close(hitcount)
			return
		}
		fmt.Printf("%s出了第%d招!\n", name, mycount)
		mycount++
		hitcount <- mycount
	}
}

執行過程:
因為是用亂數,每次都會不同.執行兩次看看.

./hello76 
油達大師出了第1招!
玉面飛鷹出了第2招!
油達大師出了第3招!
玉面飛鷹出了第4招!
油達大師出了第5招!
玉面飛鷹出了第6招!
油達大師內力耗盡!
玉面飛鷹贏了!!

./hello76 
油達大師出了第1招!
玉面飛鷹出了第2招!
油達大師出了第3招!
玉面飛鷹出了第4招!
油達大師出了第5招!
玉面飛鷹羽毛脫落!
油達大師贏了!!

上一篇
使用Mutex來鎖定資源
下一篇
分工合作
系列文
蠻可愛的 Golang30

尚未有邦友留言

立即登入留言