/*
* Copyright 2014 The Skfiy Open Association.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.skfiy.typhon.spi.pvp;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.apache.commons.lang3.ArrayUtils;
import org.skfiy.typhon.domain.FightGroup;
import org.skfiy.typhon.spi.war.FightObject;
import org.skfiy.typhon.spi.war.WarInfo;
import org.skfiy.typhon.util.FastRandom;
/**
*
* @author Kevin Zou <kevinz@skfiy.org>
*/
class PvpFindAttackGoal implements WarInfo.IFindAttackGoal {
private static final Random RANDOM = new FastRandom();
/**
*
*/
static final PvpFindAttackGoal INSTANCE = new PvpFindAttackGoal();
private final int[] ATTACKER_GOALS = {FightGroup.LEFT_PIONEER_POS,
FightGroup.RIGHT_PIONEER_POS,
FightGroup.COUNSELLOR_POS,
FightGroup.FORAGE_POS,
FightGroup.PRIMARY_POS};
@Override
public FightObject nextGoal(List<FightObject> fightObjects) {
return nextGoal(fightObjects, false);
}
@Override
public FightObject nextGoal(List<FightObject> fightObjects, boolean ran) {
if (ran) {
int t, s;
t = s = RANDOM.nextInt(fightObjects.size());
FightObject rs = null;
for (;;) {
rs = fightObjects.get(t);
if (!rs.isDead()) {
break;
}
t++;
if (t >= fightObjects.size()) {
t = 0;
}
if (t == (s - 1)) {
break;
}
}
return rs;
}
FightObject rs = null;
for (int goal : ATTACKER_GOALS) {
rs = fightObjects.get(goal);
if (!rs.isDead()) {
break;
}
}
return rs;
}
@Override
public List<FightObject> nextGoals(List<FightObject> fightObjects, int num) {
List<FightObject> results = new ArrayList<>(num);
int first = next(fightObjects);
results.add(fightObjects.get(first));
if (num >= 2) {
int[] indexes = nextIndexes(first);
shuffle(indexes);
FightObject fo;
for (int i : indexes) {
fo = fightObjects.get(i);
if (!fo.isDead()) {
results.add(fo);
if (results.size() >= num) {
break;
}
}
}
}
return results;
}
private int next(List<FightObject> fightObjects) {
FightObject fo;
for (int goal : ATTACKER_GOALS) {
fo = fightObjects.get(goal);
if (!fo.isDead()) {
return goal;
}
}
return -1;
}
private int[] nextIndexes(int first) {
int[] rs = new int[ATTACKER_GOALS.length - 1];
int i = 0;
for (int x : ATTACKER_GOALS) {
if (x != first) {
rs[i] = x;
i++;
}
}
return rs;
}
void shuffle(final int[] array) {
final Random r = new Random();
final int limit = array.length;
for (int i = 0; i < limit; ++i) {
swap(array, i, r.nextInt(limit));
}
}
void swap(final int[] array, final int i, final int j) {
int o = array[i];
array[i] = array[j];
array[j] = o;
}
}