- commit
- 1c1de7135ef83ea992f5ca574f044af9a3b65b20
- parent
- 837c95dae8c8f48466f33a4ba80c27e10cf90b87
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2024-10-05 22:28
fix concurrency: monster move logic in game goroutine
Diffstat
| M | game.go | 13 | ++++--------- |
| M | monster.go | 51 | +++++++++++++++++++++------------------------------ |
2 files changed, 25 insertions, 39 deletions
diff --git a/game.go b/game.go
@@ -18,7 +18,7 @@ type Game struct {
18 18 Monsters map[*Monster]bool
19 19 Piles map[Point]*Pile
20 20 Msg chan PlayerMessage
21 -1 MMsg chan MonsterMessage
-1 21 MMsg chan *Monster
22 22 register chan *Player
23 23 unregister chan *Player
24 24 lastId int
@@ -48,7 +48,7 @@ func getGame(id string) *Game {
48 48 Monsters: make(map[*Monster]bool),
49 49 Piles: make(map[Point]*Pile),
50 50 Msg: make(chan PlayerMessage),
51 -1 MMsg: make(chan MonsterMessage),
-1 51 MMsg: make(chan *Monster),
52 52 register: make(chan *Player),
53 53 unregister: make(chan *Player),
54 54 lastId: 0,
@@ -314,13 +314,8 @@ func (game *Game) run() {
314 314 } else if verbose {
315 315 log.Println("unknown action", pmsg.Msg)
316 316 }
317 -1 case mmsg := <-game.MMsg:
318 -1 if mmsg.Msg["action"] == "move" {
319 -1 dir, ok := mmsg.Msg["dir"].(string)
320 -1 if ok {
321 -1 mmsg.Monster.Move(dir)
322 -1 }
323 -1 }
-1 317 case monster := <-game.MMsg:
-1 318 monster.Move()
324 319 }
325 320 game.Flush()
326 321 }
diff --git a/monster.go b/monster.go
@@ -17,11 +17,6 @@ type Monster struct {
17 17 Speed int
18 18 }
19 19
20 -1 type MonsterMessage struct {
21 -1 Monster *Monster
22 -1 Msg Message
23 -1 }
24 -1
25 20 func makeMonster(game *Game, pos Point) *Monster {
26 21 monster := &Monster{
27 22 Game: game,
@@ -49,30 +44,7 @@ func (monster *Monster) run() {
49 44 case <-monster.quit:
50 45 return
51 46 case <-ticker.C:
52 -1 bestDist := 100000
53 -1 dir := "left"
54 -1 for player := range monster.Game.Players {
55 -1 dist := monster.Pos.Dist(player.Pos)
56 -1 if dist < bestDist {
57 -1 bestDist = dist
58 -1 dir = monster.Pos.Dir(player.Pos)
59 -1 }
60 -1 }
61 -1
62 -1 if bestDist > 10 {
63 -1 continue
64 -1 }
65 -1 if !monster.Game.IsFree(monster.Pos.Move(dir)) {
66 -1 dir = RandomDir()
67 -1 }
68 -1
69 -1 monster.Game.MMsg <- MonsterMessage{
70 -1 monster,
71 -1 Message{
72 -1 "action": "move",
73 -1 "dir": dir,
74 -1 },
75 -1 }
-1 47 monster.Game.MMsg <- monster
76 48 }
77 49 }
78 50 }
@@ -92,10 +64,29 @@ func (monster *Monster) TakeDamage(attack float64) {
92 64 }
93 65 }
94 66
95 -1 func (monster *Monster) Move(dir string) {
-1 67 func (monster *Monster) Move() {
96 68 game := monster.Game
-1 69
-1 70 bestDist := 100000
-1 71 dir := "left"
-1 72 for player := range game.Players {
-1 73 dist := monster.Pos.Dist(player.Pos)
-1 74 if dist < bestDist {
-1 75 bestDist = dist
-1 76 dir = monster.Pos.Dir(player.Pos)
-1 77 }
-1 78 }
-1 79
-1 80 if bestDist > 10 {
-1 81 return
-1 82 }
-1 83 if !game.IsFree(monster.Pos.Move(dir)) {
-1 84 dir = RandomDir()
-1 85 }
-1 86
97 87 pos := monster.Pos.Move(dir)
98 88 player := game.getPlayerAt(pos)
-1 89
99 90 if player != nil {
100 91 player.TakeDamage(monster.Attack)
101 92 } else if game.getMonsterAt(pos) == nil && game.IsFree(pos) {