source: experiments/frams/capture-the-flag/data/scripts/capture-the-flag.expdef @ 1300

Last change on this file since 1300 was 634, checked in by sz, 8 years ago

Updated for the upcoming Framsticks release - the old Shapes object is now called WireframeAppearance?.

File size: 12.2 KB
Line 
1expdef:
2name:Capture The Flag game
3info:~
4A simple Capture The Flag game. Read more at
5http://www.framsticks.com/capture-the-flag
6~
7code:~
8
9//Flag positions
10global flagsX;
11global flagsY;
12
13//global log;
14
15//Sum of team points and events
16global points;
17global scored;
18global taken;
19global retrieved;
20
21function onExpDefLoad()
22{
23        World.wrldsiz = 100;
24        World.wrldtyp = 0;
25        World.wrldbnd = 2; //Teleport
26       
27        ExpProperties.memberssno = 4;
28        ExpProperties.teamsno = 2;
29        ExpProperties.mindistance = 60;
30       
31        ExpProperties.pointsCapture = 10;
32        ExpProperties.pointsRetrieve = 5;
33        ExpProperties.pointsScoring = 50;
34
35        //Styles of flags
36        WireframeAppearance.set("1p_flag0","lllX(X, RRllX(, RRllX(, (X, lllX, X),), LLLLLLLX(,, llllX)), X)", 0xFF0000);
37        WireframeAppearance.set("1p_flag1","lllX(X, RRllX(, RRllX(, (X, lllX, X),), LLLLLLLX(,, llllX)), X)", 0x0000FF);
38        WireframeAppearance.set("1p_flag2","lllX(X, RRllX(, RRllX(, (X, lllX, X),), LLLLLLLX(,, llllX)), X)", 0x00FF00);
39        WireframeAppearance.set("1p_flag3","lllX(X, RRllX(, RRllX(, (X, lllX, X),), LLLLLLLX(,, llllX)), X)", 0x00FFFF);
40        WireframeAppearance.set("1p_flag4","lllX(X, RRllX(, RRllX(, (X, lllX, X),), LLLLLLLX(,, llllX)), X)", 0xFF00FF);
41       
42//      log = File.createDirect("statistics"+Math.time+".txt","CTF statistics");
43//      log.writeString("Step;Team1_Points;Team1_Scored;Team1_Captured;Team1_Retrieved;Team2_Points;Team2_Scored;Team2_Captured;Team2_Retrieved;\n");
44
45}
46
47function onExpInit()
48{
49        ExpProperties_create_call();
50
51}
52
53function onBorn(cr)
54{
55  cr.energy0 = 100;
56  cr.energy = cr.energy0;
57}
58
59function onDied(cr)
60{
61 
62}
63
64function onExpLoad()
65{
66 
67}
68
69function onExpLoad_Unknown()
70{
71 
72}
73
74function onExpSave()
75{
76 
77}
78
79function createTeams(){
80       
81}
82
83function ExpProperties_create_call(){
84        //Create GenePool and Population for each team
85        GenePools.clear();
86        var pool=GenePools[0];
87        pool.name = "Team1";
88        pool.fitness = "return 0;";
89        while (pool.size > 0)
90                pool.delete(0);
91       
92        Populations.clear();
93        var pop=Populations[0];
94        pop.name = "Team1";
95       
96        while (pop.size > 0)
97                        pop.delete(0);
98       
99       
100       
101        pop.selfmask = 0x50001;
102    pop.othermask = 0x60001;
103       
104        var i = 2;
105        for (i = 2; i <= ExpProperties.teamsno; i++){
106                pop=Populations.addGroup("Team"+i);
107                pop.selfmask = 0x50001;
108        pop.othermask = 0x60001;
109                pool=GenePools.addGroup("Team"+i);
110                pool.fitness = "return 0;";
111        }
112       
113        //Create GenePool for flags and fill it
114        pool=GenePools.addGroup("Flags");
115       
116        pool.add(Geno.newFrom("m:Vstyle=flag0\np:",48,"Flag","Single flag object"));
117        pool.add(Geno.newFrom("m:Vstyle=flag1\np:",48,"Flag","Single flag object"));
118        pool.add(Geno.newFrom("m:Vstyle=flag2\np:",48,"Flag","Single flag object"));
119        pool.add(Geno.newFrom("m:Vstyle=flag3\np:",48,"Flag","Single flag object"));
120        pool.add(Geno.newFrom("m:Vstyle=flag4\np:",48,"Flag","Single flag object"));
121}
122
123function ExpProperties_fill_call(){
124        var team = 0;
125        var player = 0;
126       
127        //Reset all global points vectors
128        flagsX = [];
129        flagsY = [];
130       
131        points = [];
132        scored = [];
133        taken = [];
134        retrieved = [];
135       
136        //Init global vectors
137        var x, y, i;
138        var ok = 0;
139       
140        for (i = 0; i < ExpProperties.teamsno; i++){
141                points.add(0);
142                scored.add(0);
143                taken.add(0);
144                retrieved.add(0);       
145        }
146       
147        //Clear Populations
148        for (team = 0; team < ExpProperties.teamsno; team++){
149                while (Populations[team].size > 0)
150                        Populations[team].delete(0);
151        }
152       
153        //Draw flag positions according to minimal distance parameter
154        var totalTries = 0, flagTries = 0, done = 0;
155       
156        while (totalTries < 1000 && done == 0){
157                flagsX = Vector.new();
158                flagsY = Vector.new();
159
160                ok = 1;         
161                while (flagsX.size < ExpProperties.teamsno && ok == 1){
162                        ok = 0;
163                        flagTries = 0;
164                        while (ok == 0 && flagTries < 1000){
165                                x = Math.random(80) + 10;
166                                y = Math.random(80) + 10;
167                               
168                                ok = 1;
169                                for (i = 0; i < flagsX.size; i++){
170                                        if (Math.sqrt(Math.pow(flagsX[i] - x, 2)+Math.pow(flagsY[i] - y,2)) < ExpProperties.mindistance){
171                                                ok = 0;
172                                                break;
173                                        }
174                                }
175                                if (ok == 1){
176                                        flagsX.add(x);
177                                        flagsY.add(y);
178                                } else
179                                        flagTries += 1;
180                        }
181                       
182                }
183               
184                if (flagsX.size == ExpProperties.teamsno)
185                        done = 1;
186                else
187                        totalTries += 1;
188        }
189        //Flags weren't placed successfully'
190        if (done != 1){
191                Simulator.message("Flags could not be placed correctly. Consider lowering minimal distance between flags.", 2);
192                Simulator.beep();
193                return;
194        }
195       
196       
197        //Fill each team's Population with players and a flag and place players close to their flag
198        for (team = 0; team < ExpProperties.teamsno; team++){
199                while (Populations[team].size > 0)
200                        Populations[team].delete(0);
201               
202                var cr = Populations[team].add(GenePools[ExpProperties.teamsno][team]);
203                placeFlag(cr);
204                cr.signals.add("Flag");
205                cr.signals[0].flavor = team;
206                cr.signals[0].power=1000;
207                cr.data->taken = 0;
208                cr.data->owner = 0;
209                cr.data->cooldown = 0;
210               
211                var crX, crY;
212               
213                for (player = 0; player < ExpProperties.memberssno; player++){
214                        var pool=GenePools[team];
215                        cr = Populations[team].add(pool[player % pool.size]);
216                        crX = Math.random(30) - 15;
217                        if (crX >=0 && crX < 5)
218                                crX = 5;
219                        else if (crX > -5 && crX < 0)
220                                crX = -5;
221                        crY = Math.random(30) - 15;
222                        if (crY >=0 && crY < 5)
223                                crY = 5;
224                        else if (crY > -5 && crY < 0)
225                                crY = -5;
226                        cr.locationSetBboxLow(flagsX[team] + crX, flagsY[team] + crY, 0);
227                        cr.data->holding = 0;
228                        cr.data->flag = 0;
229                        cr.data->score = 0;
230                }
231        }
232}
233
234function ExpProperties_default_call(){
235        //Insert default player genotype in team's GenePools
236        var team = 0;
237        for (team = 0; team < ExpProperties.teamsno; team++){
238                while (GenePools[team].size > 0)
239                        GenePools[team].delete(0);
240                if (team != 1)
241                        GenePools[team].add(Geno.newFrom("lllfffX[0:2.420, 2:-2, 1:-1][-1:1, 0:1, 0:-1][-1:1](RRlllfffMMMX[|-1:-10]lllFFFMMMX[|-2:-1], fffIXlllfffMMMsX[|6:10, 3:-10](RRlllfffMMMIX[|-4:-10]lllFFFMMMIX[|-5:-1][*], , RRlllfffMMMIX[|-7:10]lllFFFMMMIX[|-8:-1][*]), RRlllfffMMMX[|-10:10]lllFFFMMMX[|-11:-1.784])", 49, "Player", "Player"));
242                else if (team == 1)
243                        GenePools[team].add(Geno.newFrom("lllfffX[0:2.420, 2:-2, 1:-1][-1:1, 0:1, 0:-1][-1:1](RRlllfffMMMX[|-1:-10]lllFFFMMMX[|-2:-1], fffIXlllfffMMMsX[|1:1][Thr2,lo:-0.75,hi:0.75,t:0.75,3:-10,6:10](RRlllfffMMMIX[|-4:-10]lllFFFMMMIX[|-5:-1][FlagDef,opp:0,my:1], , RRlllfffMMMIX[|-7:10]lllFFFMMMIX[|-8:-1][FlagDef,opp:0,my:1]), RRlllfffMMMX[|-10:10]lllFFFMMMX[|-11:-1.784])", 49, "Inteligent Player", "Inteligent Player"));
244        }
245}
246
247function onStep(){
248        var team = 0;
249        var player = 0;
250       
251        //Update flags position if taken and cooldown if recently retrieved
252        for (team = 0; team < Populations.size; team++){
253                var pop=Populations[team];
254
255                if (pop[0].data->cooldown > 0)
256                        pop[0].data->cooldown -= 1;
257               
258                for (player = 1; player < pop.size; player++){
259                        var cr=pop[player];
260                        if (cr.data->holding == 1){
261                                cr.data->flag.locationSetBboxLow(cr.bboxLow.x, cr.bboxLow.y, cr.bboxSize.z + 1);
262                        }
263                }
264        }
265       
266//      if (Simulator.time % 100 == 0){
267//              var i = 0;
268//              var line = "";
269//              line=line+Simulator.time+";";
270//             
271//              for (i = 0; i < ExpProperties.teamsno; i++){
272//                      line=line+points[i]+";"+scored[i]+";"+taken[i]+";"+retrieved[i]+";";
273//              }
274//              line=line+"\n";
275//              log.writeString(line);
276//             
277//      }
278       
279}
280
281function placeFlag(flag){
282        flag.locationSetBboxLow(flagsX[flag.population.index], flagsY[flag.population.index], 0);
283}
284
285function takeFlag(flag, creature){
286        //If the cooldown is on - do nothing
287        if (flag.data->cooldown > 0)
288                return;
289       
290        //Take flag by changing its flavour and setting flag in player and player in flag fields
291        flag.signals[0].flavor = flag.population.index + 100;
292        flag.data->taken = 1;
293        flag.data->owner = creature;
294        creature.data->holding = 1;
295        creature.data->flag = flag;
296       
297        //Score points for taking a flag
298        creature.data->score += ExpProperties.pointsCapture;
299       
300//      Simulator.print("Flag "+(flag.group.index+1)+" taken by team "+(creature.group.index+1));
301       
302        //Update team points and events
303        points[creature.population.index] = points[creature.population.index] + ExpProperties.pointsCapture;
304        taken[creature.population.index] = taken[creature.population.index] + 1;
305
306}
307
308function retrieveFlag(flag, creature){
309        //Retrieve flag by changing its flavour and deleting it from player and player from flag
310        flag.signals[0].flavor = flag.population.index;
311        flag.data->taken = 0;
312       
313        flag.data->owner.data->holding = 0;
314        flag.data->owner.data->flag = 0;
315       
316        flag.data->owner = 0;
317       
318        //Set cooldown for taking a flag
319        flag.data->cooldown = 1000;
320       
321        placeFlag(flag);
322
323        //Score points for retrieving a flag
324        creature.data->score += ExpProperties.pointsRetrieve;
325       
326//      Simulator.print("Flag "+ (flag.group.index+1) +" retrieved");
327       
328        //Update team scores
329        points[creature.population.index] = points[creature.population.index] + ExpProperties.pointsRetrieve;
330        retrieved[creature.population.index] = retrieved[creature.population.index] + 1;
331}
332
333function scoreFlag(flag, creature){
334        //Put the flag back on its spot and delete references between player and flag
335        creature.data->flag.signals[0].flavor = creature.data->flag.population.index;
336        creature.data->flag.data->taken = 0;
337        creature.data->flag.data->owner = 0;
338       
339        placeFlag(creature.data->flag);
340       
341        creature.data->holding = 0;
342        creature.data->flag = 0;
343       
344        //Score points for scoring a flag
345        creature.data->score += ExpProperties.pointsScoring;
346       
347//      Simulator.print("Team "+ (creature.group.index + 1) +" scored");
348       
349        //Update team points
350        points[creature.population.index] = points[creature.population.index] + ExpProperties.pointsScoring;
351        scored[creature.population.index] = scored[creature.population.index] + 1;
352}
353
354function onTeam1CrCollision, onTeam2CrCollision, onTeam3CrCollision, onTeam4CrCollision, onTeam5CrCollision(){
355        var c1 = CrCollision.Creature1;
356        var c2 = CrCollision.Creature2;
357
358        //Flag vs. flag collision - do nothing
359        if (c1.geno.name == "Flag" && c2.geno.name == "Flag"){
360                return;
361        }
362       
363        var flag;
364        var creature;
365        var colFlag = 0;
366       
367        //Try to assign colliding creatures to flag and player
368        if (c1.geno.name == "Flag"){
369                flag = c1;
370                creature = c2;
371                colFlag = 1;
372        } else if (c2.geno.name == "Flag"){
373                flag = c2;
374                creature = c1;
375                colFlag = 1;
376        }
377
378        //Flag vs. player collision
379        if (colFlag == 1){
380                //Collision with my flag which is taken
381                if (flag.population.index == creature.population.index && flag.data->taken == 1){
382                        retrieveFlag(flag, creature);
383                } //Collision with my flag which is not taken while carrying another team's flag
384                else if (flag.population.index == creature.population.index && flag.data->taken == 0 && creature.data->holding == 1 && flag.data->cooldown != 1){
385                        scoreFlag(flag, creature);
386                } //Collision with another team's flag which is not taken while not carrying any flag
387                else if (flag.population.index != creature.population.index && flag.data->taken == 0 && creature.data->holding == 0 && flag.data->cooldown != 1){
388                        takeFlag(flag, creature);
389                }
390        }
391        //Player vs. player collision
392        else {
393                //Players of different teams
394                if (c1.population.index != c2.population.index){
395                        //If player 1 has a flag ...
396                        if (c1.data->holding == 1){
397                                // ... and the flag is of my team ...
398                                if (c2.population.index == c1.data->flag.population.index){
399                                        //... retrieve it
400                                        retrieveFlag(c1.data->flag, c2);
401                                }
402                        }
403                        //If player 2 has a flag ...
404                        if (c2.data->holding == 1){
405                                // ... and the flag is of my team ...
406                                 if (c1.population.index == c2.data->flag.population.index){
407                                        //... retrieve it
408                                        retrieveFlag(c2.data->flag, c1);
409                                }
410                        }
411                }
412        }
413
414
415
416~
417
418property:
419id:teamsno
420name:Number of teams
421type:d 2 5
422
423property:
424id:memberssno
425name:Number of members in team
426type:d 1 8
427
428property:
429id:mindistance
430name:Minimal distance between flags
431type:d 1 100
432
433property:
434id:create
435name:Create teams
436type:p
437
438property:
439id:default
440name:Insert default player
441type:p
442
443property:
444id:fill
445name:Fill teams
446type:p
447
448property:
449id:pointsCapture
450name:Points for flag capture
451type:d 0 100
452
453property:
454id:pointsRetrieve
455name:Points for flag retrieve
456type:d 0 100
457
458property:
459id:pointsScoring
460name:Points for scoring a flag
461type:d 0 100
462
Note: See TracBrowser for help on using the repository browser.