laneya2

cave exploration game
git clone https://git.ce9e.org/laneya2.git

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) {