2009/10/17
FlashLite1.1:SLGの戦略AIを作る
距離移動コストと敵の強さから費用対効果を計算してそれぞれ行動します。
実装してませんが、複数ユニットで攻撃するようなチームプレイ戦略とかを
算出できるようになれば面白くなりそう。
zipファイル
※ちなみに as/init.as の
//playerAsCpu = "xooo";
のコメントをはずすと青軍を操作できます。
//thinkTarget.as
//攻撃のROI計算
targetBin = "";
_maxYummy = 0;
for(i = 1; i <= playerCount; i++ ) {
if (i != player) {
_units = eval("units" add i);
while (length(_units) > 0) {
_unitId = i * 1000 + ord(subString(_units, 1, 1)) - 0x80;
x = getProperty("map/unit" add _unitId, _x);
y = getProperty("map/unit" add _unitId, _y);
_unitHp = ord(subString(_units, 3, 1)) - 0x80;
_index = 1 + x + y * mapWidth;
_minCost = -1;
if (y > 0) {
_cost = ord(subString(costMap, _index - mapWidth, 1)) - 0x80;
if ((_cost >= 0) and ((_cost < _minCost) or (_minCost < 0))) {
_minCost = _cost;
s = mbChr(0x80 + x) add mbChr(0x80 + y - 1);
_direction = 1;
}
}
if (x < mapWidth-1) {
_cost = ord(subString(costMap, _index + 1, 1)) - 0x80;
if ((_cost >= 0) and ((_cost < _minCost) or (_minCost < 0))) {
_minCost = _cost;
s = mbChr(0x80 + x + 1) add mbChr(0x80 + y);
_direction = 2;
}
}
if (y < mapHeight-1) {
_cost = ord(subString(costMap, _index + mapWidth, 1)) - 0x80;
if ((_cost >= 0) and ((_cost < _minCost) or (_minCost < 0))) {
_minCost = _cost;
s = mbChr(0x80 + x) add mbChr(0x80 + y + 1);
_direction = 3;
}
}
if (x > 0) {
_cost = ord(subString(costMap, _index - 1, 1)) - 0x80;
if ((_cost >= 0) and ((_cost < _minCost) or (_minCost < 0))) {
_minCost = _cost;
s = mbChr(0x80 + x - 1) add mbChr(0x80 + y);
_direction = 4;
}
}
if (_minCost >= 0) {
_yummy = (unitHp/_unitHp)/(_minCost/unitMove+1)
if (_yummy > _maxYummy) {
_maxYummy = _yummy;
targetBin = mbChr(0x80 + i) add subString(_units, 1, 3) add s add mbChr(0x80 + _direction);
}
}else {
//攻撃不可
}
_units = subString(_units, 4);
}
}
}
//thinkCost.as
//コスト計算(マップ移動)
//-1 未調査 -1 囲まれて移動不可エリアか未調査エリア
//-2 距離が大きすぎ
//-3 超えられないもの
//-4 敵
_timer = getTimer() + 1000 / 12;
while((length(_stack) > 0) and (_timer > getTimer())) {
x = ord(subString(_stack, 1, 1)) - 0x80;
y = ord(subString(_stack, 2, 1)) - 0x80;
_cost = ord(subString(_stack, 3, 1)) - 0x80;
_direction = ord(subString(_stack, 4, 1)) - 0x80;
_stack = subString(_stack, 5);
_index = 1 + x + y * mapWidth;
i = ord(subString(costMap, _index, 1)) - 0x80;
//速度優先最適化
//if (i > -2) {
_cost += ord(subString(moveCostsByChip, ord(subString(fieldMap, _index, 1)) - 0x80, 1)) - 0x80;
if ((_cost < i) or (i == -1)) {
if (_cost > unitMove * 2) {
costMap = subString(costMap, 1, _index - 1 ) add mbChr(0x80 - 2) add subString(costMap, _index + 1);
}else {
costMap = subString(costMap, 1, _index - 1 ) add mbChr(0x80 + _cost) add subString(costMap, _index + 1);
moveMap = subString(moveMap, 1, _index - 1 ) add mbChr(0x80 + _direction) add subString(moveMap, _index + 1);
switch(false) {
case(_direction == 3):
if (y > 0) {
if (ord(subString(costMap, _index - mapWidth, 1)) - 0x80 > -2) {
_stack = _stack add mbChr(0x80 + x) add mbChr(0x80 + y - 1) add mbChr(0x80 + _cost) add mbChr(0x80 + 1);
}
}
case(_direction == 4):
if (x < mapWidth - 1) {
if (ord(subString(costMap, _index + 1, 1)) - 0x80 > -2) {
_stack = _stack add mbChr(0x80 + x + 1) add mbChr(0x80 + y) add mbChr(0x80 + _cost) add mbChr(0x80 + 2);
}
}
case(_direction == 1):
if (y < mapHeight - 1) {
if (ord(subString(costMap, _index + mapWidth, 1)) - 0x80 > -2) {
_stack = _stack add mbChr(0x80 + x) add mbChr(0x80 + y + 1) add mbChr(0x80 + _cost) add mbChr(0x80 + 3);
}
}
case(_direction == 2):
if (x > 0) {
if (ord(subString(costMap, _index - 1, 1)) - 0x80 > -2) {
_stack = _stack add mbChr(0x80 + x - 1) add mbChr(0x80 + y) add mbChr(0x80 + _cost) add mbChr(0x80 + 4);
}
}
}
}
}
//}
}