package exe; import robocode.*; import baseRobot.*; /** * 敵時系列データの収集と分析 * * @author Fumi Iseki * @version 1.0 */ public class TimeData { private ExtRobot myRobo; private int bufferSize; protected RingBuffer pT, pX, pY, vX, vY, aX, aY; protected RingBuffer pE, pA, pD; public static RingBuffer hitRate = new RingBuffer(20); public static RingBuffer canMode = new RingBuffer(20); public static RingBuffer firCrct = new RingBuffer(20); /** * コンストラクタ */ public TimeData(ExtRobot robo, int n) { myRobo = robo; bufferSize = n; pT = new RingBuffer(n); pX = new RingBuffer(n); pY = new RingBuffer(n); vX = new RingBuffer(n); vY = new RingBuffer(n); aX = new RingBuffer(n); aY = new RingBuffer(n); pE = new RingBuffer(n); pA = new RingBuffer(n); pD = new RingBuffer(n); } /** * コンストラクタ.その2 */ public TimeData(ExtRobot robo) { this(robo, 100); } /** * データ収集 */ public void putData() { double t2 = (double)myRobo.getNowTime(); double t1 = pT.getData(0); double t0 = pT.getData(1); double a2 = myRobo.getEnemyAngle(); double d2 = myRobo.getEnemyDistance(); double th = (0.5 - a2/180.)*Math.PI; double x2 = d2*Math.cos(th) + myRobo.getX(); double y2 = d2*Math.sin(th) + myRobo.getY(); double vt = (0.5 - myRobo.getEnemyHead()/180)*Math.PI; double v2 = myRobo.getEnemySpeed()*Math.cos(vt); double w2 = myRobo.getEnemySpeed()*Math.sin(vt); double e2 = myRobo.getEnemyEnergy(); // ラグランジュ補間 double lt0 = (t0-t1)*(t0-t2); double lt1 = (t1-t0)*(t1-t2); double lt2 = (t2-t0)*(t2-t1); if (t2-t1>=2 && lt0!=0. && lt1!=0. && lt2!=0.0) { double x1 = pX.getData(0); double y1 = pY.getData(0); double x0 = pX.getData(1); double y0 = pY.getData(1); double v1 = vX.getData(0); double w1 = vY.getData(0); double v0 = vX.getData(1); double w0 = vY.getData(1); double e1 = pE.getData(0); double e0 = pE.getData(1); double a1 = pA.getData(0); double a0 = pA.getData(1); double d1 = pD.getData(0); double d0 = pD.getData(1); for (double t=t1+1; t0) { // 等加速度運動 double tt; if (bb>0) tt = (-bb + Math.sqrt(cc))/aa; else { double t1 = -bb - Math.sqrt(cc); double t2 = -bb + Math.sqrt(cc); if (t1>0) tt = t1/aa; else tt = t2/aa; } if (tt>0) { if (tt>t) tt = t; vt.x = px + vx*t + ax*tt*(t-tt*0.5); vt.y = py + vy*t + ay*tt*(t-tt*0.5); } } return vt; } /** * 円運動を予測 */ public Vector circleMover(int t) { Vector vt = new Vector(-1); if (2*t+1>pT.getValidDataNum()) return vt; double xx = pX.getData(0); double yy = pY.getData(0); double px = xx - pX.getData(t); double py = yy - pY.getData(t); double ox = pX.getData(t) - pX.getData(2*t); double oy = pY.getData(t) - pY.getData(2*t); double nx = px - ox; double ny = py - oy; double ol = Math.sqrt(ox*ox + oy*oy); double nl = Math.sqrt(nx*nx + ny*ny); if (ol>0.01 && nl>0.01) { double gm = nl/ol; double cs = (ox*nx + oy*ny)/(nl*ol); double sn = (ox*ny - oy*nx)/(nl*ol); vt.x = xx + px + gm*(cs*px - sn*py); vt.y = yy + py + gm*(sn*px + cs*py); } return vt; } /** * 等加速度運動かどうかをチェックする */ public boolean isConstAccele(int t) { if (aX.isConstant(t) && aY.isConstant(t)) return true; else return false; } /** * 円運動かどうかをチェックする */ public boolean isCircle(int t) { if (2*t+1>pT.getValidDataNum()) return false; double xx = pX.getData(t); double yy = pY.getData(t); double px = xx - pX.getData(2*t); double py = yy - pY.getData(2*t); double ox = pX.getData(2*t) - pX.getData(3*t); double oy = pY.getData(2*t) - pY.getData(3*t); double nx = px - ox; double ny = py - oy; double ol = Math.sqrt(ox*ox + oy*oy); double nl = Math.sqrt(nx*nx + ny*ny); if (ol>0.01 && nl>0.01) { double gm = nl/ol; double cs = (ox*nx + oy*ny)/(nl*ol); double sn = (ox*ny - oy*nx)/(nl*ol); xx = xx + px + gm*(cs*px - sn*py); yy = yy + py + gm*(sn*px + cs*py); } else return false; double x0 = xx - pX.getData(0); double y0 = yy - pY.getData(0); if (x0*x0+y0*y0<0.2) return true; else return false; } }