@@ -7,39 +7,27 @@ import renderer.Renderer
7
7
import scalatron .botwar .BotWarSimulation .SimState
8
8
import java .awt .event .{WindowEvent , WindowAdapter , KeyEvent , KeyListener }
9
9
import akka .dispatch .ExecutionContext
10
- import akka .actor .ActorSystem
11
10
import scalatron .core ._
12
11
13
12
14
13
/** BotWar: an implementation of the Scalatron Game trait.
15
14
* Main.main() feeds this instance to Scalatron.run(). */
16
15
case object BotWar extends Game
17
16
{
18
- val name = Constants .GameName
19
-
20
17
def gameSpecificPackagePath = " scalatron.botwar.botPlugin"
21
18
22
- def runVisually (
23
- pluginPath : String ,
24
- argMap : Map [String ,String ],
25
- rounds : Int ,
26
- tournamentState : TournamentState , // receives tournament round results
27
- secureMode : Boolean ,
28
- verbose : Boolean
29
- )(
30
- actorSystem : ActorSystem ,
31
- executionContextForUntrustedCode : ExecutionContext
32
- )
33
- {
19
+ def runVisually (rounds : Int , scalatron : ScalatronInward ) {
20
+ val argMap = scalatron.argMap
21
+
34
22
// determine the permanent configuration for the game
35
- val permanentConfig = PermanentConfig .fromArgMap(secureMode, argMap)
23
+ val permanentConfig = PermanentConfig .fromArgMap(scalatron. secureMode, argMap)
36
24
37
25
// pop up the display window, taking command line args into account
38
26
val display = Display .create(argMap)
39
27
display.show()
40
28
41
29
// create a renderer; we'll use it to paint the display
42
- val renderer = Renderer (permanentConfig, tournamentState )
30
+ val renderer = Renderer (permanentConfig, scalatron )
43
31
44
32
// add a keyboard listener to allow the user to configure the app while it runs
45
33
val keyListener = new KeyListener {
@@ -67,9 +55,9 @@ case object BotWar extends Game
67
55
68
56
// the simulation runner will invoke this callback, which we use to update the display
69
57
val stepCallback = (state : SimState ) => {
70
- tournamentState.updateMostRecentState (state)
58
+ scalatron.postStepCallback (state)
71
59
72
- val executionContextForTrustedCode = actorSystem.dispatcher
60
+ val executionContextForTrustedCode = scalatron. actorSystem.dispatcher
73
61
renderer.draw(display.renderTarget, state.gameState)(executionContextForTrustedCode)
74
62
75
63
// enforce maxFPS (max frames per second) by putting this thread to sleep if appropriate
@@ -82,24 +70,15 @@ case object BotWar extends Game
82
70
! appShouldExit && ! renderer.interactivelyAdjustableSettings.abortThisRound
83
71
}
84
72
85
- // the simulation runner will invoke this callback, which we use to update the display
86
- val resultCallback = (state : SimState , tournamentRoundResult : TournamentRoundResult ) => {
87
- tournamentState.updateMostRecentState(state)
88
- tournamentState.addResult(tournamentRoundResult)
89
- }
90
-
91
-
92
- var pluginCollection = PluginCollection (pluginPath, gameSpecificPackagePath, verbose)
93
73
94
74
// now perform game runs ad infinitum
95
75
var roundIndex = 0
96
76
while (! appShouldExit && roundIndex < rounds) {
97
77
// load plugins, either from scratch or incrementally (changed plug-ins only)
98
- pluginCollection = pluginCollection.incrementalRescan // or: fullRescan
99
- val plugins = pluginCollection.plugins
78
+ val entityControllers = scalatron.freshEntityControllers
100
79
101
80
// update the game configuration based on the plug-ins that are loaded
102
- val gameConfig = Config .create(permanentConfig, roundIndex, plugins , argMap)
81
+ val gameConfig = Config .create(permanentConfig, roundIndex, entityControllers , argMap)
103
82
val factory = BotWarSimulation .Factory (gameConfig)
104
83
105
84
// prepare a random seed for this game round. Options:
@@ -108,8 +87,8 @@ case object BotWar extends Game
108
87
val randomSeed = System .currentTimeMillis.intValue // or: round
109
88
110
89
// run game
111
- val runner = Simulation .Runner (factory, stepCallback, resultCallback )
112
- runner(plugins , randomSeed)(actorSystem, executionContextForUntrustedCode)
90
+ val runner = Simulation .Runner (factory, stepCallback, scalatron.postRoundCallback )
91
+ runner(entityControllers , randomSeed)(scalatron. actorSystem, scalatron. executionContextForUntrustedCode)
113
92
114
93
roundIndex += 1
115
94
@@ -121,19 +100,14 @@ case object BotWar extends Game
121
100
122
101
123
102
def runHeadless (
124
- pluginPath : String ,
125
- argMap : Map [String ,String ],
126
103
rounds : Int ,
127
- tournamentState : TournamentState , // receives tournament round results
128
- secureMode : Boolean ,
129
- verbose : Boolean
130
- )(
131
- actorSystem : ActorSystem ,
132
- executionContextForUntrustedCode : ExecutionContext
104
+ scalatron : ScalatronInward
133
105
)
134
106
{
107
+ val argMap = scalatron.argMap
108
+
135
109
// determine the permanent configuration for the game
136
- val permanentConfig = PermanentConfig .fromArgMap(secureMode, argMap)
110
+ val permanentConfig = PermanentConfig .fromArgMap(scalatron. secureMode, argMap)
137
111
138
112
// determine the maximum frames/second (to throttle CPU usage or sim loop; min: 1 fps)
139
113
val maxFPS = argMap.get(" -maxfps" ).map(_.toInt).getOrElse(50 ).max(1 )
@@ -142,7 +116,7 @@ case object BotWar extends Game
142
116
143
117
// the simulation runner will invoke this callback, which we use to update the display
144
118
val stepCallback = (state : SimState ) => {
145
- tournamentState.updateMostRecentState (state)
119
+ scalatron.postStepCallback (state)
146
120
147
121
// enforce maxFPS (max frames per second) by putting this thread to sleep if appropriate
148
122
val currentTime = System .currentTimeMillis
@@ -154,25 +128,16 @@ case object BotWar extends Game
154
128
true
155
129
}
156
130
157
- // the simulation runner will invoke this callback, which we use to update the tournament state
158
- val resultCallback = (state : SimState , tournamentRoundResult : TournamentRoundResult ) => {
159
- tournamentState.updateMostRecentState(state)
160
- tournamentState.addResult(tournamentRoundResult)
161
- }
162
-
163
- var pluginCollection = PluginCollection (pluginPath, gameSpecificPackagePath, verbose)
164
-
165
131
// now perform game runs ad infinitum
166
132
var roundIndex = 0
167
133
while (roundIndex < rounds) {
168
134
val startTime = System .currentTimeMillis()
169
135
170
136
// load plugins, either from scratch or incrementally (changed plug-ins only)
171
- pluginCollection = pluginCollection.incrementalRescan // or: fullRescan
172
- val plugins = pluginCollection.plugins
137
+ val entityControllers = scalatron.freshEntityControllers
173
138
174
139
// update the game configuration based on the plug-ins that are loaded
175
- val gameConfig = Config .create(permanentConfig, roundIndex, plugins , argMap)
140
+ val gameConfig = Config .create(permanentConfig, roundIndex, entityControllers , argMap)
176
141
val factory = BotWarSimulation .Factory (gameConfig)
177
142
178
143
// prepare a random seed for this game round. Options:
@@ -181,8 +146,8 @@ case object BotWar extends Game
181
146
val randomSeed = System .currentTimeMillis.intValue // or: round
182
147
183
148
// run game
184
- val runner = Simulation .Runner (factory, stepCallback, resultCallback )
185
- runner(plugins , randomSeed)(actorSystem, executionContextForUntrustedCode)
149
+ val runner = Simulation .Runner (factory, stepCallback, scalatron.postRoundCallback )
150
+ runner(entityControllers , randomSeed)(scalatron. actorSystem, scalatron. executionContextForUntrustedCode)
186
151
187
152
roundIndex += 1
188
153
@@ -196,13 +161,13 @@ case object BotWar extends Game
196
161
197
162
198
163
/** Starts a headless game simulation using the given plug-in collection.
199
- * @param plugins the collection of plug-ins to use as control function factories.
164
+ * @param entityControllers the collection of plug-ins to use as control function factories.
200
165
* @param secureMode if true, certain bot processing restrictions apply
201
166
* @param argMap the command line arguments
202
167
* @return the initial simulation state
203
168
*/
204
169
def startHeadless (
205
- plugins : Iterable [Plugin . FromJarFile ],
170
+ entityControllers : Iterable [EntityController ],
206
171
secureMode : Boolean ,
207
172
argMap : Map [String ,String ]
208
173
)(
@@ -214,7 +179,7 @@ case object BotWar extends Game
214
179
val roundIndex = 0
215
180
216
181
// determine the per-round configuration for the game
217
- val gameConfig : Config = Config .create(permanentConfig, roundIndex, plugins , argMap)
182
+ val gameConfig : Config = Config .create(permanentConfig, roundIndex, entityControllers , argMap)
218
183
219
184
// update the game configuration based on the plug-ins that are loaded
220
185
@@ -225,21 +190,20 @@ case object BotWar extends Game
225
190
// (b) deterministically incremented (beneficial for testing purposes)
226
191
val randomSeed = System .currentTimeMillis.intValue // or: round
227
192
228
- factory.createInitialState(randomSeed, plugins)( executionContextForUntrustedCode)
193
+ factory.createInitialState(randomSeed, entityControllers, executionContextForUntrustedCode)
229
194
}
230
195
231
196
232
197
/** Starts a headless game simulation using the given plug-in collection.
233
- * @param plugins the collection of plug-ins to use as control function factories.
198
+ * @param entityControllers the collection of plug-ins to use as control function factories.
234
199
* @return the initial simulation state
235
200
*/
236
201
def startHeadless (
237
- plugins : Iterable [Plugin .FromJarFile ],
238
- roundConfig : RoundConfig
239
- )(
202
+ entityControllers : Iterable [EntityController ],
203
+ roundConfig : RoundConfig ,
240
204
executionContextForUntrustedCode : ExecutionContext
241
205
) : SimState = {
242
- val gameConfig = Config .create(roundConfig.permanent, roundConfig.roundIndex, plugins , roundConfig.argMap)
206
+ val gameConfig = Config .create(roundConfig.permanent, roundConfig.roundIndex, entityControllers , roundConfig.argMap)
243
207
244
208
// update the game configuration based on the plug-ins that are loaded
245
209
val factory = BotWarSimulation .Factory (gameConfig)
@@ -249,19 +213,14 @@ case object BotWar extends Game
249
213
// (b) deterministically incremented (beneficial for testing purposes)
250
214
val randomSeed = System .currentTimeMillis.intValue // or: round
251
215
252
- factory.createInitialState(randomSeed, plugins)( executionContextForUntrustedCode)
216
+ factory.createInitialState(randomSeed, entityControllers, executionContextForUntrustedCode)
253
217
}
254
218
255
219
256
220
/** Dump the game-specific command line configuration options via println.
257
221
* "... -x 100 -y 100 -steps 1000" */
258
- def printArgList () {
259
- Config .printArgList()
260
- PermanentConfig .printArgList()
261
- Display .printArgList()
262
- Renderer .printKeyboardCommands()
263
-
264
- println(" -maxfps <int> maximum steps/second (to reduce CPU load; default: 50)" )
265
- }
222
+ def cmdArgList =
223
+ Iterable (" maxfps <int>" -> " maximum steps/second (to reduce CPU load; default: 50)" ) ++
224
+ Config .cmdArgList ++ Display .cmdArgList
266
225
}
267
226
0 commit comments