| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- package game
- import (
- "battlecamp-go/board"
- "battlecamp-go/events"
- "battlecamp-go/player"
- "battlecamp-go/stomp"
- "log"
- "math/rand"
- "sync"
- "time"
- )
- type Game struct {
- Id int64 `json:"id"`
- StartTime int64 `json:"startTime"`
- EndTime int64 `json:"endTime"`
- Board *board.Board `json:"board"`
- Players []*player.Player `json:"-"`
- mutex sync.Mutex
- Winner *player.Player `json:"winner,omitempty"`
- }
- func NewGame(cols, rows int) *Game {
- createTime := time.Now().Unix()
- game := &Game{
- StartTime: createTime,
- Board: board.NewRemote(cols, rows),
- Players: make([]*player.Player, 0),
- }
- return game
- }
- func (g *Game) Join(p *player.Player) {
- g.mutex.Lock()
- g.placePlayer(p)
- g.Players = append(g.Players, p)
- g.mutex.Unlock()
- }
- func (g *Game) placePlayer(p *player.Player) {
- xRange := g.Board.Width / 5
- yRange := g.Board.Height
- for {
- x := rand.Intn(xRange)
- y := rand.Intn(yRange)
- if g.isValidPlayerPos(x, y) {
- p.Pos.X = x
- p.Pos.Y = y
- return
- }
- }
- }
- func (g *Game) Move(p *player.Player, direction string) bool {
- if !(direction == "N" || direction == "W" || direction == "S" || direction == "E") {
- log.Printf("Illigal direction %v", direction)
- return false
- }
- newX := p.Pos.X
- newY := p.Pos.Y
- switch direction {
- case "N":
- newY--
- case "W":
- newX--
- case "S":
- newY++
- case "E":
- newX++
- }
- //TODO make thread safe
- if !g.isValidPlayerPos(newX, newY) {
- log.Printf("Illigal player pos oldX %v oldY %v newX %v newY %v dir %v ", p.Pos.X, p.Pos.Y, newX, newY, direction)
- return false
- }
- p.Pos.X = newX
- p.Pos.Y = newY
- // END TODO make tread safe
- up := events.PlayerUpdate{
- GameId: g.Id,
- Players: g.Players,
- }
- stomp.SendJsonPlayerUpdate("update", up)
- if g.isWinner(p) {
- g.EndTime = time.Now().Unix()
- g.Winner = p
- ge := events.GameEnd{
- Type: "GAME_END",
- GameId: g.Id,
- Payload: g.Winner.Id,
- }
- stomp.SendJson("game", ge)
- }
- return true
- }
- func (g *Game) isWinner(p *player.Player) bool {
- return g.Board.Finish.X == p.Pos.X && g.Board.Finish.Y == p.Pos.Y
- }
- func (g *Game) isValidPlayerPos(x, y int) bool {
- if x < 0 || y < 0 || x >= g.Board.Width || y >= g.Board.Height {
- return false
- }
- t := g.Board.Get(x, y)
- if t == board.Rock {
- return false
- }
- return g.getPlayerAt(x, y) == nil
- }
- func (g *Game) getPlayerAt(x, y int) *player.Player {
- for _, p := range g.Players {
- if p.Pos.X == x && p.Pos.Y == y {
- return p
- }
- }
- return nil
- }
- func (g *Game) GetPlayer(playerId string) *player.Player {
- for _, p := range g.Players {
- if p.Id == playerId {
- return p
- }
- }
- return nil
- }
|