Maison >développement back-end >Golang >Une simple simulation Go - problèmes de concurrence
L'éditeur php Xinyi vous propose un jeu de simulation Go simple mais intéressant appelé "Concurrency Problem". Ce jeu prend pour thème la programmation simultanée, permettant aux joueurs de découvrir le charme de la programmation simultanée dans un monde virtuel. Dans le jeu, les joueurs doivent écrire du code pour gérer l'exécution simultanée de plusieurs tâches et tester leurs capacités de programmation simultanée. L'interface de jeu est concise et claire, et le fonctionnement est simple, adapté aux débutants pour débuter, et il offre également plusieurs modes de difficulté et de défi parmi lesquels les joueurs peuvent choisir. Que vous soyez débutant ou développeur expérimenté, vous pourrez profiter du plaisir de la programmation simultanée dans ce jeu de simulation.
Je suis un étudiant polonais et ce semestre j'ai commencé un cours de programmation concurrente (Go, Ada et quelques langages théoriques et CSP à l'avenir). Pour être honnête, Golang a l'air intéressant mais je suis un peu confus. L'essentiel est que, d'après mon expérience, je me qualifierais de programmeur inférieur à la moyenne. Fondamentalement, ma tâche est de créer une simulation, que je décrirai ainsi :
Il existe une grille n*m
Les voyageurs peuvent être générés aléatoirement, jusqu'à k voyageurs, chaque voyageur a un identifiant unique (1, 2, 3, etc., jusqu'à k)
A des moments aléatoires, si l'espace est libre (je suis sûr que l'espace libre est 0), le voyageur peut se déplacer vers le haut, la gauche, la droite ou le bas sur la grille
Dispose également d'une caméra qui imprime parfois l'état actuel du maillage ainsi que les mouvements récents (pas encore implémenté)
Officieusement, j'ai entendu dire que je devrais utiliser les chaînes, quoi que cela signifie
Mon idée est de créer une structure avec l'identifiant et les coordonnées de chaque voyageur et d'envoyer son identifiant au canal qui représente la volonté de bouger, puis je choisirai au hasard la direction du mouvement.
Je suis un peu confus au sujet de la concurrence - non seulement si et où dois-je utiliser wgs et mutex, mais aussi par exemple si j'utilise func(){} la boucle doit-elle être à l'intérieur ou à l'extérieur. Je serais très heureux d'apprécier tout conseil, aide ou correctif/idée pour corriger mon code car actuellement, comme vous l'avez deviné, il ne fonctionne pas correctement (par exemple lorsque l'appareil photo imprime la grille, il y a parfois plus de k voyageurs, où plusieurs les voyageurs partagent le même nombre et parfois ils semblent disparaître). J'espère que tout le monde passe une bonne journée et j'apprécierais vraiment toute aide :)
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); } }
Je suis un peu dépassé par toutes les idées - wgs, mutex, atomes, etc.
Cela étant dit :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!