forked from: Arkanoid AI
んーなんか普通にスルーするのあるなぁ・・なんでだろう mostcloseにひきづられるのかな
/**
* Copyright uwi ( http://wonderfl.net/user/uwi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/suUi
*/
// forked from uwi's Arkanoid AI
// んーなんか普通にスルーするのあるなぁ・・なんでだろう mostcloseにひきづられるのかな
package {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.text.TextField;
public class FlashTest extends Sprite {
private var _tf : TextField;
private var _balls : Array;
private var _wbar : Number = 80;
private var _hbar : Number = 10;
private var _xbar : Number = 200;
private var _ybar : Number = 400;
private var _vbar : Number = 15.0;
private var _field : BitmapData;
private var _ndrop : int = 0;
private var _nreflect : int = 0;
private var _arrival : Array;
public function FlashTest() {
_field = new BitmapData(465, 465, false);
addChild(new Bitmap(_field));
_tf = new TextField();
addChild(_tf);
_tf.width = 465;
_tf.height = 465;
_tf.textColor = 0xffffff;
_tf.text = "";
_balls = [];
for(var i : int = 0;i < 10;i++)appendBall();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function algo() : Number
{
var ranges : Array = [];
_tf.text = "";
for each(var b : Object in _balls){
// ignore raising balls, meanwhile.
if(b.vy > 0){
var t : Number = ((_ybar - _hbar / 2) - b.y) / b.vy;
if(t > 0 && t < 500){
var px : Number = b.x + t * b.vx;
var s : int = Math.floor(px / 465);
if((s & 1) == 1){
px = 465 - (px - 465 * s);
}else{
px = px - 465 * s;
}
ranges.push({t : t, min : px - _wbar * 0.4, max : px + _wbar * 0.4, w : 1.0});
}
}
}
var ret : Object = solvePath(_xbar, _vbar, ranges);
// _tf.appendText("" + ret.min + "\t" + ret.max + "\n");
_tf.appendText("drop : " + _ndrop + "\n");
_tf.appendText("reflect : " + _nreflect + "\n");
_tf.appendText("balls : " + _balls.length + "\n");
if(ret.max < _xbar)return -_vbar;
if(ret.min > _xbar)return _vbar;
return 0;
}
private function appendBall() : void
{
var vr : Number = Math.random() * 5 + 5;
var vtheta : Number = Math.random() * Math.PI * 0.9 - Math.PI * 0.45;
if(Math.random() > 0.5)vtheta += Math.PI;
_balls.push({
x : Math.random() * 465,
y : Math.random() * 100,
vx : vr * Math.sin(vtheta),
vy : vr * Math.cos(vtheta)
});
}
private function removeBall(ind : int) : void
{
var b : Object = _balls.pop();
if(ind < _balls.length)_balls[ind] = b;
}
private function draw() : void
{
_field.lock();
_field.fillRect(_field.rect, 0x000000);
// balls
for each(var b : Object in _balls){
_field.fillRect(new Rectangle(b.x - 3, b.y - 3, 6, 6), 0xffffff);
}
// bar
_field.fillRect(new Rectangle(_xbar - _wbar / 2, _ybar - _hbar / 2, _wbar, _hbar), 0x00ff00);
_field.unlock();
}
private function progress() : void
{
// balls
for(var i : int = 0;i < _balls.length;i++){
var b : Object = _balls[i];
b.x += b.vx;
b.y += b.vy;
if(b.x < 0){ b.vx = -b.vx; b.x = -b.x; }
if(b.x > 465){ b.vx = -b.vx; b.x = 465*2-b.x; }
if(b.y < 0){ b.vy = -b.vy; b.y = -b.y; }
if(b.y > 465){
_ndrop++;
removeBall(i);
}
// inaccurate
if(b.y >= _ybar - _hbar / 2 && b.y - b.vy < _ybar - _hbar / 2 && b.x >= _xbar - _wbar / 2 && b.x <= _xbar + _wbar / 2){
b.vy = -b.vy;
b.y = (_ybar - _hbar / 2) * 2 -b.y;
_nreflect++;
}
}
}
private var _t : int = 0;
private function onEnterFrame(e : Event) : void
{
if(_t++ == 100){
appendBall();
_t = 0;
}
_xbar += algo();
draw();
progress();
}
// range {t: min: max: w: }
private function solvePath(cur : Number, maxv : Number, ranges : Array) : Object
{
if(ranges.length == 0){
return {min : cur, max : cur};
}
var range : Object;
var mostclose : Number = Number.MAX_VALUE;
for each(range in ranges){
if(mostclose > range.t)mostclose = range.t;
}
var rangemin : Number = cur - maxv * mostclose;
var rangemax : Number = cur + maxv * mostclose;
var updowns : Array = [];
for each(range in ranges){
var pos : Number;
pos = range.max + maxv * (range.t - mostclose);
if(pos >= rangemin && pos <= rangemax)updowns.push({pos : pos, w : -range.w});
pos = range.min - maxv * (range.t - mostclose);
if(pos >= rangemin && pos <= rangemax)updowns.push({pos : pos, w : range.w});
}
_tf.appendText("" + mostclose + "\t" + updowns.length + "\n");
if(updowns.length == 0){
return {min : cur, max : cur};
}
updowns.sortOn(["pos", "w"], [Array.NUMERIC, Array.NUMERIC | Array.DESCENDING]);
var maxp : Number = 0;
var maxrange : Object = {min : rangemin, max : updowns[0].pos};
var score : Number = 0;
for(var i : int = 0;i < updowns.length;i++){
var p : Object = updowns[i];
score += p.w;
// _tf.appendText("" + p.pos + "\t" + score + "\n");
if(maxp < score){
maxp = score;
var nextpos : Number = i + 1 < updowns.length ? updowns[i + 1].pos : rangemax;
maxrange = {min : p.pos, max : nextpos};
}
}
// maxrange.mostclose = mostclose;
return maxrange;
}
}
}