Ver código fonte

ignore new binary

Create new bserv binary

Herein lie the following ideas:

- change package visibility of many things
- try to stash the globals into structs
- the code is far from correct; it merely compiles
Stephen McQuay 5 anos atrás
pai
commit
c8efd34080
16 arquivos alterados com 146 adições e 126 exclusões
  1. 1
    1
      .gitignore
  2. 20
    18
      bserv/main.go
  3. 2
    2
      config.go
  4. 41
    33
      control.go
  5. 4
    4
      deathmatch.go
  6. 27
    24
      game.go
  7. 1
    1
      id.go
  8. 1
    1
      id_test.go
  9. 4
    4
      melee.go
  10. 3
    2
      obstacle.go
  11. 1
    1
      player.go
  12. 6
    4
      projectile.go
  13. 11
    11
      protocol.go
  14. 20
    17
      robot.go
  15. 3
    2
      robot_test.go
  16. 1
    1
      splosion.go

+ 1
- 1
.gitignore Ver arquivo

@@ -1,3 +1,3 @@
1
-botserv
1
+bserv/bserv
2 2
 *.swp
3 3
 tags

main.go → bserv/main.go Ver arquivo

@@ -9,6 +9,7 @@ import (
9 9
 	"os"
10 10
 	"runtime/pprof"
11 11
 	"time"
12
+	"bitbucket.org/hackerbots/botserv"
12 13
 
13 14
 	"code.google.com/p/go.net/websocket"
14 15
 )
@@ -22,12 +23,6 @@ var config = flag.String("config", "~/.config/hackerbots/config.json", "location
22 23
 
23 24
 var delta float32
24 25
 
25
-var idg *IdGenerator
26
-var conf Config
27
-
28
-// This is the main, global collection of games
29
-var games MapLock
30
-
31 26
 func main() {
32 27
 	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
33 28
 	log.Printf("Starting Server...")
@@ -49,10 +44,7 @@ func main() {
49 44
 		log.Println("serving profile info at http://localhost:8667/debug/pprof/")
50 45
 	}
51 46
 
52
-	games = MapLock{m: make(map[string]*game)}
53
-	idg = NewIdGenerator()
54
-
55
-	conf, err = loadConfig(*config)
47
+	conf, err := botserv.LoadConfig(*config)
56 48
 	if err != nil {
57 49
 		log.Fatal(err)
58 50
 	}
@@ -61,14 +53,24 @@ func main() {
61 53
 
62 54
 	sm := http.NewServeMux()
63 55
 
64
-	sm.Handle("/", JsonHandler(index))
65
-	sm.Handle("/ws/", websocket.Handler(addPlayer))
66
-	sm.Handle("/game/start/", JsonHandler(startGame))
67
-	sm.Handle("/game/list/", JsonHandler(listGames))
68
-	sm.Handle("/game/stats/", JsonHandler(gameStats))
69
-	sm.Handle("/game/bw/", JsonHandler(bw))
70
-	sm.Handle("/game/stop/", JsonHandler(stopGame))
71
-	sm.HandleFunc("/fuck/shit/up/", killServer)
56
+	c := botserv.Controller{
57
+		Idg:  botserv.NewIdGenerator(),
58
+		Conf: conf,
59
+		Games: botserv.MapLock{
60
+			M: make(map[string]*botserv.Game),
61
+		},
62
+		Memprofile: *mprofile,
63
+		Profile:    *profile,
64
+	}
65
+
66
+	sm.Handle("/", botserv.JsonHandler(c.Index))
67
+	sm.Handle("/ws/", websocket.Handler(c.AddPlayer))
68
+	sm.Handle("/game/start/", botserv.JsonHandler(c.StartGame))
69
+	sm.Handle("/game/list/", botserv.JsonHandler(c.ListGames))
70
+	sm.Handle("/game/stats/", botserv.JsonHandler(c.GameStats))
71
+	sm.Handle("/game/bw/", botserv.JsonHandler(c.BW))
72
+	sm.Handle("/game/stop/", botserv.JsonHandler(c.StopGame))
73
+	sm.HandleFunc("/fuck/shit/up/", c.KillServer)
72 74
 
73 75
 	err = http.ListenAndServe(*addr, sm)
74 76
 	if err != nil {

+ 2
- 2
config.go Ver arquivo

@@ -1,4 +1,4 @@
1
-package main
1
+package botserv
2 2
 
3 3
 import (
4 4
 	"encoding/json"
@@ -31,7 +31,7 @@ const (
31 31
 	DEFAULT_MODE = "deathmatch"
32 32
 )
33 33
 
34
-func loadConfig(filename string) (Config, error) {
34
+func LoadConfig(filename string) (Config, error) {
35 35
 	c := Config{
36 36
 		Tick:      TICK,
37 37
 		Timescale: TIMESCALE,

+ 41
- 33
control.go Ver arquivo

@@ -1,4 +1,4 @@
1
-package main
1
+package botserv
2 2
 
3 3
 import (
4 4
 	"encoding/json"
@@ -19,13 +19,21 @@ func (h JsonHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
19 19
 	h(w, req)
20 20
 }
21 21
 
22
-func startGame(w http.ResponseWriter, req *http.Request) {
22
+type Controller struct {
23
+	Idg        *IdGenerator
24
+	Conf       Config
25
+	Games      MapLock
26
+	Memprofile string
27
+	Profile    string
28
+}
29
+
30
+func (c *Controller) StartGame(w http.ResponseWriter, req *http.Request) {
23 31
 	log.Println("asked to create a game")
24 32
 
25
-	requested_game_name := idg.Hash()
26
-	width, height := float32(conf.Width), float32(conf.Height)
33
+	requested_game_name := c.Idg.Hash()
34
+	width, height := float32(c.Conf.Width), float32(c.Conf.Height)
27 35
 	obstacles := 0
28
-	maxPoints := conf.MaxPoints
36
+	maxPoints := c.Conf.MaxPoints
29 37
 	mode := "deathmatch"
30 38
 
31 39
 	// here we determine if we are going to run with defaults or pick them off
@@ -55,10 +63,10 @@ func startGame(w http.ResponseWriter, req *http.Request) {
55 63
 		mode = cfg.Mode
56 64
 	}
57 65
 
58
-	g := games.get(requested_game_name)
66
+	g := c.Games.get(requested_game_name)
59 67
 	if g == nil {
60 68
 		log.Printf("Game '%s' non-existant; making it now", requested_game_name)
61
-		g, err := NewGame(requested_game_name, width, height, obstacles, conf.Tick, maxPoints, mode)
69
+		g, err := NewGame(requested_game_name, width, height, obstacles, c.Conf.Tick, maxPoints, mode)
62 70
 		if err != nil {
63 71
 			log.Printf("problem creating game: %s: %s", requested_game_name, err)
64 72
 			b, _ := json.Marshal(NewFailure("game creation failure"))
@@ -66,7 +74,7 @@ func startGame(w http.ResponseWriter, req *http.Request) {
66 74
 			return
67 75
 		}
68 76
 		go g.run()
69
-		games.add(g)
77
+		c.Games.add(g)
70 78
 	} else {
71 79
 		log.Printf("Game '%s' already exists: %p", requested_game_name, g)
72 80
 		b, _ := json.Marshal(NewFailure("game already exists"))
@@ -84,10 +92,10 @@ func startGame(w http.ResponseWriter, req *http.Request) {
84 92
 	}
85 93
 }
86 94
 
87
-func listGames(w http.ResponseWriter, req *http.Request) {
95
+func (c *Controller) ListGames(w http.ResponseWriter, req *http.Request) {
88 96
 	log.Println("games list requested")
89
-	games.RLock()
90
-	defer games.RUnlock()
97
+	c.Games.RLock()
98
+	defer c.Games.RUnlock()
91 99
 	type pout struct {
92 100
 		Name string `json:"name"`
93 101
 		Id   string `json:"id"`
@@ -97,7 +105,7 @@ func listGames(w http.ResponseWriter, req *http.Request) {
97 105
 		Players []pout `json:"players"`
98 106
 	}
99 107
 	ids := make([]gl, 0)
100
-	for id, g := range games.m {
108
+	for id, g := range c.Games.M {
101 109
 		players := make([]pout, 0)
102 110
 		// TODO - players instead of robots?
103 111
 		for p := range g.players {
@@ -118,19 +126,19 @@ func listGames(w http.ResponseWriter, req *http.Request) {
118 126
 	}
119 127
 }
120 128
 
121
-func gameStats(w http.ResponseWriter, req *http.Request) {
129
+func (c *Controller) GameStats(w http.ResponseWriter, req *http.Request) {
122 130
 	// TODO: wrap this up in something similar to the JsonHandler to verify the
123 131
 	// url? Look at gorilla routing?
124
-	key, err := getGameId(req.URL.Path)
132
+	key, err := c.getGameId(req.URL.Path)
125 133
 	if err != nil {
126 134
 		b, _ := json.Marshal(NewFailure(err.Error()))
127 135
 		http.Error(w, string(b), http.StatusBadRequest)
128 136
 		return
129 137
 	}
130 138
 	log.Printf("requested stats for game: %s", key)
131
-	games.RLock()
132
-	g, ok := games.m[key]
133
-	games.RUnlock()
139
+	c.Games.RLock()
140
+	g, ok := c.Games.M[key]
141
+	c.Games.RUnlock()
134 142
 	if !ok {
135 143
 		b, _ := json.Marshal(NewFailure("game not found"))
136 144
 		http.Error(w, string(b), http.StatusNotFound)
@@ -143,19 +151,19 @@ func gameStats(w http.ResponseWriter, req *http.Request) {
143 151
 	}
144 152
 }
145 153
 
146
-func bw(w http.ResponseWriter, req *http.Request) {
154
+func (c *Controller) BW(w http.ResponseWriter, req *http.Request) {
147 155
 	// TODO: wrap this up in something similar to the JsonHandler to verify the
148 156
 	// url? Look at gorilla routing?
149
-	key, err := getGameId(req.URL.Path)
157
+	key, err := c.getGameId(req.URL.Path)
150 158
 	if err != nil {
151 159
 		b, _ := json.Marshal(NewFailure(err.Error()))
152 160
 		http.Error(w, string(b), http.StatusBadRequest)
153 161
 		return
154 162
 	}
155 163
 	log.Printf("requested bandwidth for game: %s", key)
156
-	games.RLock()
157
-	g, ok := games.m[key]
158
-	games.RUnlock()
164
+	c.Games.RLock()
165
+	g, ok := c.Games.M[key]
166
+	c.Games.RUnlock()
159 167
 	if !ok {
160 168
 		b, _ := json.Marshal(NewFailure("game not found"))
161 169
 		http.Error(w, string(b), http.StatusNotFound)
@@ -170,16 +178,16 @@ func bw(w http.ResponseWriter, req *http.Request) {
170 178
 	}
171 179
 }
172 180
 
173
-func stopGame(w http.ResponseWriter, req *http.Request) {
174
-	key, err := getGameId(req.URL.Path)
181
+func (c *Controller) StopGame(w http.ResponseWriter, req *http.Request) {
182
+	key, err := c.getGameId(req.URL.Path)
175 183
 	if err != nil {
176 184
 		b, _ := json.Marshal(NewFailure(err.Error()))
177 185
 		http.Error(w, string(b), http.StatusBadRequest)
178 186
 		return
179 187
 	}
180
-	games.Lock()
181
-	g, ok := games.m[key]
182
-	defer games.Unlock()
188
+	c.Games.Lock()
189
+	g, ok := c.Games.M[key]
190
+	defer c.Games.Unlock()
183 191
 	if !ok {
184 192
 		http.NotFound(w, req)
185 193
 		return
@@ -197,15 +205,15 @@ func stopGame(w http.ResponseWriter, req *http.Request) {
197 205
 	}
198 206
 }
199 207
 
200
-func killServer(w http.ResponseWriter, req *http.Request) {
201
-	if *profile != "" {
208
+func (c *Controller) KillServer(w http.ResponseWriter, req *http.Request) {
209
+	if c.Profile != "" {
202 210
 		log.Print("trying to stop cpu profile")
203 211
 		pprof.StopCPUProfile()
204 212
 		log.Print("stopped cpu profile")
205 213
 	}
206
-	if *mprofile != "" {
214
+	if c.Memprofile != "" {
207 215
 		log.Print("trying to dump memory profile")
208
-		f, err := os.Create(*mprofile)
216
+		f, err := os.Create(c.Memprofile)
209 217
 		if err != nil {
210 218
 			log.Fatal(err)
211 219
 		}
@@ -216,7 +224,7 @@ func killServer(w http.ResponseWriter, req *http.Request) {
216 224
 	log.Fatal("shit got fucked up")
217 225
 }
218 226
 
219
-func index(w http.ResponseWriter, req *http.Request) {
227
+func (c *Controller) Index(w http.ResponseWriter, req *http.Request) {
220 228
 	log.Println("version requested")
221 229
 	version := struct {
222 230
 		Version string `json:"version"`
@@ -230,7 +238,7 @@ func index(w http.ResponseWriter, req *http.Request) {
230 238
 	}
231 239
 }
232 240
 
233
-func getGameId(path string) (string, error) {
241
+func (c *Controller) getGameId(path string) (string, error) {
234 242
 	var err error
235 243
 	trimmed := strings.Trim(path, "/")
236 244
 	fullPath := strings.Split(trimmed, "/")

+ 4
- 4
deathmatch.go Ver arquivo

@@ -1,4 +1,4 @@
1
-package main
1
+package botserv
2 2
 
3 3
 import (
4 4
 	"log"
@@ -7,10 +7,10 @@ import (
7 7
 type deathmatch struct {
8 8
 }
9 9
 
10
-func (g *deathmatch) setup(gg *game) {
10
+func (g *deathmatch) setup(gg *Game) {
11 11
 }
12 12
 
13
-func (g *deathmatch) gameOver(gg *game) (bool, *GameOver) {
13
+func (g *deathmatch) gameOver(gg *Game) (bool, *GameOver) {
14 14
 	over := false
15 15
 	var stats *GameOver
16 16
 
@@ -41,5 +41,5 @@ func (g *deathmatch) gameOver(gg *game) (bool, *GameOver) {
41 41
 	return over, stats
42 42
 }
43 43
 
44
-func (g *deathmatch) tick(gg *game, payload *Boardstate) {
44
+func (g *deathmatch) tick(gg *Game, payload *Boardstate) {
45 45
 }

+ 27
- 24
game.go Ver arquivo

@@ -1,4 +1,4 @@
1
-package main
1
+package botserv
2 2
 
3 3
 // delete me
4 4
 
@@ -24,23 +24,23 @@ type Scanner struct {
24 24
 }
25 25
 
26 26
 type MapLock struct {
27
-	m map[string]*game
27
+	M map[string]*Game
28 28
 	sync.RWMutex
29 29
 }
30 30
 
31 31
 // get is a function that returns a game if found, and creates one if
32 32
 // not found and force is true. In order to get a hash (rather than use
33 33
 // the string you pass) send "" for id.
34
-func (ml *MapLock) get(id string) *game {
34
+func (ml *MapLock) get(id string) *Game {
35 35
 	ml.Lock()
36
-	g, _ := ml.m[id]
36
+	g, _ := ml.M[id]
37 37
 	ml.Unlock()
38 38
 	return g
39 39
 }
40 40
 
41
-func (ml *MapLock) add(g *game) {
41
+func (ml *MapLock) add(g *Game) {
42 42
 	ml.Lock()
43
-	ml.m[g.id] = g
43
+	ml.M[g.id] = g
44 44
 	ml.Unlock()
45 45
 }
46 46
 
@@ -64,7 +64,7 @@ type GameStats struct {
64 64
 	sync.RWMutex
65 65
 }
66 66
 
67
-type game struct {
67
+type Game struct {
68 68
 	id                string
69 69
 	players           map[*player]bool
70 70
 	projectiles       map[*Projectile]bool
@@ -87,15 +87,18 @@ type game struct {
87 87
 	stats             GameStats
88 88
 	mode              GameMode
89 89
 	bw                *bandwidth.Bandwidth
90
+	Conf              Config
91
+	Games             *MapLock
92
+	Verbose           bool
90 93
 }
91 94
 
92 95
 type GameMode interface {
93
-	setup(g *game)
94
-	tick(gg *game, payload *Boardstate)
95
-	gameOver(gg *game) (bool, *GameOver)
96
+	setup(g *Game)
97
+	tick(gg *Game, payload *Boardstate)
98
+	gameOver(gg *Game) (bool, *GameOver)
96 99
 }
97 100
 
98
-func NewGame(id string, width, height float32, obstacles, tick, maxPoints int, mode string) (*game, error) {
101
+func NewGame(id string, width, height float32, obstacles, tick, maxPoints int, mode string) (*Game, error) {
99 102
 	bw, err := bandwidth.NewBandwidth(
100 103
 		[]int{1, 10, 60},
101 104
 		1*time.Second,
@@ -105,7 +108,7 @@ func NewGame(id string, width, height float32, obstacles, tick, maxPoints int, m
105 108
 		return nil, err
106 109
 	}
107 110
 	go bw.Run()
108
-	g := &game{
111
+	g := &Game{
109 112
 		id:                id,
110 113
 		register:          make(chan *player, maxPlayer),
111 114
 		unregister:        make(chan *player, maxPlayer),
@@ -141,7 +144,7 @@ func NewGame(id string, width, height float32, obstacles, tick, maxPoints int, m
141 144
 	return g, nil
142 145
 }
143 146
 
144
-func (g *game) tick(payload *Boardstate) {
147
+func (g *Game) tick(payload *Boardstate) {
145 148
 	g.players_remaining = 0
146 149
 	payload.Objects = MinifyObstacles(g.obstacles)
147 150
 
@@ -196,7 +199,7 @@ func (g *game) tick(payload *Boardstate) {
196 199
 	}
197 200
 }
198 201
 
199
-func (g *game) sendUpdate(payload *Boardstate) {
202
+func (g *Game) sendUpdate(payload *Boardstate) {
200 203
 	// Ensure that the robots are always sent in a consistent order
201 204
 	sort.Sort(RobotSorter{Robots: payload.OtherRobots})
202 205
 	sort.Sort(AllRobotSorter{Robots: payload.AllBots})
@@ -292,20 +295,20 @@ func (g *game) sendUpdate(payload *Boardstate) {
292 295
 
293 296
 }
294 297
 
295
-func (g *game) run() {
298
+func (g *Game) run() {
296 299
 	var t0, t1 time.Time
297
-	ticker := time.NewTicker(time.Duration(conf.Tick) * time.Millisecond)
300
+	ticker := time.NewTicker(time.Duration(g.Conf.Tick) * time.Millisecond)
298 301
 	for {
299 302
 		select {
300 303
 		case <-g.kill:
301 304
 			log.Printf("game %s: received kill signal, dying gracefully", g.id)
302 305
 			close(g.bw.Quit)
303
-			games.Lock()
306
+			g.Games.Lock()
304 307
 			for player := range g.players {
305 308
 				close(player.send)
306 309
 			}
307
-			delete(games.m, g.id)
308
-			games.Unlock()
310
+			delete(g.Games.M, g.id)
311
+			g.Games.Unlock()
309 312
 			return
310 313
 		case p := <-g.register:
311 314
 			g.players[p] = true
@@ -330,7 +333,7 @@ func (g *game) run() {
330 333
 
331 334
 			g.turn++
332 335
 			payload.Turn = g.turn
333
-			if *verbose {
336
+			if g.Verbose {
334 337
 				log.Printf("\033[2JTurn: %v", g.turn)
335 338
 				log.Printf("Players: %v", len(g.players))
336 339
 				log.Printf("Projectiles: %v", len(g.projectiles))
@@ -346,7 +349,7 @@ func (g *game) run() {
346 349
 			g.mode.tick(g, payload)
347 350
 
348 351
 			t1 = time.Now()
349
-			if *verbose {
352
+			if g.Verbose {
350 353
 				log.Printf("Turn Processes %v\n", t1.Sub(t0))
351 354
 			}
352 355
 
@@ -354,14 +357,14 @@ func (g *game) run() {
354 357
 			g.sendUpdate(payload)
355 358
 
356 359
 			t1 = time.Now()
357
-			if *verbose {
360
+			if g.Verbose {
358 361
 				log.Printf("Sent Payload %v\n", t1.Sub(t0))
359 362
 			}
360 363
 		}
361 364
 	}
362 365
 }
363 366
 
364
-func (g *game) sendGameOver(eg *GameOver) {
367
+func (g *Game) sendGameOver(eg *GameOver) {
365 368
 	log.Printf("sending out game over message: %+v", eg)
366 369
 	for p := range g.players {
367 370
 		p.send <- eg
@@ -373,7 +376,7 @@ func (g *game) sendGameOver(eg *GameOver) {
373 376
 
374 377
 // returns a GameParam object popuplated by info from the game. This is
375 378
 // used during client/server initial negociation.
376
-func (g *game) gameParam() *GameParam {
379
+func (g *Game) gameParam() *GameParam {
377 380
 	return &GameParam{
378 381
 		BoardSize: BoardSize{
379 382
 			Width:  g.width,

+ 1
- 1
id.go Ver arquivo

@@ -1,4 +1,4 @@
1
-package main
1
+package botserv
2 2
 
3 3
 import (
4 4
 	"crypto/md5"

+ 1
- 1
id_test.go Ver arquivo

@@ -1,4 +1,4 @@
1
-package main
1
+package botserv
2 2
 
3 3
 import (
4 4
 	"testing"

+ 4
- 4
melee.go Ver arquivo

@@ -1,4 +1,4 @@
1
-package main
1
+package botserv
2 2
 
3 3
 import (
4 4
 	"log"
@@ -9,15 +9,15 @@ type melee struct {
9 9
 	respawn_timer float64
10 10
 }
11 11
 
12
-func (g *melee) setup(gg *game) {
12
+func (g *melee) setup(gg *Game) {
13 13
 	g.respawn_timer = 5000
14 14
 }
15 15
 
16
-func (g *melee) gameOver(gg *game) (bool, *GameOver) {
16
+func (g *melee) gameOver(gg *Game) (bool, *GameOver) {
17 17
 	return false, &GameOver{}
18 18
 }
19 19
 
20
-func (g *melee) tick(gg *game, payload *Boardstate) {
20
+func (g *melee) tick(gg *Game, payload *Boardstate) {
21 21
 	for p := range gg.players {
22 22
 		for _, r := range p.Robots {
23 23
 			_, ok := g.respawn[r]

+ 3
- 2
obstacle.go Ver arquivo

@@ -1,9 +1,10 @@
1
-package main
1
+package botserv
2 2
 
3 3
 import (
4
-	v "bitbucket.org/hackerbots/vector"
5 4
 	"math"
6 5
 	"math/rand"
6
+
7
+	v "bitbucket.org/hackerbots/vector"
7 8
 )
8 9
 
9 10
 type Obstacle struct {

+ 1
- 1
player.go Ver arquivo

@@ -1,4 +1,4 @@
1
-package main
1
+package botserv
2 2
 
3 3
 import (
4 4
 	"encoding/gob"

+ 6
- 4
projectile.go Ver arquivo

@@ -1,8 +1,9 @@
1
-package main
1
+package botserv
2 2
 
3 3
 import (
4
-	v "bitbucket.org/hackerbots/vector"
5 4
 	"log"
5
+
6
+	v "bitbucket.org/hackerbots/vector"
6 7
 )
7 8
 
8 9
 type Projectile struct {
@@ -13,12 +14,13 @@ type Projectile struct {
13 14
 	Speed    float32   `json:"-"`
14 15
 	Damage   int       `json:"-"`
15 16
 	Owner    *Robot    `json:"-"`
17
+	Delta    float32
16 18
 }
17 19
 
18
-func (p *Projectile) Tick(g *game) {
20
+func (p *Projectile) Tick(g *Game) {
19 21
 	vec := p.MoveTo.Sub(p.Position)
20 22
 	v_norm := vec.Normalize()
21
-	v_scaled := v_norm.Scale(p.Speed * delta)
23
+	v_scaled := v_norm.Scale(p.Speed * p.Delta)
22 24
 	newPos := p.Position.Add(v_scaled)
23 25
 
24 26
 	hit_player := false

+ 11
- 11
protocol.go Ver arquivo

@@ -1,4 +1,4 @@
1
-package main
1
+package botserv
2 2
 
3 3
 import (
4 4
 	"log"
@@ -143,7 +143,7 @@ func NewFailure(reason string) *Failure {
143 143
 	}
144 144
 }
145 145
 
146
-func addPlayer(ws *websocket.Conn) {
146
+func (c *Controller) AddPlayer(ws *websocket.Conn) {
147 147
 	var gid GameID
148 148
 	err := websocket.JSON.Receive(ws, &gid)
149 149
 	if err != nil {
@@ -151,16 +151,16 @@ func addPlayer(ws *websocket.Conn) {
151 151
 		return
152 152
 	}
153 153
 
154
-	game := games.get(gid.Id)
154
+	game := c.Games.get(gid.Id)
155 155
 	if game == nil {
156 156
 		var err error
157 157
 		game, err = NewGame(
158 158
 			gid.Id,
159
-			float32(conf.Width),
160
-			float32(conf.Height),
161
-			conf.Obstacles,
162
-			conf.Tick,
163
-			conf.MaxPoints,
159
+			float32(c.Conf.Width),
160
+			float32(c.Conf.Height),
161
+			c.Conf.Obstacles,
162
+			c.Conf.Tick,
163
+			c.Conf.MaxPoints,
164 164
 			"",
165 165
 		)
166 166
 		if err != nil {
@@ -169,10 +169,10 @@ func addPlayer(ws *websocket.Conn) {
169 169
 			return
170 170
 		}
171 171
 		go game.run()
172
-		games.add(game)
172
+		c.Games.add(game)
173 173
 	}
174 174
 
175
-	player_id := idg.Hash()
175
+	player_id := c.Idg.Hash()
176 176
 	err = websocket.JSON.Send(ws, NewPlayerID(player_id))
177 177
 	if err != nil {
178 178
 		log.Printf("game %s: unable to send player_id to player %s", gid.Id, player_id)
@@ -284,7 +284,7 @@ encodingLoops:
284 284
 			convertedStats[name] = dstat
285 285
 			r := Robot{
286 286
 				Stats:    dstat,
287
-				Id:       idg.Hash(),
287
+				Id:       c.Idg.Hash(),
288 288
 				Name:     name,
289 289
 				Health:   10,
290 290
 				Heading:  v.Vector2d{1, 0},

+ 20
- 17
robot.go Ver arquivo

@@ -1,10 +1,11 @@
1
-package main
1
+package botserv
2 2
 
3 3
 import (
4
-	v "bitbucket.org/hackerbots/vector"
5 4
 	"log"
6 5
 	"math"
7 6
 	"math/rand"
7
+
8
+	v "bitbucket.org/hackerbots/vector"
8 9
 )
9 10
 
10 11
 type Robot struct {
@@ -30,6 +31,8 @@ type Robot struct {
30 31
 	Probe          *v.Point2d  `json:"probe"`
31 32
 	ProbeResult    *Collision  `json:"probe_result"`
32 33
 	gameStats      *BotStats   `json:-`
34
+	Delta          float32     `json:-`
35
+	Idg            *IdGenerator
33 36
 }
34 37
 
35 38
 type Collision struct {
@@ -172,7 +175,7 @@ type Instruction struct {
172 175
 
173 176
 // returns collision, the intersection point, and the robot with whom r has
174 177
 // collided, if this happened.
175
-func (r *Robot) checkCollisions(g *game, probe v.Vector2d) (bool, *v.Point2d, *Robot) {
178
+func (r *Robot) checkCollisions(g *Game, probe v.Vector2d) (bool, *v.Point2d, *Robot) {
176 179
 	finalCollision := false
177 180
 	collision := false
178 181
 	closest := float32(math.Inf(1))
@@ -243,19 +246,19 @@ func (r *Robot) checkCollisions(g *game, probe v.Vector2d) (bool, *v.Point2d, *R
243 246
 	return finalCollision, intersection, finalRobot
244 247
 }
245 248
 
246
-func (r *Robot) Tick(g *game) {
249
+func (r *Robot) Tick(g *Game) {
247 250
 	r.Collision = nil
248 251
 	r.Hit = false
249 252
 	r.scan(g)
250 253
 
251 254
 	// Adjust Speed
252 255
 	if r.Speed < r.TargetSpeed {
253
-		r.Speed += (r.Stats.Acceleration * delta)
256
+		r.Speed += (r.Stats.Acceleration * r.Delta)
254 257
 		if r.Speed > r.TargetSpeed {
255 258
 			r.Speed = r.TargetSpeed
256 259
 		}
257 260
 	} else if float32(math.Abs(float64(r.Speed-r.TargetSpeed))) > v.Epsilon {
258
-		r.Speed -= (r.Stats.Acceleration * delta)
261
+		r.Speed -= (r.Stats.Acceleration * r.Delta)
259 262
 		// Cap reverse to 1/2 speed
260 263
 		if r.Speed < (-0.5 * r.TargetSpeed) {
261 264
 			r.Speed = (-0.5 * r.TargetSpeed)
@@ -292,15 +295,15 @@ func (r *Robot) Tick(g *game) {
292 295
 		}
293 296
 
294 297
 		// Max turn radius in this case is in degrees per second
295
-		if float32(math.Abs(float64(angle))) > (float32(r.Stats.TurnSpeed) * delta) {
298
+		if float32(math.Abs(float64(angle))) > (float32(r.Stats.TurnSpeed) * r.Delta) {
296 299
 			// New heading should be a little less, take current heading and
297 300
 			// rotate by the max turn radius per frame.
298
-			rot := (float32(r.Stats.TurnSpeed) * delta) * v.Deg2rad
301
+			rot := (float32(r.Stats.TurnSpeed) * r.Delta) * v.Deg2rad
299 302
 
300 303
 			new_heading = current_heading.Rotate(rot * float32(dir))
301 304
 		}
302 305
 
303
-		move_vector := new_heading.Scale(r.Speed * delta)
306
+		move_vector := new_heading.Scale(r.Speed * r.Delta)
304 307
 		collision, intersection_point, hit_robot := r.checkCollisions(g, move_vector)
305 308
 		if collision {
306 309
 			dmg := int(math.Abs(float64(r.Speed)) / 10.0)
@@ -352,7 +355,7 @@ func (r *Robot) Tick(g *game) {
352 355
 
353 356
 	// We only self repair when we're stopped
354 357
 	if math.Abs(float64(r.Speed)) < v.Epsilon && r.RepairCounter > 0 {
355
-		r.RepairCounter -= delta
358
+		r.RepairCounter -= r.Delta
356 359
 		if r.RepairCounter < 0 {
357 360
 			r.Health += g.repair_hp
358 361
 			if r.Health > r.Stats.Hp {
@@ -364,9 +367,9 @@ func (r *Robot) Tick(g *game) {
364 367
 
365 368
 	// We are only allowed to scan when we're stopped
366 369
 	if math.Abs(float64(r.Speed)) < v.Epsilon && r.ActiveScan {
367
-		r.ScanCounter += delta * float32(r.Stats.ScannerRadius) * 0.1
370
+		r.ScanCounter += r.Delta * float32(r.Stats.ScannerRadius) * 0.1
368 371
 	} else if r.ScanCounter > 0 {
369
-		r.ScanCounter -= delta * float32(r.Stats.ScannerRadius) * 0.05
372
+		r.ScanCounter -= r.Delta * float32(r.Stats.ScannerRadius) * 0.05
370 373
 		if r.ScanCounter <= 0 {
371 374
 			r.ScanCounter = 0
372 375
 		}
@@ -394,7 +397,7 @@ func (r *Robot) Tick(g *game) {
394 397
 	}
395 398
 }
396 399
 
397
-func (r *Robot) scan(g *game) {
400
+func (r *Robot) scan(g *Game) {
398 401
 	r.Scanners = r.Scanners[:0]
399 402
 	for player := range g.players {
400 403
 		for _, bot := range player.Robots {
@@ -440,9 +443,9 @@ func (r *Robot) scan(g *game) {
440 443
 
441 444
 }
442 445
 
443
-func (r *Robot) fire(g *game) *Projectile {
446
+func (r *Robot) fire(g *Game) *Projectile {
444 447
 	// Throttle the fire rate
445
-	time_since_fired := (float32(g.turn) * (delta * 1000)) - (float32(r.LastFired) * (delta * 1000))
448
+	time_since_fired := (float32(g.turn) * (r.Delta * 1000)) - (float32(r.LastFired) * (r.Delta * 1000))
446 449
 	if time_since_fired < float32(r.Stats.FireRate) {
447 450
 		return nil
448 451
 	}
@@ -451,7 +454,7 @@ func (r *Robot) fire(g *game) *Projectile {
451 454
 	r.gameStats.Shots++
452 455
 
453 456
 	return &Projectile{
454
-		Id:       idg.Hash(),
457
+		Id:       r.Idg.Hash(),
455 458
 		Position: r.Position,
456 459
 		MoveTo:   *r.FireAt,
457 460
 		Damage:   r.Stats.WeaponDamage,
@@ -461,7 +464,7 @@ func (r *Robot) fire(g *game) *Projectile {
461 464
 	}
462 465
 }
463 466
 
464
-func (r *Robot) reset(g *game) {
467
+func (r *Robot) reset(g *Game) {
465 468
 	for {
466 469
 		start_pos := v.Point2d{
467 470
 			X: rand.Float32() * float32(g.width),

+ 3
- 2
robot_test.go Ver arquivo

@@ -1,10 +1,11 @@
1
-package main
1
+package botserv
2 2
 
3 3
 import (
4
-	v "bitbucket.org/hackerbots/vector"
5 4
 	"log"
6 5
 	"math"
7 6
 	"testing"
7
+
8
+	v "bitbucket.org/hackerbots/vector"
8 9
 )
9 10
 
10 11
 func init() {

+ 1
- 1
splosion.go Ver arquivo

@@ -1,4 +1,4 @@
1
-package main
1
+package botserv
2 2
 
3 3
 import (
4 4
 	v "bitbucket.org/hackerbots/vector"

Carregando…
Cancelar
Salvar