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

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

capture-the-flag using data->fields:

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