Игры для программистовГотовые программы для игр Colobot и Ceebot

Астронавт-колоботерПоследнее время с поисковых систем стабильно приходят пользователи, пытающиеся найти у меня готовые программы для игр Colobot и Ceebot.

Поэтому я решил срочно исправляться. В этом посте я собрал некоторые программы, которые позволят Вам сэкономить время или посмотреть, как программируют в Colobot другие игроки.

Кстати, я написал отличный обзор этой игре у себя в блоге. Можете также почитать мои другие обзоры игр для программистов.

Пост получился очень большим из-за того что я привел исходные коды многих программ. Но, в любом случае, это будет удобно тем, кто ищет готовые программы — все в одном месте.

Аккуратно! Ваш скролл может умереть мучительной и жестокой смертью.

Программа для PhazerShooter

Поместите робота на местность (желательно повыше), активируйте и наблюдайте за его работой. Он уничтожит все цели, которые летят не выше 80 метров.

extern void object::Phazer()
{
	float scanRange = 150; // scan for targets within this radius
 
	// Platform specific parameters
	float minAngle = -20; // minimum gun elevation relative to platform
	float maxAngle = 45; // maximum gun elevation relative to platform
	float weaponHeight = 2; // height of weapon above platform
	float weaponOffset = 2; // weapon is this amount in front of platform
	float maxTurnRate = 54; // maximum turn rate
 
	// Ballistic parameters
	float v0 = 50; // muzzle velocity (m / s)
	float g = 50; // gravitation (m / s^2)
	float bc = v0 * v0 / g; // ballistic constant (max range at equal height)
 
	object target; // target
 
	while (true)
	{
		target = ScanForTarget(scanRange); // do a target scan
 
		while (target == null) // wait until target becomes available
		{
			motor(0,0); // engines idle
			wait(1); // wait a little to relieve CPU
			target = ScanForTarget(scanRange); // scan again
		}
 
		// Variables to track target (cylindrcal coцrdinates)
		float bearing, range, height, time;
		float deltaBearing, deltaRange, deltaHeight, deltaTime;
		// Initialize the 'old' variables
		float oldBearing = orientation + direction(target.position);
		float oldRange = distance2d(position, target.position);
		float oldHeight = target.position.z - position.z;
		float oldTime = abstime();
 
		// Variables needed for target solution
		float rt, zt;
		float t;
		float D;
		float it = sqrt(2) * oldRange / v0; // initial estimate for intercept time
		float azimuth;
		float elevation;
		float turnRate;
		float motorOutput;
 
		// Variables needed for slope correction
		float pitchAz;
		float rollAz;
		float a;
		float b;
		float c;
		float d;
		float corr;
 
		float fireTime = abstime() + 0.2; // don't fire for 0.5 seconds (first track target)
 
		while (target == ScanForTarget(scanRange)) // As long as target is the most critical target
		{
			// Collect data
			bearing = orientation + direction(target.position);
			range = distance2d(position, target.position);
			height = target.position.z - position.z;
			time = abstime();
 
			// Calculate differences
			deltaBearing = bearing - oldBearing;
			deltaRange = range - oldRange;
			deltaHeight = height - oldHeight;
			deltaTime = time - oldTime;
 
			// Save data for next pass
			oldBearing = bearing;
			oldRange = range;
			oldHeight = height;
			oldTime = time;
 
			// Extrapolate target motion to interception point
			t = it / deltaTime; // time factor
			azimuth = bearing + t * deltaBearing - orientation; // intercept azimuth
			if (azimuth < -180) azimuth += 360; // azimuth correction (pole passage)
			if (azimuth > 180) azimuth -= 360;
			zt = height + t * deltaHeight - cos(pitch) * cos(roll) * weaponHeight; // intercept height
			rt = range + t * deltaRange - weaponOffset * cos(azimuth) * cos(pitch); // intercept range
 
			// Calculate weapon elevation
			D = bc * (bc - 2 * zt) / (rt * rt) - 1; // discriminant
			if (D < 0)
			  elevation = atan(bc / rt); // target out of range
			else
			  elevation = atan(bc / rt - sqrt(D)); // target in range
 
			it = rt / (v0 * cos(elevation)); // intercept time (estimate for next pass)
 
			// Slope-correction
			pitchAz = pitch * cos(azimuth) - roll * sin(azimuth); // pitch at target azimuth
			rollAz = roll * cos(azimuth) + pitch * sin(azimuth); // roll at target azimuth
 
			// Solve slope-target spherical triangle
			b = elevation - pitchAz; // relative elevation at target azimuth
			a = asin(sin(b) * cos(rollAz)); // new gun elevation
			c = acos(cos(b) / cos(a)); if (b < 0) c = -c; // intermediate variable
			d = asin(sin(c) * sin(rollAz)); // intermediate variable
			corr = -acos(cos(c) / cos(d)); if (d < 0) corr = -corr; // azimuth correction
			azimuth += corr; // apply azimuthal correction
 
			// Point the weapon in the right direction
			aim(a); // weapon elevation
			turnRate = (deltaBearing + azimuth / 5) / deltaTime; // rotate with target
			motorOutput = 0.5 * turnRate / maxTurnRate; // calculate motor output
			motor(-motorOutput, motorOutput); // apply turn rate
 
			// Fire if target is within weapon envelope
			if (D >= 0 && a > minAngle - 2 && a < maxAngle + 2 && azimuth > -2 && azimuth < 2 && fireTime < abstime())
			{
				fire(0.2); // fire
				fireTime = abstime() + it + 0.1; // wait until round hit (or not)
				message("Firing at range " + distance(position, target.position) + " m."); // show off performance
			}
		}
	}
}
 
object object::ScanForTarget(float range) // does one scan sweep for targets within certain range
{
	object target = null;
 
	// search for nearest target
	for (int i = AlienAnt; i <= AlienWorm; i++)
	{
		object item = radar(i, 0, 360, 0, range); // scan for specific target type
		if (item != null) // if one found
		{
			target = item; // it becomes the target
			range = distance2d(position, target.position); // only pick up new targets closer than this one
		}
	}
	return target;
}

Дозаправщик (FieldRefuel)

Цель этой программы — увеличить длительность атаки ботами. Очень большое количество энергии тратится на перемещения с поля боя на базу, подзарядку и возвращение обратно. Эта программа позволяет создавать бота, который будет заниматься исключительно дозаправкой всех остальных роботов.

// FieldRefuel -- The purpose of this program is to extend the
// range of attack bots. It takes them too much energy to get
// out in the field to have to go back and refuel, so I just
// let them run as they will and have this program running on
// a dedicated bot all the time.
//
// It runs in conjunction with a public function I have on all
// my bots called FlatGround - when their energy level gets below
// 1/4, they look for the nearest flat spot at least 50 meters
// away from all enemies and goes to sit there to wait for
// refuelling. This prevents the refuel bot from sliding off a
// hillside and botching the switch.
//
// The bot that runs this sits at the power station, and when a
// bot gets to 1/4 energy it goes out to its position. The 2nd
// goto(bot.position) is to compensate for movement between the
// time that it hit the low power mark and found flat ground.
//
// It goes out to the downed bot, swaps cells (it assumes the
// fuel bot is holding 1 full cell at all times), and refuels.
// When it's done, it pulls back off the pad to make room for
// others.
 
extern void object::FieldRefuel()
{
 
	object power=radar(PowerStation);
	object bot=radar(TrackedShooter); //only watches 1 bot
 
	errmode(0);	//don't exit on errors
 
	while(true)	//infinite loop
	{
		while(bot.energyCell.energyLevel < 0.26) //1/4 energy
		{
			goto(bot.position);
			wait(1);
			goto(bot.position);	//movement correction
			drop(Behind);		//switch cells
			grab();
			turn(90);
			drop();
			turn(-90);
			grab(Behind);
			drop();
			turn(90);
			grab();
			goto(power.position);	//refuel
			wait(7);
			move(-5);
		}
	}
}

Муравьеубийца!

Улучшенная программа для убийства муравьев. Присутствуют баги, так что пользуйтесь аккуратно.

Предназначена для ботов WingedShooters.

extern void object::KillAnts()
{
	//preparation
	object ant;
	float angle;
	float sin1;
	object repair;
	object power;
	object ship;
 
	ant=radar(AlienAnt);
	//co kdyby tu uz zadnej ant nebyl?
 
	//rise 30metres
	while(altitude<30){
		jet(1);
	}
	ant=radar(AlienAnt);
 
	//main loop
	while(radar(AlienAnt)!=null){
		if(ant==null){
			break;
		}
 
		if(temperature>0.8){
			while(altitude!=0){
				jet(-1);
			}
 
			wait(2);
		}
 
 
 
		if(shieldLevel<0.5){
			repair=radar(RepairCenter);
			goto(repair.position);
			while(shieldLevel<1){
				wait(1);
			}
		}
 
		if(energyCell.energyLevel<0.25){
 
 
			power=radar(PowerStation);
			goto(power.position);
			while(energyCell.energyLevel<1){
				wait(1);
			}
			while(altitude<30){
				jet(1);
			}
		}
		while(altitude<20){
			jet(1);
		}
		//move 20 metres ?before? ant
		ant=radar(AlienAnt);
		turn(direction(ant.position));
		move(distance(position,ant.position)-20);
 
		//descent //5 metres above ant
		if(altitude>ant.altitude){
			while(altitude>ant.altitude){
				jet(-1);
			}
		}
		if(altitude<ant.altitude){
			while(altitude<ant.altitude){
				jet(1);
			}
		}
 
 
		turn(direction(ant.position));
		//aim!
		angle=(altitude*altitude)+(distance2d(position,ant.position)*distance2d(position,ant.position));
		angle=sqrt(angle);
		sin1=distance2d(position,ant.position)/angle;
		angle=acos(sin1);
		ant=radar(AlienAnt);
		turn(direction(ant.position));
		aim(angle);
		fire(0.5);
 
 
	}
 
	ship=radar(SpaceShip);
	goto(ship.position);
}

Список item`ов

Это не совсем программа. Это — список каждой (!) вещи в colobot, включая такие параметры, как высота и радиус. Включает хорошо написанную документацию, но на английском. Также приведены полезные функции, которые можно использовать при программировании.

num - [Tallest Point][Radi-Clearance] Name 
ie.
### - [Heigh][Radi-] Name
502 - [02.00][02.25] Alien Ant
 
 
If you use the tallest point and radi-clearance numbers i suggest 
that you add a few meters to them, these are the absolute 
minimum(of the maximum) clearances to the next 1/4 of a 
meter. I used a Winged Flyer to get these measurements so if your
using a shilder(or other large bot) you may have to add an 
additional 1 or 2 meters. Also if the object is larger in the 
air than on the ground, the  air measurement is taken at the 
widest part.
 
How do you use this information, just like you would use the name
of an object i.e.
 
Radar(5,0,360,0,800); 
// is the same as:
Radar(BotFactory,0,360,0,800);
// this means you now have a list of EVRYTHING detectable by the Radar
// And all the clearance stats you need to avoid them :P
 
 
 
0   - [--.--][--.--] <-- This is your new best friend!
 
Using 0 in a radar command will return the closest(or farthest depending 
what you have your radar command set for) ITEM OF ANY CATEGORY!
 
The following example isn’t very practical(and my not even work), it's 
just a little something to get your mind going.
 
You could use this and simply check for lets say any Alien like this:
/---------------------------------------------------------------\
|object Item;							|
|Item = radar(0,0,360,0,45);					|
|//501 to 505 is Aliens						|
|if((abs(Item.category)>=501)&&(abs(Item.category)<=505))	|
|{								|
|	//Aim the cannon					|
|	fire(0.25);	//Kill it				|
|}								|
\---------------------------------------------------------------/
Now I don’t know how practical of an implementation this is but
you get the idea of some uses, i would say that the use of this
"0" would be better suited for avoiding objects rather than trying to 
kill something, because if a bush or tree is closer than the Ant
its going to detect the bush or tree instead. Now I’m sure with 
some thought you can come up with a way to avoid this problem
but hey i have to leave you something to think about :P
 
i use "abs(Item.category)" to return the numeric category value
if you just used "Item.category" it would return the name of the object
if it has one, and frankly the Name of the object may work, i 
believe that Colobot sees the name as a numeric value. I just haven’t 
bothered to test that yet.
 
============================ Full Listing ============================
### - [Heigh][Radi-] Name; Levels found on and/or more definitions.
======================================================================
0   - [--.--][--.--] Wild Card, it is anything and everything!
 
2   - [19.50][32.25] Gantry Crane
3   - [22.50][20.00] Space Ship; Top Width of 8.25 
4   - [08.00][03.00] Derrick
5   - [06.50][06.00] Bot Factory
6   - [03.50][06.00] Power Station
7   - [04.00][05.00] Ore Converter
8   - [05.00][05.25] Repair Center
9   - [07.75][02.75] Defense Tower
10  - [00.00][00.00] Alien Nest; Organic Material/hatchery?, however it is probably holding Orga mater
11  - [05.75][03.75] Research Center
12  - [04.75][02.75] Radar Station
13  - [05.25][04.00] Power Plant; Power Cell Factory
14  - [04.25][05.25] Auto Lab
15  - [10.25][07.00] Nuclear Power Station
16  - [00.00][00.00] Start Area; platform
17  - [00.00][00.00] Goal Area;  platform
18  - [04.75][02.75] Information exchange post
19  - [17.25][06.50] Power Captor
20  - [25.25][07.75] Target "the target stand" (+)==<  looking thing; 03.25 at bace
21  - [00.00][00.00] Target2 "the actual Brass + Target"
22  - [03.75][04.50] Vault
23  - [06.25][18.75] Huston Mission Control
 
31  - [01.00][01.50] Titanium Ore
32  - [01.00][01.50] Uranium Ore
33  - [01.00][01.50] Titanium
34  - [01.00][01.50] Power Cell
35  - [01.00][01.50] Nuclear Power Cell
36  - [01.00][01.50] Orga Mater
37  - [01.00][01.50] Black Box
38  - [01.00][01.50] TNT Brick
 
50  - [00.00][00.00] green cross   -> energy deposit.
51  - [00.00][00.00] red cross     -> titanium ore.
52  - [00.00][00.00] yellow circle -> uranium ore.
 
### - [Heigh][Radi-] Name
 
60  - [01.25][02.00] Mine
61  - [01.00][01.75] Firework
63  - [01.00][02.00] Rocket Back Pack
 
70  - [01.25][01.75] Plant; Earth, Tropica, Centaury
71  - [01.25][01.75] Plant; Earth, Tropica, Centaury
72  - [01.25][01.75] Plant; Earth, Tropica, Centaury
73  - [01.25][01.75] Plant; Earth, Tropica, Centaury
74  - [01.25][01.75] Plant; Earth, Tropica, Centaury
75  - [00.00][00.00] Small Plant; Tropica
76  - [00.00][00.00] Small Plant; Tropica
77  - [00.00][00.00] Small Plant; Tropica
80  - [05.25][02.75] Large Plant; Tropica
81  - [04.75][02.50] Large Plant; Tropica
82  - [05.25][02.50] Large Plant; Tropica
83  - [05.25][03.00] Large Plant; Tropica
84  - [04.25][02.50] Large Plant; Tropica
85  - [01.25][01.75] Plant; Volcano
86  - [01.25][01.75] Plant; Volcano
87  - [01.25][01.75] Plant, Tall; Volcano
88  - [01.25][01.75] Plant; Volcano
89  - [01.25][01.75] Plant; Volcano
90  - [07.75][01.75] Tree; Earth
91  - [10.00][02.50] Tree; Earth
92  - [09.50][02.75] Tree; Earth
93  - [08.25][03.75] Tree; Earth
 
### - [Heigh][Radi-] Name
 
100 - [02.25][02.50] Practice Bot
 
110 - [02.50][02.50] Wheeled Grabber
111 - [02.50][02.50] Tracked Grabber
112 - [02.50][02.50] Winged Grabber
113 - [02.50][02.50] Legged Grabber
 
120 - [02.50][02.50] Wheeled Shooter
121 - [02.50][02.50] Tracked Shooter
122 - [02.50][02.50] Winged Shooter
123 - [02.50][02.50] Legged Shooter
 
130 - [02.50][02.50] Wheeled Orga Shooter
131 - [02.50][02.50] Tracked Orga Shooter
132 - [02.50][02.50] Winged Orga Shooter
133 - [02.50][02.50] Legged Orga Shooter
 
140 - [02.50][02.50] Wheeled Sniffer
141 - [02.50][02.50] Tracked Sniffer
142 - [02.50][02.50] Winged Sniffer
143 - [02.50][02.50] Legged Sniffer
 
200 - [03.00][03.00] Thumper
201 - [03.25][03.00] Phazer Shooter35
202 - [03.50][03.00] Recycler
203 - [04.50][03.00] Shielder; Height 3.00 when not active
210 - [02.50][02.50] Subber
211 - [02.25][02.50] Target Bot
250 - [00.00][00.00] Way Point
 
### - [Heigh][Radi-] Name
 
260 - [00.00][00.00] Blue Flag
261 - [00.00][00.00] Red Flag
262 - [00.00][00.00] Green Flag
263 - [00.00][00.00] Yellow Flag
264 - [00.00][00.00] Purple Flag
270 - [01.00][01.50] KeyA - Blue
271 - [01.00][01.50] KeyB - Red
272 - [01.00][01.50] KeyC - Green
273 - [01.00][01.50] KeyD - Yellow
 
300 - [02.00][01.75] Me
302 - [02.00][01.75] Tech (looks a lot like "Me" in some levels)
400 - [01.50][02.25] Barrier-Short; 1.5 width (about radi-of bot)
401 - [01.50][03.50] Barrier-Long; 1.5 width (about radi-of bot)
 
500 - [07.25][06.25] Alien Queen
501 - [02.00][02.25] Alien Egg
502 - [02.00][02.25] Alien Ant
503 - [01.25][02.00] Alien Spider
504 - [02.25][02.25] Alien Wasp
505 - [00.00][00.00] Alien Worm
 
600 - [02.50][03.00] A Wreckage wild card! for Recyclables
/* All Wreckage's are all 600, the 60_ is the .category
600 - [01.75][02.00] Wreckage; Whelled Grabber, Recyclable
601 - [01.50][02.00] Wreckage; Sunken Whelled Grabber, Recyclable
602 - [02.00][03.00] Wreckage; Tracked Shooter, Recyclable
603 - [02.00][03.00] Wreckage; Sunken Tracked Shooter, Recyclable
603 - [02.25][02.50] Wreckage; Sunken Recyceler, Recyclable
605 - [02.50][02.50] Wreckage; Recyceler, Recyclable
*/
606 - [04.00][06.00] Ruin; Bot Factory
607 - [01.50][02.25] Ruin; Ore Converter Door
608 - [01.25][02.00] Ruin; Support, C shaped hunk of mettel
609 - [01.50][02.25] Ruin; Brick like, Radar Station Base
610 - [01.25][05.00] Ruin; Ore Converter
611 - [08.75][13.25] Ruin; Space Ship Bace
612 - [09.50][08.50] Ruin; Space Ship Top
 
700 - [02.00][02.00] Crystal; Crystalium
701 - [02.50][02.50] Crystal; Crystalium
702 - [03.50][02.75] Crystal; Crystalium
703 - [06.00][04.50] Crystal; Crystalium
 
710 - [06.00][04.25] Green Mega Stalk; Stranve Plant, Small
711 - [07.50][03.50] Green Mega Stalk; Stranve Plant, Small
712 - [06.25][03.25] Green Mega Stalk; Stranve Plant, Small
713 - [08.75][05.25] Green Mega Stalk; Stranve Plant, Med
714 - [12.50][07.25] Green Mega Stalk; Stranve Plant, Large
715 - [12.50][07.25] Green Mega Stalk; Stranve Plant, Large with Green Shield like apperatice
715 - [--.--][22.00] #715's Green Shield (affects flyers ability to fly); you cannot fly over it
 
731 - [02.50][02.00] Mushroom; non corrosive
732 - [02.50][02.00] Mushroom; corrosive
 
900 - [04.00][05.02] Lunar Lander; Derelict of Apollo Mission
901 - [02.05][03.25] Lunar Roving Vehicle
902 - [00.00][00.00] American flag; Derelict of Apollo Mission
903 - [01.75][01.75] Inverted Satelite Dish; Derelict of Apollo Mission
904 - [02.75][02.00] Satelite Dish; Derelict of Apollo Mission
910 - [04.50][03.75] Home
 
### - [Heigh][Radi-] Name
 
-If you have any additions to this list please let me know at 
	RossK_WC2@hotmail.com
	Aim: Ens1747
	ICQ: 1747522
 
====================================================
And incase if your wondering how i extracted this data, here you go:
-----------------------------------------------------------------------------------
//Outputs all objects on the map to a file
//Note: Wrecks are all 600 no mater what .category
extern void object::FindNewItems() // This prossess takes some time
{
	file filSearch();
	object Named;
 
	//File is output to "...\Colobot\files\Search.txt"
	filSearch.open("Search.txt", "w");
	for(int I=1; I<=1000; I++)
	{
		Named = radar(I);
		if(Named!=null)
		{
			filSearch.writeln("" + I + " - " + Named.category);
		}
	}
 
	filSearch.close();
}
-----------------------------------------------------------------------------------
// just pull your bot up to an object and run this app, search for the largest 
// result by circling the Object and probing from difrent directions
 
extern void object::ObjectLookUp()
{
	object Named;
 
	Named = radar(0,0,90,0,10);	//useing radar(0,..) for wildcard, it'll detect anything
	if(Named != null)
	{
		message("Dist From (" + Named.category + ", " + abs(Named.category) + "): " + (distance2d(position, Named.position)));
	}
 
}
-----------------------------------------------------------------------------------
extern void object::ObjectLookAllUp()
{
	object Named;
	float fltGole[];
	int j=0;
 
	for(int i=0;i<=1000;i++)
	{
		Named = radar(i,0,90,0,5);
		if(Named != null)
		{
			fltGole[j++] = i;
			message("Dist From (" + Named.category + ", " + abs(Named.category) + "): " + (distance2d(position, Named.position)));
		}
	}
	message("All that worked: " + fltGole);
}
-----------------------------------------------------------------------------------
//If you dont understand this i have nothing to say :P
//Fly above the object so you can just move freely
extern void object::HowHigh()	
{
	object Named;
 
	Named = radar(0,0,360,0,3);	//useing radar(0,..) for wildcard, it'll detect anything
	message("Elevation: " + (position.z-topo(Named.position)));
}
-----------------------------------------------------------------------------------
//Marks closest object of type ### with a waypoint to make it easy to find.
extern void object::MarkUnknows()
{
	object objWhat;
	objWhat=radar(###);	//Put In Desired Object Number
	produce(objWhat.position, 0, WayPoint, "");
}

Новый радар!

Улучшенная версия процедуры radar (). Позволяет находить все на карте. Не нужно строительство отдельного здания для этого.

extern void object::main()
{
	object item;
	int i=0;
	item = retobject(i);
	//item =newradar(PhazerShooter,0,360,0,1000,1);
	//goto(space(item.position));
 
	while(true)
	{
		//goto(space(item.position));
		message(item.category);
		wait(0.2);
		i++;
		item = retobject(i);
	};
 
}
 
 
 
public object object::newradar(int category, float angle, float focus, float min, float max,float way)
{
	ipf(1800);
	object currect=retobject(0);
	object itemx=null;
	int i=0;
	int needdistance;
	bool checkfornomtems = false; //1 to check for no possition items //else don't
	if (way == -1)
	{
		needdistance = min - 0.01;
	}
	else needdistance = max + 0.01;
 
	do
	{
		i++; 
		if(currect.category == category)
		{
			if((position.x != nan) or (checkfornomtems == true))
			{
				float dis = direction(currect.position) - angle;
				if (dis < 0)
				{
					dis = -dis; 
				}
				if (dis > 180)
				{
					dis = 360 - dis;
				}
				if((distance(this.position,currect.position) >= min) && (distance(this.position,currect.position) <= max) && ( (distance(this.position,currect.position) * way) < (needdistance * way))  && (dis <= focus /2) )
				{
 
					itemx=currect;
					needdistance = distance(this.position,currect.position);
 
				}
			}
		}
		currect=retobject(i);
 
	}
	while(currect != null);
	ipf(200);
	return itemx;
}

Автоперезарядка башен

Для роботов WeeledGrabber (или TrackedGrabber). Отличная программа, решающая проблему перезарядки башен. Роботы будут стоять и сканировать уровень заряда всех башен. Как только уровень падает до 1/3 бот приедит к башне, перезарядит батарейку, а пустую отвезет на станцию перезарядки. Программа протестирована на 3 башнях. ;-)

extern void object::advChargeTowers()
{
	object tower, battery;
	object power;
	int a;
	float dist;
	errmode(0);
	if (load!=null) {
		drop();
 
	}
	dist=0;
	while (true) {
		if (energyCell.energyLevel<0.3) {
			power=radar(PowerStation);
			a=goto(power.position);
			if (a!=0) {
				message("please free way to the Power Station!");
				return;
			}
			while (energyCell.energyLevel!=1) {
				wait(1);
			}
		}
 
		tower=radar(DefenseTower,0,360,dist);
		if (tower==null) {
			dist=0;
			tower=radar(DefenseTower,0,360,dist);
		}
 
		if (tower.energyCell.energyLevel<0.3) {
			battery=radar(PowerCell,0,360);
			if (battery==null) {
				message("No batteries :-(",DisplayWarning);
				break;
			}
			goto(battery.position);
			grab();
			if (load.energyLevel!=1) {
				power=radar(PowerStation);
				a=goto(power.position);
				if (a!=0) {
					message("please free way to the Power Station!");
					return;
				}
				while (load.energyLevel!=1) {
					wait(1);
				}
			}
			goto(tower.position);
			drop(Behind);
			grab();
			turn(90);
			drop();
			turn(-90);
			grab(Behind);
			drop();
			//SwitchCell1();
			//break;
			turn(90);
			grab();
			power=radar(PowerStation);
			a=goto(power.position);
			if (a!=0) {
				message("please free way to the Power Station!");
				return;
			}
			while (load.energyLevel!=1) {
				wait(1);
			}
			goto(space(position,5,25));
			drop();
 
 
		} else {
			dist=distance(tower.position,position)+1;
 
		}
	}
 
}

Радароупроститель!

Класс, упрощающий работу с радаром. Теперь нет необходимости в запоминании множества кодов, а можно использовать красивые константы.

Пример использования:

   object item;
   otherCategories otherCats();  // Создаем экземпляр класса.
 
   item = radar(otherCats.Mushroom1); // Ищем ближайший объект (Mushroom)
public class otherCategories
{
	static int Firework = 61;
	static int Bag = 63;
	static int Greenery0 = 70;
	static int Greenery1 = 71;
	static int Greenery2 = 72;
	static int Greenery3 = 73;
	static int Greenery4 = 74;
	static int Greenery5 = 75;
	static int Greenery6 = 76;
	static int Greenery7 = 77;
	static int Greenery10 = 80;
	static int Greenery11 = 81;
	static int Greenery12 = 82;
	static int Greenery13 = 83;
	static int Greenery14 = 84;
	static int Greenery15 = 85;
	static int Greenery16 = 86;
	static int Greenery17 = 87;
	static int Greenery18 = 88;
	static int Greenery19 = 89;
	static int Tree0 = 90;
	static int Tree1 = 91;
	static int Tree2 = 92;
	static int Tree3 = 93;
	static int RuinBotFactory = 606;
	static int RuinDoor = 607;
	static int RuinSupport = 608;
	static int RuinRadar = 609;
	static int RuinConvert = 610;
	static int RuinBaseCamp = 611;
	static int RuinHeadCamp = 612;
	static int Quartz0 = 700;
	static int Quartz1 = 701;
	static int Quartz2 = 702;
	static int Quartz3 = 703;
	static int Mushroom1 = 731;
	static int Mushroom2 = 732;
	static int MegaStalk0 = 710;
	static int MegaStalk1 = 711;
	static int MegaStalk2 = 712;
	static int MegaStalk3 = 713;
	static int MegaStalk4 = 714;
	static int MegaStalk5 = 715;
	static int ApolloLEM = 900;
	static int ApolloJeep = 901;
	static int ApolloFlag = 902;
	static int ApolloModule = 903;
	static int ApolloAntenna = 904;
	static int Home = 910;
}

Робот-гувернантка

Для робота Winged (желательно). Робот занимается тем, что мониторит других ботов, и заменяет им батарейки, если у них заряд упал ниже определенной величины(настраивается в константах). Разряженные батарейки автоматически доставляет в центр перезарядки.

// (c) Minhiriath Condravox 2002
// Harvests a number of categories of objects and stores them at 
// predetermined storage sites.
// Automatically restores energy if drops below fENERGYLOW.
// Automatically repairs shields if drops below fSHIELDLOW.
extern void object::Harvest()
{
	float fSHIELDLOW=0.50, fENERGYLOW=0.25;
	int iDROPTURN = 4, iMAXHARVESTPRG = 4;
 
	int iHarvestPRG[iMAXHARVESTPRG][3], i=0;
	iHarvestPRG[i][0] = Titanium;
	iHarvestPRG[i][1] = SpaceShip;
	iHarvestPRG[i++][2] = 15;
	iHarvestPRG[i][0] = PowerCell;
	iHarvestPRG[i][1] = PowerStation;
	iHarvestPRG[i++][2] = 5;
	iHarvestPRG[i][0] = NuclearCell;
	iHarvestPRG[i][1] = PowerStation;
	iHarvestPRG[i++][2] = 5;
	iHarvestPRG[i][0] = TitaniumOre;
	iHarvestPRG[i][1] = Converter;
	iHarvestPRG[i++][2] = 5;
	int iHarvestPRGNr = 1;
 
	object oHarvestItem;
	int iErrCode, iCount, iNrHarvests = 0;
	boolean bPaused = false;
 
	while (true)
	{
		// Check energy and shields
		if ( CheckAndRepowerEnergy(fENERGYLOW) > 0) { break; }
		if ( CheckAndRepowerShields(fSHIELDLOW) > 0) { break; }
 
		// Find closest harvest item at at least range x from store site and get it
		oHarvestItem = FindHarvestObject(iHarvestPRG[iHarvestPRGNr][0], iHarvestPRG[iHarvestPRGNr][1], iHarvestPRG[iHarvestPRGNr][2]);
 
		if ( oHarvestItem!=null )
		{
			// Go to harvest item
			errmode(0);
			if ( goto(oHarvestItem.position, 10)<1 )
			{
				// Grab 
				if (grab(InFront)==0) { iNrHarvests++; }
				else { message("Harvester bot couldn't get object!", DisplayError); }
				errmode(1);
 
				// Recheck if there is a object held
				if (load != null)
				{
					if ( CheckAndRepowerEnergy(fENERGYLOW) > 0) { break; }
					if ( CheckAndRepowerShields(fSHIELDLOW) > 0) { break; }
 
					// find store site and return to it with object
					if ( FindAndMoveToObject(iHarvestPRG[iHarvestPRGNr][1], 0, iHarvestPRG[iHarvestPRGNr][2])>0 )
					{
						message("Harvester bot unable to reach store site!", DisplayError);
						break;
					}
 
					// Wait for power or nuclear cell to reload
					if ((iHarvestPRG[iHarvestPRGNr][1]==PowerStation) && ((load.category==PowerCell) || (load.category==NuclearCell)))
					    { while (load.energyLevel < 1.0); }
 
					// Try to drop object or rotate until empty spot found
					DropItem();
 
					// Take distance while converting TitaniumOre and get Titanium out
					if ( (iHarvestPRG[iHarvestPRGNr][0]==TitaniumOre) && (iHarvestPRG[iHarvestPRGNr][1]==Converter) )
					{
						move(-3); wait(15); 
						move(3);  grab();  
						turn(180);  move(6);
						DropItem();
					}
				}
			}
			else
			{
				message(oHarvestItem.position+" from "+position+"!", DisplayError);
				break;
			}
			errmode(1);
		}
		else
		{
			// Display amount of type harvested.
			if (iNrHarvests > 0)
			{
				message("Harvested total of "+iNrHarvests+" "+iHarvestPRG[iHarvestPRGNr][0]+".");
				wait(2);
			}
 
			// Start harvesting next type
			iHarvestPRGNr++;
			if (iHarvestPRGNr >= iMAXHARVESTPRG)
			{
				iHarvestPRGNr = 0;
			}
			message("Switched to harvesting "+iHarvestPRG[iHarvestPRGNr][0]+".");
			iNrHarvests = 0;
		}
	}
	message("Harvester bot stopped harvesting!", DisplayError);
}
 
// Find nearest object of category iDestCat and move towards object if found.
// Doesn't move if destination is less than iMinRange away.
// Returns error codes : 
// 0    object found and reached
// 1    object found but not reached
// 2    object not found
int object::FindAndMoveToObject(int iDestCat, int iMinRange, int iMinDist)
{
	int iErrCode = -1;
	object oDest;
 
	errmode(0);
	if ( (oDest = radar(iDestCat, 0, 360, iMinRange)) != null)
	{
		if ( distance2d(position, oDest.position)>iMinDist )
		{
			if ( goto(oDest.position, 10) == 0) { iErrCode = 0; }
			else                                { iErrCode = 1; }
		}
		else { iErrCode = 0; }
	}
	else { iErrCode = 2; }
	errmode(1);
 
	return(iErrCode);
}
 
// Checks bot energy cell power level and repowers at nearest PowerStation if 
// dropped below fEnergyLow.
// Returns error codes:
// -1    energy above fEnergyLow
//  0    energy restored successfully
//  1    energy needs restoring but couldn't reach PowerStation
//  2    energy needs restoring but no PowerStation found
int object::CheckAndRepowerEnergy(float fEnergyLow)
{
	object oPowerStation;
	int iErrCode=-1;
 
	// Automatically repower energy if low
	if (energyCell.energyLevel < fEnergyLow)
	{
		message("Harvester bot recharging.");
 
		iErrCode = FindAndMoveToObject(PowerStation, 0, 0);
		switch (iErrCode)
		{
			case 0 :
			    while (energyCell.energyLevel < 1.0);
			    break;
			case 1 :
			    message("Harvester bot en route to PowerStation - can't get there!", DisplayWarning);
			    FindAndMoveToObject(SpaceShip, 0, 5);
			    break;
			case 2 :
			    message("Harvester bot recharging - can't find PowerStation!", DisplayWarning);
			    FindAndMoveToObject(SpaceShip, 0, 5);
			    break;
		}
	}
 
	return (iErrCode);
}
 
// Checks bot shields and repowers at nearest RepairCenter if dropped below fShieldLow.
int object::CheckAndRepowerShields(float fShieldLow)
{
	object oRepairCenter;
	int iErrCode=-1;
 
	// Auto repair if shield low
	if (shieldLevel < fShieldLow)
	{
		message("Harvester bot repairing!", DisplayWarning);
 
		iErrCode = FindAndMoveToObject(RepairCenter, 0, 0);
		switch (iErrCode)
		{
			case 0 :
			    while (shieldLevel < 1.0);
			    break;
			case 1 :
			    message("Harvester bot en route to RepairCenter - can't get there!", DisplayWarning);
			    FindAndMoveToObject(SpaceShip, 0, 5);
			    break;
			case 2 :
			    message("Harvester bot recharging - can't find RepairCenter!", DisplayWarning);
			    FindAndMoveToObject(SpaceShip, 0, 5);
			    break;
		}
	}
 
	return (iErrCode);
}
 
// Find nearest harvestable iFindCat object at least fStoreSize away from iStoreSiteCat
object object::FindHarvestObject(int iFindCat, int iStoreSiteCat, float fStoreSize)
{
	object oStoreSite=radar(iStoreSiteCat), oFind;
	int iMinDist = 0;
 
	if (oStoreSite!=null)
	{
		do
		{
			oFind = radar(iFindCat, 0, 360, iMinDist);
			if (oFind!=null)
			{
				if ( distance2d(oStoreSite.position, oFind.position)<fStoreSize )
				{
					oFind=null;
					iMinDist++;
				}
			}
			else { break; }
		} while ( (oFind==null) && (iMinDist < 1000) );
	}
	else
	{
		message("Can't store at "+iStoreSiteCat+" - not present.");
		oFind=null;
	}
 
	return (oFind);
}
 
// Try to drop object or rotate until empty spot found
void object::DropItem()
{
	int iDROPTURN = 1;
	int iCount = 0, iErrCode = -1;
 
	errmode(0);
	while ( (drop(InFront) > 0) & (iCount <360) ) 
	{ 
		turn(iDROPTURN); 
		iCount += iDROPTURN;
		if (iCount >= 360)
		{
			message("Harvester bot unable to drop object!", DisplayError);
			iCount = 0;
		}
	}
	errmode(1);
}

Авто-создание роботов

Продвинутая программа для роботов-грабберов для создания других ботов. Она находит Титаниум, перемещает его на станцию создания роботов, ждет 25 секунд, берет заряженную батарейку, помещает его в бота и отьезжает, чтобы новосозданный робот мог оттуда выехать. Также, если необходимо, она подождет, пока батарейка зарядится на станции подзарядки.

extern void object::BotCreate()
{
 
	object metal;
	object factory;
	object power;
	object recharge;
	metal=radar(Titanium);
	factory=radar(BotFactory);
	power=radar(PowerCell);
	recharge=radar(PowerStation);
	goto(metal.position);
	grab();
	goto(factory.position);
	move(1);
	drop(InFront);
	move(-3);
	wait(25);
	goto(power.position);
	grab();
	if(power.energyLevel!=1){
		if(PowerStation==1){
			goto(recharge.position);
			while(power.energyLevel!=1){
				wait(0.1);
			}
		}
		else{
			turn(-90);
			move(15);
			drop();
			turn(180);
			move(15);
		}
	}
	goto(factory.position);
	drop();
	move(-2);
	turn(90);
	move(10);
 
}

Автоогонь

Интересная программа для стреляющих роботов. Позволяет Вам сконцентрироваться на управлении, когда как огонь по вражеским целям будет вести программа.

// Redesinged script copied from AlienKiller by Yenz
// This code almost entirely copied from the AlienKiller script
// made by Yenz. I wanted to make a simple cyborg script where
// a bot is manually piloted, but has precision aiming. Just run
// this script instead of hitting the fire button and the bot
// will aim and fire once at the closest alien in front of it.
// 
// Now rewritten to include both pitch and roll correction
// Reports warnings for temperature, shield and energy levels
// in percentages.
 
 
extern void object::RoboAim2()
{
	object alien;
	float angle;
	int alienList[], nr;
 
	nr = 0;
 
	alienList[nr++] = AlienWasp;
	alienList[nr++] = AlienAnt;
	alienList[nr++] = AlienSpider;
	alienList[nr++] = AlienWorm;
	alienList[nr++] = AlienEgg;
 
	alien = radar(alienList,0,90,0,45);
	if(alien != null)        //if there still is a alien left
	{
		if(distance(position, alien.position) < 45)
		{
			turn(direction(alien.position));    //coarse turn adjustment;
 
			angle = atan(((topo(alien.position)+alien.altitude)-(topo(position)+altitude))/distance2d(position, alien.position));        //determine absolute aiming angle
 
			// calulate and turn to adjust for roll angle
			if(roll < 0) turn((angle-pitch)*cos(roll)*cos(90-roll));
			else turn(-((angle-pitch)*cos(roll)*cos(90-roll)));
 
			aim(angle-pitch);    //aim at the target
 
			fire(0.1);    //kill it
		}
	}
	else message("No target");
 
	if(temperature > 0.8) message("Engines at " + (temperature * 100) + "%");
	if(shieldLevel < 0.2) message("Warning-Shield at " + (shieldLevel * 100) + "%");
	if(energyCell.energyLevel < 0.2) message("Warning-Energy at " + (energyCell.energyLevel * 100) + "%");
}

Младший научный работник

Программа для исследовательских центров. Робот автоматически меняет разряженные батарейки. Он ищет другие заряженные батарейки и помещает их в исследовательский центр.

extern void object::Research()
{
 
	object power;
	object research;
	power=radar(PowerCell);
	research=radar(ResearchCenter);
	goto(power.position);
	if(power.energyLevel!=1){
		turn(-90);
		move(10);
	}
	grab();
	goto(research.position);
	drop();
 
}

Вася-ремонтник

Программа для бота Shielder, которая позволяет в автоматическом режиме ремонтировать поврежденные здания. Он также может ремонтировать и других поврежденных роботов

// This program was designed for the Shielder
// to repair stationary objects (i.e. buildings).
// If you want to include (damaged) bots, they 
// must remain still during the repair.
 
extern void object::RepairBase()
{
	bool includeBots = false;  // You decide.
 
	object allies[];
 
	allies = findAllies(includeBots);
 
	for(int i = 0; i < sizeof(allies); i++)
	{
		if(distance2d(position,allies[i].position) > 26)
		{
			turn(direction(allies[i].position)); 
 
			for(int d = 24; d >= 5; d--)
			{
				point dest = triangulate2d(allies[i].position,d);
 
				errmode(0);
				if( goto(dest) == 0 )
				    break;
				errmode(1);   
			}
 
			if(distance2d(position,allies[i].position) > 26)
			{
				message("Could not goto " + allies[i].category + ".", DisplayError);
				return;
			}   
		}
 
		while(allies[i].shieldLevel < 1)
		    shield(1,distance2d(position,allies[i].position));
		message(allies[i].category + " repaired.  (" + (i+1) + "/" + sizeof(allies) + ")", DisplayInfo);
 
		shield(0,0);
	}   
 
	message("All repaired.", DisplayInfo);
}
 
object[] object::findAllies(bool repairAll)
{
 
	int allyList[];
	int i = 0;
 
	allyList[i++] = Derrick;
	allyList[i++] = BotFactory;
	allyList[i++] = PowerStation;
	allyList[i++] = PowerCaptor;
	allyList[i++] = Converter;
	allyList[i++] = RepairCenter;
	allyList[i++] = DefenseTower;
	allyList[i++] = ResearchCenter;
	allyList[i++] = RadarStation;
	allyList[i++] = ExchangePost;
	allyList[i++] = PowerPlant;
	allyList[i++] = AutoLab;
	allyList[i++] = NuclearPlant;
 
	if(repairAll)
	{
		allyList[i++] = WingedGrabber;
		allyList[i++] = TrackedGrabber;
		allyList[i++] = WheeledGrabber;
		allyList[i++] = LeggedGrabber;
		allyList[i++] = WingedShooter;
		allyList[i++] = TrackedShooter;
		allyList[i++] = WheeledShooter;
		allyList[i++] = LeggedShooter;
		allyList[i++] = WingedOrgaShooter;
		allyList[i++] = TrackedOrgaShooter;
		allyList[i++] = WheeledOrgaShooter;
		allyList[i++] = LeggedOrgaShooter;
		allyList[i++] = WingedSniffer;
		allyList[i++] = TrackedSniffer;
		allyList[i++] = WheeledSniffer;
		allyList[i++] = LeggedSniffer;
		allyList[i++] = Thumper;
		allyList[i++] = PhazerShooter;
		allyList[i++] = Recycler;
		allyList[i++] = Shielder;
		allyList[i++] = Subber;
	}
 
 
	object allies[];
	object tempObject;
 
	i = 0;
	int j = 0;
	int k = 0;
 
	while( (tempObject = retobject(i++)) != null )
	{
		for(j = 0; j < sizeof(allyList); j++)
		{
			if(tempObject.category == allyList[j] and tempObject.shieldLevel < 1)
			{
				message(tempObject.category + " needs repair.");
				allies[k++] = tempObject;
				break;
			}    
		}
	}
 
	for(i = sizeof(allies)-1; i > 0; i--)
	{
		for(j = 0; j < i; j++)
		{
			if(distance2d(position,allies[j].position) > distance2d(position,allies[j+1].position))
			{
				tempObject  = allies[j];
				allies[j]   = allies[j+1];
				allies[j+1] = tempObject;
			}
		}
	}
 
	return allies;
}
 
 
point object::triangulate2d(point p,int dist)
{
	point dest = p;
	float angl = orientation+180;
 
	if(angl > 360)
	    angl -= 360;
 
	dest.x += cos(angl) * dist;
	dest.y += sin(angl) * dist;
 
	return dest;
}

Джеки Чан

Продвинутая программа для атаки. Применяет некоторые трюки, позволяя достичь превосходства в борьбе с другими роботами.

extern void object::Attack2()
{
	ipf(800);
 
	int cat[];                
	cat[0] = AlienAnt;    
	cat[1] = AlienWorm;  
	cat[2] = AlienWasp; 
	cat[3] = AlienSpider;
	cat[4] = AlienEgg;
 
	object target;
 
	float dir;
	float dis;
	float dif;
	float ang;
 
	boolean hot = false;
 
	while((target = radar(cat)) != null)
	{
		if(temperature > 0.8)
		    hot = true;
		if(temperature < 0.2)
		    hot = false;
 
		if(hot and topo(position) > 1)
		    jet(-1);
		else
		{
			dis = distance2d(position,target.position);  
			dif = target.position.z-position.z;
			ang = atan(dif/(dis-5)); 
 
			jet(1-ang/-15);   
		}
 
		dis = distance2d(position,target.position); 
		dif = target.position.z-position.z;
		ang = atan(dif/dis); 
 
		if(altitude == 0)
		    ang -= pitch;
 
		dir = direction(target.position);
 
		if(dis < 40 and abs(ang) < 20 and abs(dir) < 112.5)
		    turn(dir);
		else
		    motor(1-dir/45,1+dir/45);
 
		dis = distance2d(position,target.position);  
		dif = target.position.z-position.z;
		ang = atan(dif/dis)-pitch; 
 
		aim(ang);
 
		dir = direction(target.position);
 
		if(dis < 40  and abs(ang) < 20 and abs(dir) < 5)
		    fire(0.1); 
 
		if(dis > 40)
		    maint();  
	}
}
 
void object::maint()
{
	if(energyCell.energyLevel < 0.35)
	{
		object pwr = radar(PowerStation);
 
		if(pwr != null)
		{
			goto(pwr.position,5);
 
			while(energyCell.energyLevel < 1)
			    wait(1);
		}
	}
 
	if(shieldLevel < 0.45)
	{
		object rep = radar(RepairCenter);
 
		if(rep != null)
		{
			goto(rep.position,5);
 
			while(shieldLevel < 1)
			    wait(1);
		}
	}
}

Брюс Ли

Еще одна программа для атаки. Эффективно против всех типов врагов (кроме AlienQueen, конечно ;-) ). Автоматически себе перезаряжает, если необходимо.

// Air Superiority Fighter
// Version 1.00
// by Black Eagle
// blackeagle@gamebox.net
// For WingedShooter and WingedOrgaShooter
// Features :
// - Effective against all types of enemies (except AlienQueen, of course! :) )
// - Low energy usage for firing
// - Recharges and repairs itself when needed
// - Avoids water while cooling down (if it can)
//
// Notes :
// * Don't use first person camera while using this program
// because of the pitch bug. It will drop the accuracy
// severely.
//
// * This bot can take the following commands via an
// information exchange post :
//   - wsguardrange : change the guard range
//   - wsfirerate   : change the firing rate
//   - wsfiredelay  : change the firing delay
//   - wsguardpoint : change the guard point with the 
//                    wsguardpointx as the x value and 
//                    wsguardpointy as the y value
//                  ( This bot DOESN'T check if the guard
//                    point is covered with water or not,
//                    so be careful when using this command )
 
extern void object::AirSuperiority()
{
	object item;
	int err1;
	int err2;
	int temp1;
	int temp2;
	int tempdir;
	int tempdis;
	float curdir;
	float nexttopo;
	float turnmotor;
	float firerate;
	float enemydir;
	float enemylife;
	float fired;
	object enemy;
	object enemy1;
	point guardpoint;
	point togo;
	errmode(0);
	ipf(800);
	guardpoint = position;
	int list[], i;
	float maxsearch;
	float maxsearchorig;
	int firedelay;
	int firedelaytime;
 
 
	enemylife = 0;
 
	fired = 0.15;
	temp1 = 0;
	firedelay = 0;
	firedelaytime = 12;  // Firing delay before another fire
	firerate = 0.25;     // Firing Rate
	maxsearch = 300;     // Max. search area.
	maxsearchorig = maxsearch; 
 
	i = 0;
	list[i++] = AlienAnt;
	list[i++] = AlienWasp;
	list[i++] = AlienSpider;
	list[i++] = AlienEgg;
	list[i++] = AlienWorm;
 
 
	while(true){
 
		if (radar(PowerStation) == null) {
			message("No Power Station Found. Aborting...",DisplayError);
			break;
		}
		if (energyCell.energyLevel < (0.4+fired) | shieldLevel < 0.4)
		{                        // if so:
			item = radar(PowerStation);
			if ( item != null & distance2d(item.position,position) <= 50) {
				if ( item != null )   // station found ?
				{
					err1 = goto(item.position); // go there
					if (err1 != 0) {
						err2 = goto(space(item.position,8,120,4));
						if (err2 != 0) {
							while(err2 != 0){
								wait(1);
								err2 = goto(space(item.position,8,120,4));
							}
						}
						message("Power Station occupied, waiting...",DisplayInfo);
						while (err1 != 0) {
							wait(1);
							err1 = goto(item.position);
						}
					}
					while ( energyCell.energyLevel < 1 )
					{ // until recharged:
						wait(1);      // wait
						fired = 0.15;
					}
				}
				if (shieldLevel < 1){
					item = radar(RepairCenter);
					if ( item != null )   // repairstation found ?
					{
						err1 = goto(item.position); // go there
						if (err1 != 0) {
							err2 = goto(space(item.position,8,120,4));
							if (err2 != 0) {
								while(err2 != 0){
									wait(1);
									err2 = goto(space(item.position,8,120,4));
								}
							}
							message("Repair Center occupied, waiting...",DisplayInfo);
							while (err1 != 0) {
								wait(1);
								err1 = goto(item.position);
							}
						}
						while ( shieldLevel < 1 )
						{ // until recharged:
							wait(1);      // wait
						}
					}
				}
			}
			else {
				enemy = radar(PowerStation);
			}
		}
		if (energyCell.energyLevel >= (0.4+fired) & shieldLevel >= 0.4) enemy = radar(list,0,360,0,maxsearch,1);
 
		if (testinfo("wsguardrange",1000)) {
			maxsearch = receive("wsguardrange",1000);
			deleteinfo("wsguardrange",1000);
		}
 
		if (testinfo("wsfirerate",1000)) {
			firerate = receive("wsfirerate",1000);
			deleteinfo("wsfirerate",1000);
		}
 
		if (testinfo("wsfiredelay",1000)) {
			firedelaytime = receive("wsfiredelay",1000);
			deleteinfo("wsfiredelaytime",1000);
		}
 
		if (testinfo("wsguardpoint",1000)) {
			guardpoint.x = receive("wsguardpointx",1000);
			guardpoint.y = receive("wsguardpointy",1000);
			deleteinfo("wsguardpoint",1000);
		}
 
		if (enemy != null & temperature < 0.75) {
			togo.x = (2*cos(orientation))+position.x;
			togo.y = (2*sin(orientation))+position.y;
			togo.z = position.z;
			if(position.z - topo(position) < 2 | position.z - topo(togo) < 2 | position.z < 1) jet(1);
			else {
				if(position.z - topo(position) > 10) jet(-0.2);
				if(enemy.category != AlienWasp and enemy.category != PowerStation) {
					if(atan(((position.z-enemy.position.z)/distance2d(position,enemy.position))) > 20) jet(-0.8);
					if(atan(((position.z-enemy.position.z)/distance2d(position,enemy.position))) < 15) jet(0.8);
				}
				else {
					if( enemy.category != PowerStation ) {
						if(position.z < enemy.position.z) jet(0.4);
						if(position.z > enemy.position.z) jet(-0.4);
					}
				}
			}
			turnmotor = distance(position,enemy.position)/150;
			if(turnmotor < 0) turnmotor = 0;
			if(turnmotor > 1) turnmotor = 0.5;
			enemydir = direction(enemy.position);
			while(enemydir < -180 | enemydir > 180) {
				if(enemydir < -180) enemydir = enemydir + 360;
				if(enemydir > 180) enemydir = enemydir - 360;
			}
			if(enemy.lifeTime > enemylife & enemy.lifeTime < (enemylife + 5)) {
 
			}
			else firedelay = 0;
			enemylife = enemy.lifeTime;
			if(firedelay > 0) firedelay = firedelay - 1;
			if (distance(enemy.position,position) > 45) {
				if(enemydir > 0) motor(turnmotor,1);
				if(enemydir < 0) motor(1,turnmotor);
				if(enemydir == 0) motor(1,1);
 
			}
			else {
				if(enemydir > -60 & enemydir < 60) {
					if(enemydir > 0) motor(turnmotor,1);
					if(enemydir < 0) motor(1,turnmotor);
					if(enemydir == 0) motor(1,1);
				}
				else motor(1,1);
			}
			aim((atan((position.z+1.5-enemy.position.z)/(distance2d(enemy.position,position)))*-1)-pitch);
			if(direction(enemy.position) < 5 & direction(enemy.position) > -5 & distance(enemy.position,position) < 45 & firedelay < 1){
				fire(firerate);
				if(fired > 0) fired = fired - 0.02;
				firedelay = firedelaytime;
			}
		}
		if (enemy != null & temperature > 0.75) {
			temp1 = 0;
			enemy1 = radar(list,temp1,45,30,150,1);
			while(enemy1 != null) {
				temp1 = temp1 + 45;
				enemy1 = radar(list,temp1,45,30,150,1);
			}
			turn(temp1);
			togo.x = (4*cos(orientation))+position.x;
			togo.y = (4*sin(orientation))+position.y;
			togo.z = position.z;
			while(temperature > 0) {
				curdir = orientation;
				if (topo(position) > 0) {
					motor(1,1);
					jet(-0.1);
					togo.x = (8*cos(curdir))+position.x;
					togo.y = (8*sin(curdir))+position.y;
					togo.z = position.z;
					if (topo(togo) <= 0) {
						temp1 = 0;
						while (topo(togo) <= 0) {
							temp1 = temp1 + 15;
							enemy1 = radar(list,temp1,10,30,150,1);
							while(enemy1 != null) {
								temp1 = temp1 + 15;
								enemy1 = radar(list,temp1,10,30,150,1);
							}
							togo.x = (8*cos(curdir+temp1))+position.x;
							togo.y = (8*sin(curdir+temp1))+position.y;
							togo.z = position.z;
						}
						togo.x = (8*cos(curdir))+position.x;
						togo.y = (8*sin(curdir))+position.y;
						togo.z = position.z;
						temp2 = 0;
						while (topo(togo) <= 0) {
							temp2 = temp2 - 15;
							enemy1 = radar(list,temp2,10,30,150,1);
							while(enemy1 != null) {
								temp2 = temp2 - 15;
								enemy1 = radar(list,temp2,10,30,150,1);
							}
							togo.x = (8*cos(curdir+temp2))+position.x;
							togo.y = (8*sin(curdir+temp2))+position.y;
							togo.z = position.z;
						}
						if(-temp2 > temp1) tempdir = temp1;
						if(-temp2 <= temp1) tempdir = temp2;
						turn(tempdir);
					}
				}
				if (topo(position) <= 0) {
					motor(1,1);
					jet(-0.05);
					if(topo(togo) < 0) {
						temp1 = 0;
						tempdis = 10;
						while(topo(togo) < 0) {
							temp1 = temp1 + 45;
							togo.x = (tempdis*cos(curdir+temp1))+position.x;
							togo.y = (tempdis*sin(curdir+temp1))+position.y;
							togo.z = position.z;
							if(temp1 >= 360) {
								temp1 = 0;
								tempdis = tempdis + 15;
							}
						}
						turn(temp1);
					}
				}
			}
		}
		if (enemy == null & distance(position,guardpoint) > 3) {
			goto(guardpoint);
		}
	}
 
}

TowerService

Программа для обслуживания множества башен и ботов. Для более эффективного использования Вы можете построить здание ExchangePost.

extern void object::ServiceTower2()
{
	//resetExChgPst();
 
	while(true)
	{
		if(load == null)
		    getCell();
		else
		{
			if(load.energyLevel < 1)
			    maint();  
 
			loadTower();
		}
	}
}
void object::resetExChgPst()
{
	object towers[];
 
	towers = findAndSortTowers();
 
	for(int i = 0; i < sizeof(towers)-1; i++)
	    finishService(towers[i]);
}
 
object object::getTower()
{
	object towers[];
 
	towers = findAndSortTowers();
 
	for(int i = 0; i < sizeof(towers)-1; i++)
	{
		if(towers[i] != null and not currentlyBeingServiced(towers[i]))
		    return towers[i];
	}
 
	return null;
}
 
void object::getCell()
{
	object bestCell = findBestCell();
 
	if(bestCell == null)
	    getCellFromTower();
	else
	{
		myGoto(bestCell.position);
 
		errmode(0);
		grab();
		errmode(1);
	}
}
 
object object::findBestCell()
{
	object cell = radar(PowerCell);
	object bestCell = cell;
 
	float min = 0;
 
	while( (cell = radar(PowerCell,0,360,min)) != null )
	{ 
		if(cell.energyLevel == 1)
		    return cell;
 
		if(bestCell.energyLevel < cell.energyLevel)
		    bestCell = cell;
 
		min = distance2d(position,cell.position) + 0.5;
	}
 
	return bestCell;
} 
 
object[] object::findAndSortTowers()
{
	object towers[];
 
	int i = 0; 
	float min = 0;
 
	while((towers[i] = radar(DefenseTower,0,360,min)) != null)
	    min = distance2d(position,towers[i++].position) + 0.5;
 
	for(int j = i-1; j > 0; j--)
	{
		for(int k = 0; k < j; k++)
		{
			float energyLevel1 = -1;
			float energyLevel2 = -1;
 
			if(towers[k].energyCell != null)
			    energyLevel1 = towers[k].energyCell.energyLevel;
 
			if(towers[k+1].energyCell != null)
			    energyLevel2 = towers[k+1].energyCell.energyLevel;
 
			if(energyLevel1 > energyLevel2)
			{
				object temp  = towers[k];
				towers[k]    = towers[k+1];
				towers[k+1]  = temp;
			}
		}
	}
 
	return towers;
} 
 
void object::getCellFromTower()
{
	object tower = getTower();
 
	if(tower == null)
	    return;
 
	if(tower.energyCell != null)
	{
		int cat[];
		cat[0] = PowerStation;
		cat[1] = PowerCaptor;
 
		if(tower.energyCell.energyLevel < 0.5 and radar(cat) != null)
		{
			startService(tower);
			myGoto(tower.position);
 
			while(enemyIsNear() and tower.energyCell.energyLevel >= 0.125)
			    wait(1);   
 
			grab();
			finishService(tower);
		}  
	}
}
 
void object::loadTower()
{
	object tower = getTower();
 
	if(tower == null)
	    return;
 
	if(tower.energyCell != null)
	{
		if(tower.energyCell.energyLevel < load.energyLevel)
		{
			startService(tower);
			myGoto(tower.position);
 
			while(enemyIsNear() and tower.energyCell.energyLevel >= 0.125)
			    wait(1);   
 
			swapCell();
			finishService(tower);
		}
	}
	else
	{
		startService(tower);
 
		myGoto(tower.position);
		drop();
 
		finishService(tower);
	}
}
 
void object::startService(object o)
{
	if(radar(ExchangePost) == null)
	    return;
 
	send(o.position.x + "/" + o.position.y,1,1000); 
}
 
 
bool object::currentlyBeingServiced(object o)
{
	return testinfo(o.position.x + "/" + o.position.y,1000); 
}
 
void object::finishService(object o)
{
	deleteinfo(o.position.x + "/" + o.position.y,1000); 
}
 
void object::swapCell()
{
	drop(Behind);
 
	grab(); 
 
	turn(90);
	drop();
 
	turn(-90);
	grab(Behind);
 
	drop();
 
	turn(90);
	grab();
}
 
void object::maint()
{
	message("PowerCell needs recharge.  Searching for energy sources...");
 
	if(rechargePlanA() == false and rechargePlanB() == false)
	{
		message("Warning.  No energy sources found!");
		wait(5);
		return;
	}
 
	message("Recharge completed.  Resuming job duties...", DisplayInfo);
}
 
bool object::rechargePlanA()
{
	int cat[];
	cat[0] = PowerStation; 
	cat[1] = PowerCaptor;
 
	object pwrSource = radar(cat);  
 
	if(pwrSource == null)
	    return false;
 
	myGoto(triangulate2d(pwrSource));
	myGoto(pwrSource.position);
 
	message("Recharging at " + pwrSource.category + "...",DisplayInfo);
 
	while(load.energyLevel < 1)
	    wait(1);
 
	goto(space());
 
	return true;
}
 
bool object::rechargePlanB()
{
	object bestCell = findBestCell(); 
 
	if(bestCell == null)
	    return false;
 
	if(load.energyLevel < bestCell.energyLevel)
	{
		goto(bestCell.position);    
 
		message("Swapping with better PowerCell...",DisplayInfo);
 
		drop(Behind);
		grab();
 
		return true;
	}
 
	return false;
}
 
bool object::enemyIsNear()
{
	int cat[];                
 
	cat[0] = AlienAnt;    
	cat[1] = AlienWorm;  
	cat[2] = AlienWasp; 
	cat[3] = AlienSpider;
 
	object enemy = radar(cat,0,360,0,75);
 
	if(enemy == null)
	    return false;
 
	return true;
}
void object::myGoto(point p)
{
	errmode(0);
 
	while(goto(p) != 0)
	    wait(2);    
 
	errmode(1);
}
 
point object::triangulate2d(object o)
{
	point dest = o.position;
 
	dest.x += cos(o.orientation) * 10;
	dest.y += sin(o.orientation) * 10;
 
	return dest;
}

Сборщик урана

Программа для сбора UraniumOre (урановой руды). Поддерживает до двух одновременно работающих ботов, позволяя избегать пробок :-)

extern void object::CollectUranOre()
{
	while(true)
	{
		if(energyCell.energyLevel <= 0.4)
		    maint();
 
		if(load == null)
		    retrieveResource(UraniumOre);
		else
		{
			processResource(NuclearPlant);
			deliverResource(BotFactory);
		}
	}
}
 
void object::retrieveResource(int category)
{
	object resource;
 
	while( (resource = radar(category)) == null )
	{
		message("No UraniumOre found.  Standing by...");
		wait(10);    
	}
 
	myGoto(resource.position);
 
	errmode(0);
	grab();
	errmode(1);
}
 
void object::processResource(int category)
{
	object building;
 
	while( (building = radar(category)) == null )
	{
		message("No NuclearPlant found.  Standing by...");
		wait(10);    
	}
 
	myGoto(triangulate2d(building));
	myGoto(building.position);
 
	drop();
 
	move(-3);
	wait(35);
	move(1.5);
 
	grab();
}
 
void object::deliverResource(int category)
{
	object dest = radar(category);
 
	if(dest == null)
	    goto(space());
	else 
	{
		errmode(0);
		if(goto(space(dest.position)) != 0)
		    goto(space());
		errmode(1);
	}
 
	drop();
 
	message("NuclearCell delivered.",DisplayInfo);
}
 
void object::maint()
{
	message("Energy level low.  Searching for energy sources...");
 
	while(rechargePlanA() == false and rechargePlanB() == false)
	{
		message("Warning.  No energy sources found!");
		wait(25);
	}
 
	message("Recharge completed.  Resuming job duties...", DisplayInfo);
}
 
bool object::rechargePlanA()
{
	int cat[];
	cat[0] = PowerStation; 
	cat[1] = PowerCaptor;
 
	object pwrSource = radar(cat);  
 
	if(pwrSource != null)
	{
		myGoto(triangulate2d(pwrSource));
		myGoto(pwrSource.position);
 
		message("Recharging at " + pwrSource.category + "...",DisplayInfo);
 
		while(energyCell.energyLevel < 1)
		    wait(1);
 
		return true;
	}
 
	return false;
}
 
bool object::rechargePlanB()
{
	object cell;
	float min = 0;
 
	while( (cell = radar(PowerCell,0,360,min)) != null )
	{
		min = distance2d(position,cell.position) + 0.5;
 
		if(cell.energyLevel >= 0.5)
		{
			goto(cell.position);
 
			message("Swapping with better PowerCell...",DisplayInfo);
 
			grab();   
			drop(Behind);
 
			grab(EnergyCell);  
			drop();
 
			grab(Behind);
			drop(EnergyCell);
 
			return true;
		}
	}
 
	return false;
}
 
void object::myGoto(point p)
{
	errmode(0);
 
	while(goto(p) != 0)
	    wait(2);    
 
	errmode(1);
}
 
point object::triangulate2d(object o)
{
	point dest = o.position;
 
	dest.x += cos(o.orientation) * 15;
	dest.y += sin(o.orientation) * 15;
 
	return dest;
}

Сборщик титаниума

Программа для сбора TitaniumOre. Также поддерживает до двух одновременно работающих ботов, позволяя избегать пробок.

extern void object::CollectTitanOre()
{
	while(true)
	{
		if(energyCell.energyLevel <= 0.4)
		    maint();
 
		if(load == null)
		    retrieveResource(TitaniumOre);
		else
		{
			processResource(Converter);
			deliverResource(-1);
		}
	}
}
 
void object::retrieveResource(int category)
{
	object resource;
 
	while( (resource = radar(category)) == null )
	{
		message("No TitaniumOre found.  Standing by...");
		wait(10);    
	}
 
	myGoto(resource.position);
 
	errmode(0);
	grab();
	errmode(1);
}
 
void object::processResource(int category)
{
	object building;
 
	while( (building = radar(category)) == null )
	{
		message("No Converter found.  Standing by...");
		wait(10);    
	}
 
	myGoto(triangulate2d(building));
	myGoto(building.position);
 
	drop();
 
	move(-3);
	wait(15);
	move(1.5);
 
	grab();
}
 
void object::deliverResource(int category)
{
	object dest = radar(category);
 
	if(dest == null)
	    goto(space());
	else 
	{
		errmode(0);
		if(goto(space(dest.position)) != 0)
		    goto(space());
		errmode(1);
	}
 
	drop();
 
	message("TitaniumCube delivered.",DisplayInfo);
}
 
void object::maint()
{
	message("Energy level low.  Searching for energy sources...");
 
	while(rechargePlanA() == false and rechargePlanB() == false)
	{
		message("Warning.  No energy sources found!");
		wait(25);
	}
 
	message("Recharge completed.  Resuming job duties...", DisplayInfo);
}
 
bool object::rechargePlanA()
{
	int cat[];
	cat[0] = PowerStation; 
	cat[1] = PowerCaptor;
 
	object pwrSource = radar(cat);  
 
	if(pwrSource != null)
	{
		myGoto(triangulate2d(pwrSource));
		myGoto(pwrSource.position);
 
		message("Recharging at " + pwrSource.category + "...",DisplayInfo);
 
		while(energyCell.energyLevel < 1)
		    wait(1);
 
		return true;
	}
 
	return false;
}
 
bool object::rechargePlanB()
{
	object cell;
	float min = 0;
 
	while( (cell = radar(PowerCell,0,360,min)) != null )
	{
		min = distance2d(position,cell.position) + 0.5;
 
		if(cell.energyLevel >= 0.5)
		{
			goto(cell.position);    
 
			message("Swapping with better PowerCell...",DisplayInfo);
 
			grab();   
			drop(Behind);
 
			grab(EnergyCell);  
			drop();
 
			grab(Behind);
			drop(EnergyCell);
 
			return true;
		}
	}
 
	return false;
}
 
void object::myGoto(point p)
{
	errmode(0);
 
	while(goto(p) != 0)
	    wait(2);    
 
	errmode(1);
}
 
point object::triangulate2d(object o)
{
	point dest = o.position;
 
	dest.x += cos(o.orientation) * 10;
	dest.y += sin(o.orientation) * 10;
 
	return dest;
}

Титаниум-граббер

Еще одна программа для сборки/переработки титаниума. Роботы автоматически подзаряжаются при необходимости.

extern void object::MakeTitanium( )
{
	errmode ( 0 );
	for ( int i=0 ; i<10 ; i=i+1 )
	{
		object  obj, item; 
		point   dest,scrap, storage;
		int j=0, err=0, h=0;
		float dist, pl, xt,yt,x,y;
		do
		{
			obj = radar(TitaniumOre);
		}
		while ( obj == null );
		message("TitaniumOre found at X=" + obj.position.x +" Y="+obj.position.y,DisplayInfo);
		dist=distance(position,obj.position);
		if(category == LeggedGrabber) { pl = (0.05 + 2.1*(dist*0.0008)); }
		if(category == WheeledGrabber) { pl = (0.10 + 2.5*(dist*0.0016)); }
		if(category == TrackedGrabber) { pl = (0.10 + 2.5*(dist*0.0025)); }
		if(category == Subber) { pl = (0.20 + 2.5*(dist*0.0025));}
		if(energyCell.category == NuclearCell) { pl = pl * 0.1;}
		message("Estimated Safe power needed is :"+(pl*100)+"% Current Cell level is:"+ (energyCell.energyLevel*100)+"%",DisplayInfo);
		if(pl > 1) {
			message("The nearest Titanium ore is out of the safe power range of a full charge");
			return;
		}
		if(energyCell.energyLevel < pl and energyCell.category != NuclearCell and (radar(PowerStation)) != null) {
			j=5;
			do
			{
				item = radar(PowerStation,0,360,j-5,j);
				j+=5;
				if (item != null) { err = goto(item.position);
					if(err != 0){item = radar(WayPoint,0,1,0,1);}
				}
				if (j >= 600){
					j=5;
					message("PowerStation(s) are blocked!",DisplayWarning);
					wait(30);
				}
 
			}
			while (item == null);
			if (item != null){
				message("The Bot is recharging its power cells.",DisplayInfo);
				while ( energyCell.energyLevel < 1 )
				{
					wait(1);           
				}
 
			}
		}
		else {
			if (category != Subber) {
				if(energyCell.energyLevel < pl ) {
					message("The Bot is changing power cells.",DisplayInfo);
					j= 5;
					do{
						item = radar(PowerCell,0,360,j-5,j);
						if (item == null) {item = radar(NuclearCell,0,360,j-5,j);}
						j+=5;
						if (item != null) {if (item.energyLevel <= 0.8) {
								item = radar(WayPoint,0,1,0,1);}
						}
						if (j >= 400){
							j=5;
							message("Bot Cannot find any energy cells.",DisplayInfo);
							wait(30);
 
						}
					}
					while ( item == null );
 
					do{
						err = goto(item.position);
						if (err != 0) { 
							message("powercell get error.. trying again.",DisplayInfo);
							turn(120);
							move(15);
						}
					}
					while(err !=0 );
					grab(InFront);     // take the new cell in front
					drop(Behind);      // and drop it behind
 
					grab(EnergyCell);  // take the cell from the bot
					drop(InFront);     // and drop it in front
 
					grab(Behind);      // take the new cell
					drop(EnergyCell);  // and drop it on the bot
 
				}
				else{ if(energyCell.energyLevel < pl ) {
					item = radar(SpaceShip);
					goto(item.position);
					message("Subber needs a Cell change at SpaceShip.",DisplayError);}
				}
			}
		}
		do
		{
			obj = radar(TitaniumOre);
		}
		while ( obj == null );
		do{
			err = goto(obj.position);
			if (err != 0) {message("T.ore Get error, Trying again.",DisplayInfo);
				turn(120);
				move(15);
			}
		}
		while(err !=0 );
 
		grab();  // grab the titanium ore
 
		obj = radar(Converter);
		if ( obj == null )  return;
		do{
			err = goto(obj.position);
			if (err != 0) {message("T.ore delivery error, Trying again.",DisplayInfo);
				turn(120);
				move(15);
			}
		}
		while(err !=0 );
		drop(); 
		move(-2.5);  
		do
		{
			obj = radar(Titanium, 0, 360, 0, 5);
		}
		while ( obj == null );
		goto(obj.position);
		grab();
		if ( i > 2 ){
			i=0;
			h=h+1;
		}
		x=i*2+5;
		y=-(h)*2+10;
		scrap=position;
		xt = (x * cos(orientation)) + (y * sin(orientation));
		yt = (y * cos(orientation)) - (x * sin(orientation));
		//message("X="+xt+"Y="+yt);
		scrap.x = position.x + xt;
		scrap.y = position.y + yt;
		//message("X="+scrap.x+"Y="+scrap.y);
		storage = space(scrap,0,100,2);
		if (storage.x == nan) {
			message("bad.");
		}
		message("Titanium being stored tenitivly at: X="+storage.x+" Y="+storage.y,DisplayInfo);
		err = goto(storage);
		if (err != 0) {
			message("T storage errorin moving to space",DisplayInfo);
			goto(space(storage,4,100,2));drop();
		}
		err = drop(); 
 
		if (err != 0) {
			message("T storage error. finding open spot",DisplayInfo);
			goto(space(position,0,100,2));drop();
		}
 
		move(-2.5);
 
	}
}

Недокументированные возможности

Приведены описание хитростей и готовые процедуры, которые можно использовать в игре.

...On my latest mission to a previously explored planet i ran across a race of abandoned robots, in 
   return of being left alone they gave me information about undocumented instructions and mechanism of
   the bots.
 
---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------
 
   Syntax :
 
-- float/int abs(float/int variable)  Returns absolute value of variable. e.a. always positive.
 
   example x = -1;
           abs(x);
           message(x);
 
---------------------------------------------------------------------------------------------------------
 
   Syntax :
 
-- boolean   Same as bool.
 
   If you want a function to return a boolean only the latter is recognized.
 
   example :: boolean object::energyLow()
             {
                if (energyCell.energyLevel < 0.1)
                {
                   return true;
                }
                return false;
             }
 
---------------------------------------------------------------------------------------------------------
 
   Syntax :
 
-- boolean && boolean   Returns true if both bools are true, else false.
-- boolean || boolean   Returns false when both bools are false, else true. e.a. inversion of &&.
-- !boolean   Returns the inversion of the bool. e.a. !true = false, !false = true.
 
   example :: object target;
              target = radar(PowerStation);
              if (energyCell.energyLevel < 0.1 && energyCell.category == PowerCell)
              {
                 goto(target.position);
              }
 
---------------------------------------------------------------------------------------------------------
 
   Syntax :
 
-- variable++   Increases variable by one after instruction.
-- variable--   Decreases variable by one after instruction.
 
   Use x++ instead of x = x + 1 and x-- instead of x = x - 1. This works on both int and float variables.
 
   note -- If the variable is read in the same instruction, the variable will return the old value. 
           example: int x = 0; message(x++); This will prompt 0 instead of 1.
 
   example :: for (int x = 0, y = 10; x < y; x++)
 
---------------------------------------------------------------------------------------------------------
 
   Syntax :
 
-- ipf(int)  Changes linespeed to int;
 
   You can increase the speed the bot interprets your code with this instruction, ideal for ultra
   intensive routines. :)
 
   ipf(200) is more or less the normal setting...
 
---------------------------------------------------------------------------------------------------------
 
   Syntax :
 
-- boolean/float/int/object/string variableA, variableB, variableC;
 
   You can declare multiple variables of the same type on the same line by defining them with a ','.
 
   example :: int varX, varY, varZ;
 
 
---------------------------------------------------------------------------------------------------------
 
   Syntax :
 
-- boolean/float/int/object/string[]   Defines a array.
 
   You can create a array from any type of variable with [], members are addressed with a int index. 
   e.a. variable[12] or array[3] Arrays of arrays of the same type is possible.
 
   example :: float array[];
 
              array[0] = 1.23;
              array[1] = -4.32;
   ---
              int[] array, anotherArray, arrays[];
 
              array[0] = 1;
              array[1] = 2;
              anotherArray[0] = -1;
              anotherArray[5] = 1;
              arrays[0] = array;
              arrays[1] = anotherArray;
 
   Use sizeof to get the size or maximum index of a array, ofcourse functions can also accept and return
   arrays.
 
   Syntax :
 
-- int sizeof(array[])   Returns the size of a array or index-1.
-- type[] functionName(type variable[])  Creates a function accepting and returning a array.        
 
   note -- ( this example can best be used with ipf(10000) or similar )
 
   example :: int[] getCategories()
              {
                 object Object;
                 int typesFound[], indexFound = 0, searchIndex = 0;
 
                 while (true)
                 {
                    Object = retobject(searchIndex);
                    if (Object == null)
                    {
                       return typesFound;
                    }
                    if (!intExist(typesFound, Object.category))
                    {
                       typesFound[indexFound] = Object.category;
                       indexFound++;
                    }
                    searchIndex++;
                 }
              }
 
              boolean intExist(int[] array, int target)
              {
                 if (sizeof(array) != 0)
                 {
                    for (int searchIndex = sizeof(array) - 1; searchIndex > 0 ; searchIndex--)
                    {
                       if (array[searchIndex] == target)
                       {
                          return true;
                       }
                    }
                 }
                 return false;
              }
 
   note -- You can define directly index 5, however the rest of the array 0 to 4 is also created and
           assigned with nan.
 
   example :: string[] text;
 
              text[5] = "hello world :p";
 
   would actually make the array : text[0] = nan;
   				   text[1] = nan;
   				   text[2] = nan;
   				   text[3] = nan;
   				   text[4] = nan;
   				   text[5] = "hello world :p";
 
---------------------------------------------------------------------------------------------------------
 
   Syntax :
 
-- object radar(int[] Category, float[] Angle, float[] Focus, float[] Min, float[] Max, float[] Sens)
 
   note -- All variable accept arrays, you may use for example a array of alien category to detect 
           multiple kinds of alien foes at once.
 
   example :: object target;
              int foes[];
 
              foes[0] = AlienQueen;
              foes[1] = AlienEgg;
              foes[2] = AlienAnt;
              foes[3] = AlienSpider;
              foes[4] = AlienWasp;
              foes[5] = AlienWorm;
 
              target = radar(foes);
 
---------------------------------------------------------------------------------------------------------
 
   Syntax :
 
-- object search(int preferedCategory, int x, int y)  Returns a prefered object or the nearest object
                                                      at a specified location.
 
   note -- the x and y ofcourse optional, however y is needed when x is specified.
 
---------------------------------------------------------------------------------------------------------
 
   Syntax :
 
-- int produce(point Position, float Direction, int Category, string Script)
 
   Produces objects like bots and powercells out of thin air, amazing! :) (Doesn't work on all kinds of
   objects) Returns 0 if successful, 1 if not. A name of a script filename can be given to be runned on a
   produced bot. example: "script.txt"
 
   example :: produce(position, 0, PowerCell, "");
 
---------------------------------------------------------------------------------------------------------
 
   Syntax :
 
-- public type functionName(type variable1, type variable2, etc)
 
   You can make a function accessible with public from another script and also from another bot!
 
   example :: // bot #1
              public string indentify()
              {
                 return "Hi, my name is, my name is, my name is...";
              }
 
              // bot #2
              message(indentify());
 
---------------------------------------------------------------------------------------------------------
 
   I know there is more i could see it in their face ;), but this is it for now, maybe ever...
 
===================================================================
   Some usefull functions i wrote on those missions...
 
---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------         
 
-- Returns the angle to the grid from pointA to pointB. Similar to direction except direction assumes 
   pointA to be the bots position.           
 
   float angle(point pointA, point pointB)
   {
      float offset = 90;
      if (deltaY(pointA, pointB) > 0)
      {
         offset = 270;
      }
      return offset + atan(deltaX(pointA, pointB) / deltaY(pointA, pointB));
   }
 
---------------------------------------------------------------------------------------------------------
 
   float deltaX(point origin, point target)
   {
      return target.x - origin.x;
   }
 
---------------------------------------------------------------------------------------------------------
 
   float deltaY(point origin, point target)
   {
      return target.y - origin.y;
   }
 
---------------------------------------------------------------------------------------------------------
 
   Calculates a point from another point with a horizontal angle, a vertical angle and a distance.
 
   point triangulate(point origin, float Distance, float angleH, float angleV)
   {
      point dest;
 
      dest.x = cos(angleH) * cos(angleV) * Distance;
      dest.y = sin(angleH) * cos(angleV) * Distance;
      dest.z = sin(angleV) * Distance;
 
      return dest;
   }
 
---------------------------------------------------------------------------------------------------------
 
   Same as triangulate but only using  2 dimensions. (horizontal)
 
   point triangulate2d(point origin, float Distance, float angle)
   {
      point dest;
 
      dest.x = cos(angle) * Distance;
      dest.y = sin(angle) * Distance;
 
      return dest;
   }

Телохранитель

Нуждаетесь в телохранителе? :-) В этой программой Ваш робот-охранник будет следовать за Вами. В опасных ситуациях будет защищать Вас, стреляя в находящихся рядом врагов. Можете создавать эскорты для охраны чего-либо. Также можете делать несколько роботов охранниками друг друга для скоординированной помощи.

extern void object::Guard()
{
    int allyType = Me;                   // put ally category here (i.e. LeggedGrabber)
    int keepCloseDist = 10;              // how far behind to follow
    int parimeterToScan = 50;            // range to look for enemy
 
    object enemy;
 
    while(true)
    {
        enemy = radar(AlienAnt,0,360,0,parimeterToScan);
 
        if(enemy == null)
            follow(allyType,keepCloseDist);
        else
            moveAndDestroy(enemy);
    }
}
 
void object::follow(int category, int parimeter)
{
    object ally = radar(category);
 
    float dis = distance(position,ally.position);
 
    if(dis > parimeter)                           // if too far away from ally
    {
        float dif = ally.position.z-position.z;
        float ang = asin(dif/dis);
 
        jet(1-(ang/-20));
 
        float dir = direction(ally.position);
 
        motor(1-dir/22.5,1+dir/22.5);             // move in closer
    }
 
    else                                          // otherwise too close
    { 
        motor(dis/parimeter-1, dis/parimeter-1);  // back up a little
 
        if(topo(position) > 0)                    // if not over water
            jet(-1);                              // then land to conserve energy/minimize heat
    }
}
 
void object::moveAndDestroy(object target)
{
    float dir;    // direction of target from shooter
    float dis;    // distance of target from shooter
    float dif;    // difference in altitude of target & shooter (relative to sea-level)
    float ang;    // angle shooter must aim (-20 degrees favorable)
 
    dis = distance(position,target.position);
    dif = target.position.z-position.z;
    ang = asin(dif/dis);
 
    jet(1-(ang/-20));                         // thrust until 20 degress above target
 
    dir = direction(target.position); 
 
    motor(1-dir/22.5,1+dir/22.5);             // move towards enemy
 
    dis = distance(position,target.position);   
    dif = target.position.z-position.z;         
    ang = asin(dif/dis);                        
 
    aim(ang);                                 // take aim
 
    dir = direction(target.position);           
 
    if(dis < 30 and dir > -10 and dir < 10)   // if within range
        fire(0.1);
}

Авто-чарджер

Лучшая программа для зарядки летающих роботов-охотников. Робот найдет батарейку, перезарядит ее при необходимости, переместится к летающему роботу и перезарядит батарейку. Работает даже если нет свободных батареек: возьмет у робота разряженную батарейку -> слетает на база для подзарядки -> вернется обратно.

// locates a WingedShooter with less than 'full' (0.9)
// energy and resupplies it with a cell that's at least at
// 'minevel' (0.8).
// precond: hands empty or carrying power cell
extern void object::ReloadWingedShooter()
{
	// level at which we decide to reload power cells
	float minLevel = 0.8;
 
	// full is defined in pickNonFullWS, below
 
	point home = position;
 
	object ws = pickNonFullWS();
	if (ws == null) {
		message("Nobody to resupply");
		return;
	}
	if (load==null) grabPowerCell();
	if (load.category!=PowerCell) {
		message("I cannot resupply the WS because I am carrrying something already");
		// (and it's not a power cell)
		return;
	}
 
	if (load.energyLevel<minLevel) {
		message("reloading power cell first, it is below "+minLevel);
		sub_reload();
	}
 
	/// go to winged shooter and replace power cell
 
	goto(ws.position);
	if (ws.load!=null) {
		// switch old cell for new
		message("Removing old cell");
		drop(Behind); // drop our loaded cell
		grab(); // take old one
		turn(90);
		drop(); // drop old one
		turn(-90);
		grab(Behind); // take loaded cell
	}
	// insert new cell in winged shooter
	drop();
 
 
	message("Done refueling WS, returning to starting point");
	goto(home);
}
 
// makes sure we grab a power cell. Gets a power cell around
// us or from the power plant if that's closer.
// precond: hands empty
void object::grabPowerCell() {
 
	object energy = radar(PowerCell);
	object factory = radar(PowerPlant);
 
	if (factory!=null) {
		object bat = factory.energyCell;
		if (null!=bat) {
			// power plant has a battery ready
			if (distance(position,bat.position)<distance(position,energy.position)) {
				// power plant is closer, take its battery
				// instead
				energy = bat;
			}
		}
	}
 
	if (energy == null) {
		message("No power cell around");
		return;
	}
 
	goto(energy.position);
	grab();
}
 
// reload power and shield
void object::sub_reload()
{
	object item;           // info. about power station
 
	point start = position;      // store initial position
 
	item = radar(PowerStation); // look for station
	goto(item.position);   // go to the power station
 
	object l = load;
	if (null!=l) {
		if (l.category != EnergyCell) l = null;
	}
	int cl = 0;
	if (l == null) cl = 1;
	else cl = l.energyLevel;
 
	while ( energyCell.energyLevel < 1 or cl < 1)
	{
		wait(1);            // wait until recharged
		if (l == null) cl = 1;
		else cl = l.energyLevel;
	}
 
	object rep = radar(RepairCenter);
	if (shieldLevel<1.0 and null!=rep) {
		goto(rep.position);
		while (shieldLevel<1.0) {
			wait(1);
		}
	}
	message("Recharge completed");
}
 
// returns a winged shooter with energy below 'full',
// or null if none exist
object object::pickNonFullWS() {
 
	// we will not pick a WS with power above this level
	float full=1;
 
	float m =0;
	int count=0;
	object ws = null;
	float l; // energy level of WS in consideration
	do {
		count++;
		ws = radar(WingedShooter,0,360,m);
		l=0;
		if (null!=ws){
			if (null!=ws.energyCell) {
				l = ws.energyCell.energyLevel;
			}
		}
 
		if (l>=full and null!=ws) {
			m=distance(position,ws.position)+0.1;
			ws = null;
		} else if (null!=ws) {
			message("picked a WS with energy ("+l+")");
		}
	} while (l>=full and count<100);
	if (null==ws) {
		message("There is no WS under "+full+" around");
	}
	return ws;
}

Миссия на Земле. Автопрохождение

Программа, полностью автоматизирующая Земную миссию в демо-версии. Все возможные задачи и действия автоматизированы. Вам достаточно только загрузить программу в WheeledGrabber и TrackedGrabber. Некоторые действия вроде перемещения астронавта на корабль и создание зданий автоматизировать нельзя, так как игра это не позволяет.

extern void object::Mission1()
{
	object rdr;
 
	if(category ==WheeledGrabber)
	{
		rdr = radar(PowerCell);
		goto(rdr.position);
		grab();
 
		rdr = radar(ResearchCenter);
		goto(rdr.position);
		drop();
 
		message("Research center powered - begin research.");
 
		rdr = radar(PowerCell); // There are two powercells that get in the way
		goto(rdr.position);
		grab();
		turn(90);
		drop();
		move(-5);
		rdr = radar(PowerCell);
		goto(rdr.position);
		grab();
		turn(90);
		drop();
 
		rdr = radar(Titanium);
		goto(rdr.position);
		grab();
 
		rdr = radar(BotFactory);
		goto(rdr.position);
		drop();
		move(-5);
 
		message("Bot factory loaded. Create new bot.");
 
		rdr = radar(PowerCell);
		goto(rdr.position);
		grab();
 
		rdr = radar(TrackedGrabber);
		message("Waiting for manufacture of Tracked Grabber.");
		while(rdr == null) rdr = radar(TrackedGrabber);
 
		goto(rdr.position);
		drop();
 
		message("Tracked grabber is ready.");
 
		rdr = radar(SpaceShip);
		goto(rdr.position);
	}
	else
	{
		move(-5);
 
		rdr = radar(BlackBox);
		goto(rdr.position);
		grab();
 
		rdr = radar(SpaceShip);
		goto(rdr.position);
		drop();
	}
	message(category + ": Mission complete");
}

Миссия на Луне. Автопрохождение

Программа, полностью автоматизирующая Лунную миссию в демо-версии. Вам достаточно только загрузить программу в WheeledGrabber и TrackedGrabber. Некоторые действия вроде перемещения астронавта на корабль и создание зданий автоматизировать нельзя, так как игра это не позволяет.

extern void object::MoonOre()
{
	object rdr;
	int counter = 0;
	float range = 0;
	int errcode = 0;
 
	errmode(0);
	if(category == WheeledGrabber)
	{
		rdr = radar(PowerCell);
		errcode = goto(rdr.position);
		while(errcode != 0) errcode = goto(rdr.position);
		grab();
 
		rdr = radar(ResearchCenter);
		if(rdr == null) message("Waiting for Researchcenter to be built.");
		while(rdr == null) rdr = radar(ResearchCenter);
		errcode = goto(rdr.position);
		while(errcode != 0) errcode = goto(rdr.position);
		drop();
 
		message("Researchcenter is powered.");
		rdr = radar(Titanium);
		errcode = goto(rdr.position);
		while(errcode != 0)
		{
			rdr = radar(Titanium);
			errcode = goto(rdr.position);
		} 
		grab();
 
		rdr = radar(BotFactory);
		if(rdr == null) message("Waiting for Botfactory to be built.");
		while(rdr == null) rdr = radar(BotFactory);
		errcode = goto(rdr.position);
		while(errcode != 0)
		{
			turn(direction(rdr.position));
			move(distance2d(position, rdr.position));
			errcode = goto(rdr.position);
		}
		drop();
 
		message("Titanium loaded into BotFactory");
 
		rdr = radar(PowerCell);
		errcode = goto(rdr.position);
		while(errcode != 0) errcode = goto(rdr.position);
		grab();
 
		rdr = radar(WingedGrabber);
		if(rdr == null) message("Waiting for Wingedgrabber to be built.");
		while(rdr == null) rdr = radar(WingedGrabber);
		wait(5);
		errcode = goto(rdr.position);
		while(errcode != 0) errcode = goto(rdr.position);
		drop();
 
		message("Wingedgrabber ready.");
 
		move(-6);
 
		rdr = radar(Titanium); //Get the extra Titanium out of the way
		if(rdr != null)
		{
			errcode = goto(rdr.position);
			while(errcode != 0) errcode = goto(rdr.position);
			grab();
			errcode = goto(space(position));
			while(errcode != 0) errcode = goto(space(position));
			drop();
		}
		message("Waiting for ore to be delivered.");
		while(counter < 4)
		{
			counter = 0;
			rdr = radar(TitaniumOre,0,360,range,100);
			while(rdr != null)
			{
				counter++;
				range = distance2d(position, rdr.position) + 0.01;
				rdr = radar(TitaniumOre,0,360,range,100);
			}
			range = 0;
		}
 
		rdr = radar(SpaceShip);
		errcode = goto(rdr.position);
		while(errcode != 0) errcode = goto(rdr.position);
	}
	else
	{
		for(counter = 0; counter < 4; counter++)
		{
			rdr = radar(TitaniumOre,0,360,100,1000);
			errcode = goto(rdr.position);
			while(errcode != 0) errcode = goto(rdr.position);
			grab();
 
			rdr = radar(SpaceShip);
			errcode = goto(rdr.position);
			while(errcode != 0) errcode = goto(rdr.position);
			errcode = drop();
			while(errcode != 0)
			{
				turn(-45);
				errcode = drop();
			}
			message("Delivered " + (counter +1) + " ore samples.");
		}
	}
	message(category + ": Mission Complete.");
}

Миссия в воздухе. Автопрохождение

Программа, полностью автоматизирующая летающую миссию в демо-версии. Робот автоматически пролетает через все воздушные цели. Никаких ручных действий не требуется.

extern void object::FlyingDrill()
{
	object rdr;
	object last;
 
	while(true)
	{
		rdr = radar(Target2,0,180,1,100);
		if(rdr == null)
		{
			rdr = radar(SpaceShip,0,180,1,100);
			turn(direction(rdr.position));
			move(distance(position, rdr.position));
			break;
		}
		if(rdr.position.z > position.z) jet(0.3);
		if(rdr.position.z < position.z) jet(-0.3);
		if(direction(rdr.position) > 2) motor(0.5,1);
		if(direction(rdr.position) < 2) motor(1,0.5);
		if(abs(direction(rdr.position)) <= 2) motor(1,1);
		if(temperature > 0.9) //Should not need this part
		{
			motor(0,0);
			while(temperature > 0) wait(1);
		}
	}
}

Робот-достал

Программа, которая приказывает боту следовать за конкретным объектом. Например, за Вами.

extern void object::FollowMe()
{
	object spaceguy;
	while(true)
	{
		spaceguy=radar(Me);
		goto(spaceguy.position,spaceguy.altitude,1,1);
	}
}

Количество объектов

Выводит количество объектов в какой-либо конкретной категории.

extern void object::ScanforObject()
{
	object item;
	int number=0;
	float min=0,max=1000;
	string catname;
	do{
		// >>>>>>> change category here <<<<<<<
		item=radar(PowerCell,0,360,min,max,1);
		// >>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<
 
		if(item!=null)
		{
			++number;
			min=distance(position,item.position)+0.01;
			catname="["+item.category+"s]";
		}
	}while(item!=null);
	if(number==0)
		message("[none found]",DisplayInfo);  
	else
		message(catname +": "+number,DisplayInfo);
}

С некоторыми другими программами Вы можете ознакомится на официальном сайте. Описания там приведены на английском языке.

Удачного программирования! Если у Вас есть свои программы — выкладывайте их в комментариях.


Есть мысли на этот счет:
Новомир 27.12.2009 12:37 пишет:

Интересно, а кто-нибудь уже придумал программу Чак Норрис? :)

dima 30.01.2010 12:29 пишет:

Отличные программы, а где русского CEEBOT`а можно скачать?

Есть что сказать?
Ваше имя:
Ваш e-mail:
Ваш сайт:
Ваше мнение:




земляные работы в Донецке