package com.seizure;
import android.util.Log;
import android.util.TimingLogger;
import java.util.Random;
class AI
{
private class ColorProfit{
int ColorIndex;
int Profit;
public ColorProfit(int colorIndex, int profit)
{
ColorIndex = colorIndex;
Profit = profit;
}
}
private static final String TAG = "AI";
private static final int MAX_AI_LEVEL = 9;
// private static final TimingLogger mTimingLogger = new TimingLogger(TAG,"AI.getColor");
private int mDimension;
private ColorProfit[] mColorProfits;
private int mNonZeroColorProfitsCount;
private int mColorsCount;
private CalculateMoveThread[] workers;
private int mRunningThreadsCount;
private Object sync = new Object();
private static final Random r = new Random();
public AI(int dimension, int[] colors)
{
mDimension = dimension;
mColorProfits = new ColorProfit[mDimension];
mColorsCount = colors.length;
initWorkers(mColorsCount);
}
private void initWorkers(int count)
{
workers = new CalculateMoveThread[count];
for(int i = 0; i < count; i++ )
{
workers[i] = new CalculateMoveThread();
}
}
public int getColor(Player p, int currentPlayerIndex,
int[][] gameFieldCellStep, int[][] gameFieldCellOwners, int[][] gameFieldCellColorIndexes)
{
// mTimingLogger.reset();
for(int i = 0; i< mColorsCount; i ++)
{
workers[i].init(onCalculateComplete, mDimension, p, currentPlayerIndex,
gameFieldCellStep.clone(), gameFieldCellOwners.clone(), gameFieldCellColorIndexes.clone(), i);
}
startThreads();
// mTimingLogger.dumpToLog();
return getColorIndex(p.AiLevel);
}
private void startThreads()
{
mRunningThreadsCount = mColorsCount;
// Log.d(TAG,"[startThreads] starting threads");
for(int i=0;i< mColorsCount; i++)
workers[i].start();
while(mRunningThreadsCount > 0)
{
Log.d(TAG, "[startThreads] working threads count: " + mRunningThreadsCount);
try
{
Thread.sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
private int getColorIndex(int aiLevel)
{
int profitIndex;
final int stupidness = mNonZeroColorProfitsCount*(MAX_AI_LEVEL - aiLevel)/MAX_AI_LEVEL;
sortProfits();
if(stupidness == 0)
profitIndex = mColorsCount - 1;
else
profitIndex = mColorsCount - 1 - r.nextInt(stupidness);
//Log.d(TAG, "[getColorIndex] aiLevel: " + aiLevel + ", profitIndex: " + profitIndex);
return mColorProfits[profitIndex].ColorIndex;
}
private void sortProfits()
{
ColorProfit t;
int firstNonZeroProfitIndex=-1;
for(int i=0; i< mColorsCount; i++)
{
for(int j=i+1;j<mColorsCount; j++)
{
if(mColorProfits[i].Profit > mColorProfits[j].Profit)
{
t = mColorProfits[i];
mColorProfits[i] = mColorProfits[j];
mColorProfits[j] = t;
}
}
if(mColorProfits[i].Profit > 0 && firstNonZeroProfitIndex == -1)
{
firstNonZeroProfitIndex = i;
}
}
mNonZeroColorProfitsCount = mColorsCount - firstNonZeroProfitIndex;
}
private CalculateMoveThread.CalculateCompleteListener onCalculateComplete = new CalculateMoveThread.CalculateCompleteListener(){
public void onComplete(long threadId, int profit, int colorIndex)
{
synchronized (sync)
{
mRunningThreadsCount -=1;
mColorProfits[colorIndex] = new ColorProfit(colorIndex, profit);
// Log.d(TAG,"thread "+threadId+" complete!"
// + " colorIndex=" + colorIndex
// + " profit=" + profit
// );
}
}
};
}
|