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
RevLine 
[232]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       
[480]30        ExpProperties.memberssno = 4;
31        ExpProperties.teamsno = 2;
32        ExpProperties.mindistance = 60;
[232]33       
[480]34        ExpProperties.pointsCapture = 10;
35        ExpProperties.pointsRetrieve = 5;
36        ExpProperties.pointsScoring = 50;
[232]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{
[480]52        ExpProperties_create_call();
[232]53
54}
55
[233]56function onBorn(cr)
[232]57{
[233]58  cr.energ0 = 100;
59  cr.energy = cr.energ0;
[232]60}
61
[233]62function onDied(cr)
[232]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
[480]86function ExpProperties_create_call(){
[232]87        //Create GenePool and Population for each team
88        GenePools.clear();
[233]89        var pool=GenePools[0];
90        pool.name = "Team1";
[485]91        pool.fitness = "return 0;";
[233]92        while (pool.size > 0)
93                pool.delete(0);
[232]94       
95        Populations.clear();
[233]96        var pop=Populations[0];
97        pop.name = "Team1";
[232]98       
[233]99        while (pop.size > 0)
100                        pop.delete(0);
[232]101       
102       
103       
[233]104        pop.selfmask = 0x50001;
105    pop.othermask = 0x60001;
[232]106       
107        var i = 2;
[480]108        for (i = 2; i <= ExpProperties.teamsno; i++){
[233]109                pop=Populations.addGroup("Team"+i);
110                pop.selfmask = 0x50001;
111        pop.othermask = 0x60001;
112                pool=GenePools.addGroup("Team"+i);
[485]113                pool.fitness = "return 0;";
[232]114        }
115       
116        //Create GenePool for flags and fill it
[233]117        pool=GenePools.addGroup("Flags");
[232]118       
[233]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"));
[232]124}
125
[480]126function ExpProperties_fill_call(){
[232]127        var team = 0;
128        var player = 0;
129       
130        //Reset all global points vectors
[233]131        flagsX = [];
132        flagsY = [];
[232]133       
[233]134        points = [];
135        scored = [];
136        taken = [];
137        retrieved = [];
[232]138       
139        //Init global vectors
140        var x, y, i;
141        var ok = 0;
142       
[480]143        for (i = 0; i < ExpProperties.teamsno; i++){
[232]144                points.add(0);
145                scored.add(0);
146                taken.add(0);
147                retrieved.add(0);       
148        }
149       
150        //Clear Populations
[480]151        for (team = 0; team < ExpProperties.teamsno; team++){
[232]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;         
[480]164                while (flagsX.size < ExpProperties.teamsno && ok == 1){
[232]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++){
[480]173                                        if (Math.sqrt(Math.pow(flagsX[i] - x, 2)+Math.pow(flagsY[i] - y,2)) < ExpProperties.mindistance){
[232]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               
[480]187                if (flagsX.size == ExpProperties.teamsno)
[232]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
[480]201        for (team = 0; team < ExpProperties.teamsno; team++){
[232]202                while (Populations[team].size > 0)
203                        Populations[team].delete(0);
204               
[480]205                var cr = Populations[team].add(GenePools[ExpProperties.teamsno][team]);
[233]206                placeFlag(cr);
207                cr.signals.add("Flag");
208                cr.signals[0].flavor = team;
209                cr.signals[0].power=1000;
[485]210                cr.data->taken = 0;
211                cr.data->owner = 0;
212                cr.data->cooldown = 0;
[232]213               
214                var crX, crY;
215               
[480]216                for (player = 0; player < ExpProperties.memberssno; player++){
[233]217                        var pool=GenePools[team];
218                        cr = Populations[team].add(pool[player % pool.size]);
[232]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;
[233]229                        cr.moveAbs(flagsX[team] + crX, flagsY[team] + crY, 0);
[485]230                        cr.data->holding = 0;
231                        cr.data->flag = 0;
232                        cr.data->score = 0;
[232]233                }
234        }
235}
236
[480]237function ExpProperties_default_call(){
[232]238        //Insert default player genotype in team's GenePools
239        var team = 0;
[480]240        for (team = 0; team < ExpProperties.teamsno; team++){
[232]241                while (GenePools[team].size > 0)
242                        GenePools[team].delete(0);
243                if (team != 1)
[233]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"));
[232]245                else if (team == 1)
[233]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"));
[232]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++){
[233]256                var pop=Populations[team];
257
[485]258                if (pop[0].data->cooldown > 0)
259                        pop[0].data->cooldown -= 1;
[232]260               
[233]261                for (player = 1; player < pop.size; player++){
262                        var cr=pop[player];
[485]263                        if (cr.data->holding == 1){
264                                cr.data->flag.moveAbs(cr.pos_x, cr.pos_y, cr.size_z + 1);
[232]265                        }
266                }
267        }
268       
269//      if (Simulator.time % 100 == 0){
270//              var i = 0;
271//              var line = "";
272//              line=line+Simulator.time+";";
273//             
[480]274//              for (i = 0; i < ExpProperties.teamsno; i++){
[232]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){
[233]285        flag.moveAbs(flagsX[flag.population.index], flagsY[flag.population.index], 0);
[232]286}
287
288function takeFlag(flag, creature){
289        //If the cooldown is on - do nothing
[485]290        if (flag.data->cooldown > 0)
[232]291                return;
292       
293        //Take flag by changing its flavour and setting flag in player and player in flag fields
[233]294        flag.signals[0].flavor = flag.population.index + 100;
[485]295        flag.data->taken = 1;
296        flag.data->owner = creature;
297        creature.data->holding = 1;
298        creature.data->flag = flag;
[232]299       
300        //Score points for taking a flag
[485]301        creature.data->score += ExpProperties.pointsCapture;
[232]302       
303//      Simulator.print("Flag "+(flag.group.index+1)+" taken by team "+(creature.group.index+1));
304       
305        //Update team points and events
[480]306        points[creature.population.index] = points[creature.population.index] + ExpProperties.pointsCapture;
[233]307        taken[creature.population.index] = taken[creature.population.index] + 1;
[232]308
309}
310
311function retrieveFlag(flag, creature){
312        //Retrieve flag by changing its flavour and deleting it from player and player from flag
[233]313        flag.signals[0].flavor = flag.population.index;
[485]314        flag.data->taken = 0;
[232]315       
[485]316        flag.data->owner.data->holding = 0;
317        flag.data->owner.data->flag = 0;
[232]318       
[485]319        flag.data->owner = 0;
[232]320       
321        //Set cooldown for taking a flag
[485]322        flag.data->cooldown = 1000;
[232]323       
324        placeFlag(flag);
325
326        //Score points for retrieving a flag
[485]327        creature.data->score += ExpProperties.pointsRetrieve;
[232]328       
329//      Simulator.print("Flag "+ (flag.group.index+1) +" retrieved");
330       
331        //Update team scores
[480]332        points[creature.population.index] = points[creature.population.index] + ExpProperties.pointsRetrieve;
[233]333        retrieved[creature.population.index] = retrieved[creature.population.index] + 1;
[232]334}
335
336function scoreFlag(flag, creature){
337        //Put the flag back on its spot and delete references between player and flag
[485]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;
[232]341       
[485]342        placeFlag(creature.data->flag);
[232]343       
[485]344        creature.data->holding = 0;
345        creature.data->flag = 0;
[232]346       
347        //Score points for scoring a flag
[485]348        creature.data->score += ExpProperties.pointsScoring;
[232]349       
350//      Simulator.print("Team "+ (creature.group.index + 1) +" scored");
351       
352        //Update team points
[480]353        points[creature.population.index] = points[creature.population.index] + ExpProperties.pointsScoring;
[233]354        scored[creature.population.index] = scored[creature.population.index] + 1;
[232]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
[485]384                if (flag.population.index == creature.population.index && flag.data->taken == 1){
[232]385                        retrieveFlag(flag, creature);
386                } //Collision with my flag which is not taken while carrying another team's flag
[485]387                else if (flag.population.index == creature.population.index && flag.data->taken == 0 && creature.data->holding == 1 && flag.data->cooldown != 1){
[232]388                        scoreFlag(flag, creature);
389                } //Collision with another team's flag which is not taken while not carrying any flag
[485]390                else if (flag.population.index != creature.population.index && flag.data->taken == 0 && creature.data->holding == 0 && flag.data->cooldown != 1){
[232]391                        takeFlag(flag, creature);
392                }
393        }
394        //Player vs. player collision
395        else {
396                //Players of different teams
[233]397                if (c1.population.index != c2.population.index){
[232]398                        //If player 1 has a flag ...
[485]399                        if (c1.data->holding == 1){
[232]400                                // ... and the flag is of my team ...
[485]401                                if (c2.population.index == c1.data->flag.population.index){
[232]402                                        //... retrieve it
[485]403                                        retrieveFlag(c1.data->flag, c2);
[232]404                                }
405                        }
406                        //If player 2 has a flag ...
[485]407                        if (c2.data->holding == 1){
[232]408                                // ... and the flag is of my team ...
[485]409                                 if (c1.population.index == c2.data->flag.population.index){
[232]410                                        //... retrieve it
[485]411                                        retrieveFlag(c2.data->flag, c1);
[232]412                                }
413                        }
414                }
415        }
416
417
418
419~
420
[480]421property:
[232]422id:teamsno
423name:Number of teams
424type:d 2 5
425
[480]426property:
[232]427id:memberssno
428name:Number of members in team
429type:d 1 8
430
[480]431property:
[232]432id:mindistance
433name:Minimal distance between flags
434type:d 1 100
435
[480]436property:
[232]437id:create
438name:Create teams
439type:p
440
[480]441property:
[232]442id:default
443name:Insert default player
444type:p
445
[480]446property:
[232]447id:fill
448name:Fill teams
449type:p
450
[480]451property:
[232]452id:pointsCapture
453name:Points for flag capture
454type:d 0 100
455
[480]456property:
[232]457id:pointsRetrieve
458name:Points for flag retrieve
459type:d 0 100
460
[480]461property:
[232]462id:pointsScoring
463name:Points for scoring a flag
464type:d 0 100
465
Note: See TracBrowser for help on using the repository browser.