expdef: name:Capture The Flag game info:~ A simple Capture The Flag game. Read more at http://www.framsticks.com/capture-the-flag ~ code:~ //Flag positions global flagsX; global flagsY; //global log; //Sum of team points and events global points; global scored; global taken; global retrieved; function onExpDefLoad() { GenePools.clear(); Populations.clear(); World.wrldsiz = 100; World.wrldtyp = 0; World.wrldbnd = 2; //Teleport ExpParams.memberssno = 4; ExpParams.teamsno = 2; ExpParams.mindistance = 60; ExpParams.pointsCapture = 10; ExpParams.pointsRetrieve = 5; ExpParams.pointsScoring = 50; //Styles of flags Shapes.set("1p_flag0","lllX(X, RRllX(, RRllX(, (X, lllX, X),), LLLLLLLX(,, llllX)), X)", 0xFF0000); Shapes.set("1p_flag1","lllX(X, RRllX(, RRllX(, (X, lllX, X),), LLLLLLLX(,, llllX)), X)", 0x0000FF); Shapes.set("1p_flag2","lllX(X, RRllX(, RRllX(, (X, lllX, X),), LLLLLLLX(,, llllX)), X)", 0x00FF00); Shapes.set("1p_flag3","lllX(X, RRllX(, RRllX(, (X, lllX, X),), LLLLLLLX(,, llllX)), X)", 0x00FFFF); Shapes.set("1p_flag4","lllX(X, RRllX(, RRllX(, (X, lllX, X),), LLLLLLLX(,, llllX)), X)", 0xFF00FF); // log = File.createDirect("statistics"+Math.time+".txt","CTF statistics"); // log.writeString("Step;Team1_Points;Team1_Scored;Team1_Captured;Team1_Retrieved;Team2_Points;Team2_Scored;Team2_Captured;Team2_Retrieved;\n"); } function onExpInit() { ExpParams_create_call(); } function onBorn() { Creature.energ0 = 100; Creature.energy = Creature.energ0; } function onDied() { } function onExpLoad() { } function onExpLoad_Unknown() { } function onExpSave() { } function createTeams(){ } function ExpParams_create_call(){ //Create GenePool and Population for each team GenePools.clear(); GenePool.name = "Team1"; GenePool.fitness = "return this.user3;"; while (GenePools[0].size > 0) GenePools[0].delete(0); Populations.clear(); Population.name = "Team1"; while (Population.size > 0) Population.delete(0); Population.selfmask = 0x50001; Population.othermask = 0x60001; var i = 2; for (i = 2; i <= ExpParams.teamsno; i++){ Populations.addGroup("Team"+i); Population.selfmask = 0x50001; Population.othermask = 0x60001; GenePools.addGroup("Team"+i); GenePool.fitness = "return this.user3;"; } //Create GenePool for flags and fill it GenePools.addGroup("Flags"); GenePool.addGeno(Geno.newFrom("m:Vstyle=flag0\np:",48,"Flag","Single flag object")); GenePool.addGeno(Geno.newFrom("m:Vstyle=flag1\np:",48,"Flag","Single flag object")); GenePool.addGeno(Geno.newFrom("m:Vstyle=flag2\np:",48,"Flag","Single flag object")); GenePool.addGeno(Geno.newFrom("m:Vstyle=flag3\np:",48,"Flag","Single flag object")); GenePool.addGeno(Geno.newFrom("m:Vstyle=flag4\np:",48,"Flag","Single flag object")); } function ExpParams_fill_call(){ var team = 0; var player = 0; //Reset all global points vectors flagsX = Vector.new(); flagsY = Vector.new(); points = Vector.new(); scored = Vector.new(); taken = Vector.new(); retrieved = Vector.new(); //Init global vectors var x, y, i; var ok = 0; for (i = 0; i < ExpParams.teamsno; i++){ points.add(0); scored.add(0); taken.add(0); retrieved.add(0); } //Clear Populations for (team = 0; team < ExpParams.teamsno; team++){ while (Populations[team].size > 0) Populations[team].delete(0); } //Draw flag positions according to minimal distance parameter var totalTries = 0, flagTries = 0, done = 0; while (totalTries < 1000 && done == 0){ flagsX = Vector.new(); flagsY = Vector.new(); ok = 1; while (flagsX.size < ExpParams.teamsno && ok == 1){ ok = 0; flagTries = 0; while (ok == 0 && flagTries < 1000){ x = Math.random(80) + 10; y = Math.random(80) + 10; ok = 1; for (i = 0; i < flagsX.size; i++){ if (Math.sqrt(Math.pow(flagsX[i] - x, 2)+Math.pow(flagsY[i] - y,2)) < ExpParams.mindistance){ ok = 0; break; } } if (ok == 1){ flagsX.add(x); flagsY.add(y); } else flagTries += 1; } } if (flagsX.size == ExpParams.teamsno) done = 1; else totalTries += 1; } //Flags weren't placed successfully' if (done != 1){ Simulator.message("Flags could not be placed correctly. Consider lowering minimal distance between flags.", 2); Simulator.beep(); return; } //Fill each team's Population with players and a flag and place players close to their flag for (team = 0; team < ExpParams.teamsno; team++){ while (Populations[team].size > 0) Populations[team].delete(0); GenePools.group = ExpParams.teamsno; GenePools.genotype = team; Populations[team].createFromGenotype(); placeFlag(Populations[team][0]); Creature.signals.add("Flag"); Creature.signals[0].flavor = team; Creature.signals[0].power=1000; Creature.user1 = 0; Creature.user2 = 0; Creature.user3 = 0; GenePools.group = team; var crX, crY; for (player = 0; player < ExpParams.memberssno; player++){ GenePools.genotype = player % GenePool.size; Populations[team].createFromGenotype(); crX = Math.random(30) - 15; if (crX >=0 && crX < 5) crX = 5; else if (crX > -5 && crX < 0) crX = -5; crY = Math.random(30) - 15; if (crY >=0 && crY < 5) crY = 5; else if (crY > -5 && crY < 0) crY = -5; Creature.moveAbs(flagsX[team] + crX, flagsY[team] + crY, 0); Creature.user1 = 0; Creature.user2 = 0; Creature.user3 = 0; } } } function ExpParams_default_call(){ //Insert default player genotype in team's GenePools var team = 0; for (team = 0; team < ExpParams.teamsno; team++){ while (GenePools[team].size > 0) GenePools[team].delete(0); if (team != 1) GenePools[team].addGeno(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")); else if (team == 1) GenePools[team].addGeno(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")); } } function onStep(){ var team = 0; var player = 0; //Update flags position if taken and cooldown if recently retrieved for (team = 0; team < Populations.size; team++){ Populations.group = team; Populations.creature = 0; if (Creature.user3 > 0) Creature.user3 -= 1; for (player = 1; player < Population.size; player++){ Populations.creature = player; if (Creature.user1 == 1){ Creature.user2.moveAbs(Creature.pos_x, Creature.pos_y, Creature.size_z + 1); } } } // if (Simulator.time % 100 == 0){ // var i = 0; // var line = ""; // line=line+Simulator.time+";"; // // for (i = 0; i < ExpParams.teamsno; i++){ // line=line+points[i]+";"+scored[i]+";"+taken[i]+";"+retrieved[i]+";"; // } // line=line+"\n"; // log.writeString(line); // // } } function placeFlag(flag){ flag.moveAbs(flagsX[flag.group.index], flagsY[flag.group.index], 0); } function takeFlag(flag, creature){ //If the cooldown is on - do nothing if (flag.user3 > 0) return; //Take flag by changing its flavour and setting flag in player and player in flag fields flag.signals[0].flavor = flag.group.index + 100; flag.user1 = 1; flag.user2 = creature; creature.user1 = 1; creature.user2 = flag; //Score points for taking a flag creature.user3 += ExpParams.pointsCapture; // Simulator.print("Flag "+(flag.group.index+1)+" taken by team "+(creature.group.index+1)); //Update team points and events points.set(creature.group.index, points[creature.group.index] + ExpParams.pointsCapture); taken.set(creature.group.index, taken[creature.group.index] + 1); } function retrieveFlag(flag, creature){ //Retrieve flag by changing its flavour and deleting it from player and player from flag flag.signals[0].flavor = flag.group.index; flag.user1 = 0; flag.user2.user1 = 0; flag.user2.user2 = 0; flag.user2 = 0; //Set cooldown for taking a flag flag.user3 = 1000; placeFlag(flag); //Score points for retrieving a flag creature.user3 += ExpParams.pointsRetrieve; // Simulator.print("Flag "+ (flag.group.index+1) +" retrieved"); //Update team scores points.set(creature.group.index, points[creature.group.index] + ExpParams.pointsRetrieve); retrieved.set(creature.group.index, retrieved[creature.group.index] + 1); } function scoreFlag(flag, creature){ //Put the flag back on its spot and delete references between player and flag creature.user2.signals[0].flavor = creature.user2.group.index; creature.user2.user1 = 0; creature.user2.user2 = 0; placeFlag(creature.user2); creature.user1 = 0; creature.user2 = 0; //Score points for scoring a flag creature.user3 += ExpParams.pointsScoring; // Simulator.print("Team "+ (creature.group.index + 1) +" scored"); //Update team points points.set(creature.group.index, points[creature.group.index] + ExpParams.pointsScoring); scored.set(creature.group.index, scored[creature.group.index] + 1); } function onTeam1CrCollision, onTeam2CrCollision, onTeam3CrCollision, onTeam4CrCollision, onTeam5CrCollision(){ var c1 = CrCollision.Creature1; var c2 = CrCollision.Creature2; //Flag vs. flag collision - do nothing if (c1.geno.name == "Flag" && c2.geno.name == "Flag"){ return; } var flag; var creature; var colFlag = 0; //Try to assign colliding creatures to flag and player if (c1.geno.name == "Flag"){ flag = c1; creature = c2; colFlag = 1; } else if (c2.geno.name == "Flag"){ flag = c2; creature = c1; colFlag = 1; } //Flag vs. player collision if (colFlag == 1){ //Collision with my flag which is taken if (flag.group.index == creature.group.index && flag.user1 == 1){ retrieveFlag(flag, creature); } //Collision with my flag which is not taken while carrying another team's flag else if (flag.group.index == creature.group.index && flag.user1 == 0 && creature.user1 == 1 && flag.user3 != 1){ scoreFlag(flag, creature); } //Collision with another team's flag which is not taken while not carrying any flag else if (flag.group.index != creature.group.index && flag.user1 == 0 && creature.user1 == 0 && flag.user3 != 1){ takeFlag(flag, creature); } } //Player vs. player collision else { //Players of different teams if (c1.group.index != c2.group.index){ //If player 1 has a flag ... if (c1.user1 == 1){ // ... and the flag is of my team ... if (c2.group.index == c1.user2.group.index){ //... retrieve it retrieveFlag(c1.user2, c2); } } //If player 2 has a flag ... if (c2.user1 == 1){ // ... and the flag is of my team ... if (c1.group.index == c2.user2.group.index){ //... retrieve it retrieveFlag(c2.user2, c1); } } } } } ~ prop: id:teamsno name:Number of teams type:d 2 5 prop: id:memberssno name:Number of members in team type:d 1 8 prop: id:mindistance name:Minimal distance between flags type:d 1 100 prop: id:create name:Create teams type:p prop: id:default name:Insert default player type:p prop: id:fill name:Fill teams type:p prop: id:pointsCapture name:Points for flag capture type:d 0 100 prop: id:pointsRetrieve name:Points for flag retrieve type:d 0 100 prop: id:pointsScoring name:Points for scoring a flag type:d 0 100