|
|
Line 1: |
Line 1: |
− | {| width="100%" style="background: white; "
| + | I took the freedom of erasing all my old and deprecated stuff which just cluttered this page :) Please inform me if this is "bad" behaviour here, then we can restore it! |
− | | valign="top" width="60%" style="border: 2px solid #000; padding: .5em 1em; -moz-border-radius: 1em; -webkit-border-radius: 1em" |
| |
− | '''Welcome!'''
| |
| | | |
− | Hello, {{BASEPAGENAME}}, and welcome to [[RoboWiki]]! This place contains a wealth information about [[Robocode]], from [[Head-On Targeting|basic]] to [[Wave Surfing|more advanced]]. I hope you enjoy creating robots and being a robocoder!
| + | I also have some questions, and wonder if there is a good way to talk to more experienced Robocoders, like some IRC channel or similar, or a good place to post these questions? |
| | | |
− | If you are posting a comment on this wiki, please [[wikipedia:Wikipedia:Signatures|sign]] your messages using four tildes (<nowiki>--~~~~</nowiki>); this will automatically insert your username and the date stamp. If you are not familiar with MediaWiki, these links might help you out:
| + | While I'm at it, I wonder how to get LiteRumble running. I downloaded a "superpack" from the talk page of LiteRumble, but it was for for some 1.7.x version, and someone mentioned to update the client to the newest version. So could I just create a new folder for the most recent robocode, copy all the bots from the superpack there and change the roborumble settings? What's the most elegant way? :) And do the bots update automatically? I don't want to be just trying it out, since I fear I could destroy something by doing this.. |
− | * [[wikipedia:How to edit|How to edit]] on [[wikipedia:|Wikipedia]], [[metawikipedia:Cheatsheet|Cheatsheet]] and [[metawikipedia:File:MediaWikiRefCard.pdf|Reference Card]] of MediaWiki on the [[metawikipedia:|Meta Wikipedia]].
| |
− | * [[RoboWiki:ReadMe|Readme]] page.
| |
− | If you need [[Help:Help|help]], check out the [[Robocode/FAQ|frequently asked questions]] or ask it on this page. Again, welcome!
| |
− | | |
− | —— [[User:Rednaxela|Rednaxela]] 15:59, 28 November 2009 (UTC)
| |
− | |}
| |
− | | |
− | Welcome to the wiki! :) --[[User:Rednaxela|Rednaxela]] 15:59, 28 November 2009 (UTC)
| |
− | | |
− | Hello, and thank you. :-) --[[User:Kenran|Kenran]] 09:07, 29 November 2009 (UTC)
| |
− | | |
− | == My first try at Pattern Matching ==
| |
− | | |
− | So this my first attempt to write a simple pattern matching gun. As you can see, my in some sense my code is similar to that of [[PEZ]]'s LeachPMC, where I looked at to help me do it. (Thanks for that, PEZ :-)).
| |
− | | |
− | But now I'm having some trouble and would be very happy if someone with Robocode and Java knowledge could overlook it and / or help me with it:
| |
− | * As you can see <code>aimed</code> is superfluous at the moment. I tried to make the bot faster by only calculating predictedPosition at moments where I actually want to shoot. But I can't seem to handle this: I wanted to do sth like <code>if (getGunHeat() > getGunCoolingRate()*3 && getRoundNum() != 0)</code>, then predict and set <code>aimed = true</code>, and finally fire if <code>aimed == true && getGunTurnRemaining() == 0.0</code> (and set <code>aimed = false</code> again). But that doesn't work, at a certain point it just stops firing at all then :-/
| |
− | * I don't understand why, e.g. versus Walls, it can't handle the movement in the edges: it seems to predict the right "position" but at the wrong time, so the bullets just impact before Walls is at that position. Any ideas why this could be the case? Maybe sth with my predictPosition algorithm.
| |
− | | |
− | I hope, my code is not too sloppy, as I mentioned, I'm not a very good programmer. Anyway, great site, I wouldn't have been able to get any kind of targeting working without it :-)
| |
− | | |
− | <syntaxhighlight>package kenran.mega;
| |
− | | |
− | import robocode.*;
| |
− | import kenran.util.*;
| |
− | import java.awt.geom.Point2D;
| |
− | import java.util.ArrayList;
| |
− | | |
− | public class Pantheist extends AdvancedRobot
| |
− | {
| |
− | private static final int PM_LENGTH = 7000;
| |
− | private static final int RECENT_PATTERN_LENGTH = 10;
| |
− | | |
− | private static Point2D _enemyPosition = new Point2D.Double();
| |
− | private static Point2D _robotPosition = new Point2D.Double();
| |
− | private static double _enemyHeading = 0;
| |
− | private static double _enemyBearing;
| |
− | private static double _enemyVelocity;
| |
− | private static double _enemyDistance;
| |
− | private static double _deltaHeading;
| |
− | | |
− | private static ArrayList _record = new ArrayList(PM_LENGTH);
| |
− | private static MovementDeque _recent = new MovementDeque();
| |
− | private static MovementDeque _iterator = new MovementDeque();
| |
− | private static int _recordSize = 0;
| |
− | private static boolean _recordIsFull = false;
| |
− | | |
− | private static boolean aimed;
| |
− | | |
− | | |
− | public void run()
| |
− | {
| |
− | setAdjustGunForRobotTurn(true);
| |
− | setAdjustRadarForGunTurn(true);
| |
− | aimed = false;
| |
− | if (getRoundNum() == 0)
| |
− | for (int i = 0; i < RECENT_PATTERN_LENGTH; i++)
| |
− | _recent.add(0, 8.0);
| |
− | turnRadarRightRadians(Double.POSITIVE_INFINITY);
| |
− | do
| |
− | {
| |
− | scan();
| |
− | } while (true);
| |
− | }
| |
− | | |
− | | |
− | public void onScannedRobot(ScannedRobotEvent e)
| |
− | {
| |
− | _robotPosition.setLocation(getX(), getY());
| |
− | _enemyDistance = e.getDistance();
| |
− | _deltaHeading = e.getHeadingRadians() - _enemyHeading;
| |
− | _enemyHeading = e.getHeadingRadians();
| |
− | _enemyBearing = getHeadingRadians() + e.getBearingRadians();
| |
− | _enemyVelocity = e.getVelocity();
| |
− | _enemyPosition.setLocation(Utils.project(_robotPosition, _enemyBearing, _enemyDistance));
| |
− | record(_deltaHeading, _enemyVelocity);
| |
− | _recent.add(_deltaHeading, _enemyVelocity);
| |
− | if (getRoundNum() != 0)
| |
− | {
| |
− | Point2D predictedPosition = new Point2D.Double();
| |
− | predictedPosition.setLocation(predictPosition(1.5));
| |
− | double angle = Utils.absoluteBearing(_robotPosition, predictedPosition);
| |
− | setTurnGunRightRadians(Utils.normalRelativeAngle(angle - getGunHeadingRadians()));
| |
− | aimed = true;
| |
− | }
| |
− | if (getRoundNum() != 0 && aimed)
| |
− | {
| |
− | setFire(1.5);
| |
− | aimed = false;
| |
− | }
| |
− | double radarTurn = _enemyBearing - getRadarHeadingRadians();
| |
− | setTurnRadarRightRadians(2.0*Utils.normalRelativeAngle(radarTurn));
| |
− | }
| |
− | | |
− | | |
− | private void record(double dh, double v)
| |
− | {
| |
− | _record.add(new MovementState(dh, v));
| |
− | if (_recordIsFull)
| |
− | _record.remove(0);
| |
− | else
| |
− | {
| |
− | _recordSize++;
| |
− | _recordIsFull = (_recordSize >= PM_LENGTH);
| |
− | }
| |
− | }
| |
− | | |
− | | |
− | private double compare(MovementDeque md1, MovementDeque md2)
| |
− | {
| |
− | double sum = 0;
| |
− | for (int i = 0; i < RECENT_PATTERN_LENGTH; i++)
| |
− | {
| |
− | sum += Math.abs(md1.get(i).getDeltaHeading()-md2.get(i).getDeltaHeading()) + Math.abs(md1.get(i).getVelocity()-md2.get(i).getVelocity());
| |
− | }
| |
− | return sum;
| |
− | }
| |
− | | |
− | | |
− | private int lastIndexOfMatchingSeries()
| |
− | {
| |
− | for (int i = 0; i < RECENT_PATTERN_LENGTH; i++)
| |
− | _iterator.add((MovementState)_record.get(i));
| |
− | double min = compare(_iterator, _recent);
| |
− | int minPos = RECENT_PATTERN_LENGTH - 1;
| |
− | int i = RECENT_PATTERN_LENGTH;
| |
− | do
| |
− | {
| |
− | MovementState ms = (MovementState)_record.get(i);
| |
− | _iterator.add(ms.getDeltaHeading(), ms.getVelocity());
| |
− | double comp = compare(_iterator, _recent);
| |
− | if (comp < min)
| |
− | {
| |
− | min = comp;
| |
− | minPos = i;
| |
− | }
| |
− | i++;
| |
− | } while (i < _recordSize - 50);
| |
− | return minPos;
| |
− | }
| |
− | | |
− | | |
− | private Point2D predictPosition(double power)
| |
− | {
| |
− | int index = lastIndexOfMatchingSeries();
| |
− | double px = _enemyPosition.getX();
| |
− | double py = _enemyPosition.getY();
| |
− | double heading = _enemyHeading;
| |
− | double bulletTravelTime = 0;
| |
− | double travelTime = 0;
| |
− | for (int i = index+1; i < _recordSize && travelTime <= bulletTravelTime; i++)
| |
− | {
| |
− | MovementState ms = (MovementState)_record.get(i);
| |
− | px += Math.sin(heading) * ms.getVelocity();
| |
− | py += Math.cos(heading) * ms.getVelocity();
| |
− | heading += ms.getDeltaHeading();
| |
− | bulletTravelTime = (int)Utils.bulletTravelTime(_robotPosition.distance(px, py), power);
| |
− | travelTime++;
| |
− | }
| |
− | return new Point2D.Double(px, py);
| |
− | }
| |
− | | |
− | | |
− | static class MovementDeque
| |
− | {
| |
− | private MovementState[] msArray = new MovementState[RECENT_PATTERN_LENGTH];
| |
− | | |
− | MovementDeque() {}
| |
− | | |
− | void add(double dh, double v)
| |
− | {
| |
− | for (int i = 0; i < RECENT_PATTERN_LENGTH-1; i++)
| |
− | msArray[i] = msArray[i+1];
| |
− | msArray[RECENT_PATTERN_LENGTH-1] = new MovementState(dh, v);
| |
− | }
| |
− | | |
− | void add(MovementState ms)
| |
− | {
| |
− | add(ms.getDeltaHeading(), ms.getVelocity());
| |
− | }
| |
− | | |
− | MovementState get(int i)
| |
− | {
| |
− | if (0 <= i && i < RECENT_PATTERN_LENGTH)
| |
− | return msArray[i];
| |
− | else
| |
− | return null;
| |
− | }
| |
− | }
| |
− | }</syntaxhighlight>
| |
− | --[[User:Kenran|Kenran]] 15:48, 5 December 2009 (UTC)
| |
− | | |
− | What is the propose of <code>getRoundNum() != 0</code>? That means it won't fire in the first round. If you remove all reference to the getRoundNum() == 0 or getRoundNum() !== 0, I think it will perform much better.
| |
− | | |
− | Actually I would say, don't use the PMC robot as a codebase, as it is very optimized to the PMChallenge. Try to read the robot with normal PM, e.g. Waylander, before. If you can't figure out what is behind the shrunk code of Waylander, feel free to ask again. {{Unsigned|Nat}}
| |