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中文网其他相关文章!