php小編新一為大家帶來了一個簡單卻有趣的Go模擬遊戲,名為「並發問題」。這款遊戲以並發程式設計為主題,讓玩家在虛擬的世界中體驗並發程式設計的魅力。遊戲中,玩家需要透過編寫程式碼來處理多個任務的同時執行,測試自己的並發程式設計能力。遊戲介面簡潔明了,操作簡單,適合初學者入門,也提供了多個難度和挑戰模式供玩家選擇。無論你是初學者還是有一定經驗的開發者,都能在這個模擬遊戲中享受到並發程式設計的樂趣。
我是來自波蘭的學生,這學期我開始了並發程式設計課程(Go、Ada 以及將來的一些理論和 CSP 語言)。說實話,Golang 看起來很有趣,但我有點困惑最重要的是,根據我的經驗,我稱自己為低於平均水平的程式設計師。基本上,我的任務是建立一個模擬,我將這樣描述:
有一個 n*m 格
可以隨機產生旅行者,最多 k 個旅行者,每個旅行者都有唯一的 ID(1、2、3 等等,最多 k)
在隨機時刻,如果空間空閒(我確定空閒空間為 0),旅行者可以在網格上向上、向左、向右或向下移動
還有一個鏡頭,有時會列印網格的當前狀態以及最近的移動(尚未實現)
非正式地,我聽說我應該使用頻道,無論這意味著什麼
我的想法是創建一個帶有 id 和每個旅行者座標的結構,並將他們的 id 發送到表示移動意願的通道,然後我會隨機選擇移動方向。
我對並發有點困惑 - 不僅是我是否以及在哪裡應該使用 wgs 和互斥體,而且例如如果我執行 go func(){} 循環應該在內部還是外部。我會非常高興感謝任何提示、幫助或修復/想法來修復我的程式碼,因為目前,正如您所猜測的,它無法正常工作(例如,當相機打印網格時,有時會有超過k 個旅行者,其中多個旅行者共享相同的號碼,有時它們似乎消失了)。希望每個人都度過愉快的一天,我真的很感激任何幫助:)
package main; import( "fmt" "os" "strconv" "math/rand" //"sync" "time" ) type traveler struct{ id int; x int; y int; } func main(){ //command line n, err := strconv.Atoi(os.Args[1]); m, err := strconv.Atoi(os.Args[2]); k, err := strconv.Atoi(os.Args[3]); if err != nil{ panic(err) return } //board var grid [][]int; grid = make([][]int, n) for i:=0; i<n; i++{ grid[i] = make([]int, m) } //array of travelers, channel for moves and id travelers := make([]traveler, k) no_of_travelers := 0; move := make(chan int, k); id := 1; //var wg sync.WaitGroup go camera(grid); go func() { for i:=0; i<len(travelers); i++ { if no_of_travelers<k{ travelers[i] = spawnTraveler(&id,grid); no_of_travelers++; } } }() go func() { for{ a:= rand.Intn(k); sendMoveTraveler(&travelers[a], move); } }() receiveMoveTraveler(travelers, move, grid); } func spawnTraveler(id *int, grid [][]int) traveler{ x:=-1; y:=-1; for{ x = rand.Intn(len(grid)); y = rand.Intn(len(grid)); if(grid[x][y]==0){ break; } } t := traveler{id: *id, x: x, y:y}; grid[x][y] = *id; *id++; return t; } func sendMoveTraveler(t *traveler, move chan int){ move <- t.id } func receiveMoveTraveler(travelers []traveler, move chan int, grid [][]int){ for{ id := <- move for i:=0; i<len(travelers); i++{ if travelers[i].id == id{ direction := rand.Intn(4); //1-left 2-up 3-right 4-down switch direction { case 0: if travelers[i].x>0 && grid[travelers[i].x-1][travelers[i].y] == 0{ grid[travelers[i].x-1][travelers[i].y] = grid[travelers[i].x][travelers[i].y]; grid[travelers[i].x][travelers[i].y] = 0; travelers[i].x = travelers[i].x-1; travelers[i].y = travelers[i].y; } case 1: if travelers[i].y>0 && grid[travelers[i].x][travelers[i].y-1] == 0{ grid[travelers[i].x][travelers[i].y-1] = grid[travelers[i].x][travelers[i].y]; grid[travelers[i].x][travelers[i].y] = 0; travelers[i].x = travelers[i].x; travelers[i].y = travelers[i].y-1; } case 2: if travelers[i].x<len(grid)-1 && grid[travelers[i].x+1][travelers[i].y] == 0{ grid[travelers[i].x+1][travelers[i].y] = grid[travelers[i].x][travelers[i].y]; grid[travelers[i].x][travelers[i].y] = 0; travelers[i].x = travelers[i].x+1; travelers[i].y = travelers[i].y; } case 3: if travelers[i].y<len(grid)-1 && grid[travelers[i].x][travelers[i].y+1] == 0{ grid[travelers[i].x][travelers[i].y+1] = grid[travelers[i].x][travelers[i].y]; grid[travelers[i].x][travelers[i].y] = 0; travelers[i].x = travelers[i].x; travelers[i].y = travelers[i].y+1; } } //fmt.Println("Ściagnalem ruch", travelers[i].id); } } } } func camera(grid [][]int){ for{ for i:=0; i<len(grid); i++{ for j:=0; j<len(grid); j++{ if grid[i][j]!= 0{ fmt.Printf("%02d ", grid[i][j]); } else{ fmt.Printf("-- "); } } fmt.Println(); } fmt.Println(); time.Sleep(time.Second * 3); } }
所有的想法都讓我有點不知所措——wgs、互斥體、原子等。
話雖如此:
以上是一個簡單的Go模擬—並發問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!