bool AI::run() { realLight=(playerID())?player1Light():player0Light(); cout<<"Turn: "<<turnNumber()<<" Player: "<<playerID()<<" Light: "<<realLight<<endl; cout<<"Plants: "<<plants.size()<<endl; if(plants.size()<2) { return true; } //if the queue is empty if(que.empty()) { // cout<<"First time on this turn"<<endl; resetDataStructures(); buildQueue(); } //cout<<"Queue Size: "<<que.size()<<endl; //runs once return doActions(); /* while(!que.empty()) { que.pop(); } return true; */ //otherwise //return doActions(); /* while(!doActions()){}; return true; */ }
void TableProtoScene::ScoreBoard::renderRank() { PlayerRankList rankList = utils::calcRank(GameStatus::gameStat()); const ArgbColor color = (rankList[playerID()] == 1) ? ledColorRed : // トップは赤 (rankList[playerID()] == (GameStatus::gameStat()->chkGameType(SanmaT) ? 3 : 4) ? ledColorOrange : // ラスはオレンジ ledColorGreen); // その他は緑で表示 renderNumeral(RankPosX, RankPosY, rankList[playerID()], color); // その他は緑で表示 if ((myTimer.currTime() % 1000000 < 500000) && (GameStatus::gameStat()->CurrentPlayer.Active == playerID())) renderNumeral(RankPosX, RankPosY, digitDecimal, color); }
Unit* AI::findNearestTarget(Bot& actor) { int x=actor.x(); int y=actor.y(); int size = actor.size(); int bestDist = INT_MAX; Unit* target=NULL; // If it can attack or it cannot heal //bool attacker = actor.damage()>0 || actor.buildRate()==0; bool attacker =true; // loops through all bots for(unsigned int b=0;b<bots.size();b++) { // if I want to attack, and it is an enemy or I want to heal and its an ally if((attacker && (playerID()!=bots[b].owner()) || !(attacker && (playerID()==bots[b].owner())))) { int tempDist = distance(x,y,size, bots[b].x(),bots[b].y(),bots[b].size()); if(tempDist < bestDist) { bestDist=tempDist; target=&(bots[b]); } } } // if I am an attacker, include walls and frames if(attacker) { for(unsigned int w=0;w<walls.size();w++) { int tempDist = distance(x,y,size, walls[w].x(),walls[w].y(),1); if(tempDist < bestDist) { bestDist=tempDist; target=&(walls[w]); } } for(unsigned int f=0;f<frames.size();f++) { if(frames[f].owner() != playerID()) { int tempDist = distance(x,y,size, frames[f].x(),frames[f].y(),frames[f].size()); if(tempDist < bestDist) { bestDist=tempDist; target=&(frames[f]); } } } } return target; }
void AI::objectCheck() { cout<<"--Base AI variables--"<<endl; cout<<"turnNumber\t"<<turnNumber()<<endl; ///Player Number; either 0 or 1 cout<<"playerID\t"<<playerID()<<endl; ///What number game this is for the server cout<<"gameNumber\t"<<gameNumber()<<endl; ///Player 0's time remaining cout<<"player0Time\t"<<player0Time()<<endl; ///Player 1's time remaining cout<<"player1Time\t"<<player1Time()<<endl; ///Player 0's name cout<<"player0Name\t"<<player0Name()<<endl; ///Player 1's name cout<<"player1Name\t"<<player1Name()<<endl; ///The cost of a pirate cout<<"pirateCost\t"<<pirateCost()<<endl; ///The cost of a ship cout<<"shipCost\t"<<shipCost()<<endl; cout<<"portCost\t"<<portCost()<<endl; cout<<"boardX\t"<<boardX()<<endl; cout<<"baordY\t"<<boardY()<<endl; cout<<"--Object counts--"<<endl; cout<<"Pirates : "<<pirates.size()<<endl; displayPirates(); cout<<"Ports : "<<ports.size()<<endl; displayPorts(); cout<<"Ships : "<<ships.size()<<endl; displayShips(); cout<<"Tiles : "<<tiles.size()<<endl; displayTiles(); cout<<"Treasure: "<<treasures.size()<<endl; // displayTreasure(); }
void AI::resetDataStructures() { //ignore the boundaries for(unsigned int x=1;x<canSpawnHere.size()-1;x++) { for(unsigned int y=1;y<canSpawnHere[x].size()-1;y++) { //return them all to true canSpawnHere[x][y]=true; canSpreadHere[x][y]=true; } } //for every plant for(unsigned int i=0;i<plants.size();i++) { //you can't build here canSpawnHere[plants[i].x()+1][plants[i].y()+1]=false; //if its my plant if(plants[i].ownerID() == playerID()) { canSpreadHere[plants[i].x()+1][plants[i].y()+1] = false; } } notActing.resize(plants.size()); for(unsigned int i=0;i<notActing.size();i++) { notActing[i]=false; } }
void TableProtoScene::ScoreBoard::Render() { #ifndef _WIN32 if (!initialized) { objInit(); initialized = true; } #endif /*_WIN32*/ RECT rect = {0, 0, PanelWidth, PanelHeight}; SpriteRenderer::instantiate(myDevice)->ShowSprite(texture, (int)xpos, (int)ypos, PanelWidth, PanelHeight, 0xffffffff, &rect, 0, 0, &myMatrix); if ((playerID() >= 0) && (playerID() < (GameStatus::gameStat()->chkGameType(SanmaT) ? 3 : 4))) { renderWind(); renderRank(); renderScore(); renderName(); } }
//This function is run once, before your first turn. void AI::init() { //get the opponent's ID if(playerID() == 0) { enemyAI_ID = 1; } else { enemyAI_ID = 0; } }
//This function is run once, before your first turn. void AI::init() { //Determines which player you are if(playerID() == 0) { enemyAI_ID = 1; } else { enemyAI_ID = 0; } }
std::tuple<unsigned, unsigned, signed, signed> TableProtoScene::ScoreBoard::scoreInfo(ScoreMode scoreMode) { if (scoreMode == scoreChip) { const int& chipAmount = GameStatus::gameStat()->Player[playerID()].playerChip; return std::make_tuple(abs(chipAmount), 0, 0, (chipAmount > 0) ? 1 : (chipAmount < 0) ? -1 : 0); } else { const LargeNum playerScoreDiff = GameStatus::gameStat()->Player[playerID()].PlayerScore - GameStatus::gameStat()->statOfMine().PlayerScore; const LargeNum* const score = (scoreMode == scoreDiff) ? &playerScoreDiff : &(GameStatus::gameStat()->Player[playerID()].PlayerScore); const int digit[10] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; int sign; if (*score > LargeNum::fromInt(0)) sign = 1; else if (*score < LargeNum::fromInt(0)) sign = -1; else sign = 0; for (int i = DigitGroups - 1; i >= 0; --i) { for (int j = ((i == DigitGroups - 1) ? 9 : 7); j >= 0; --j) { if ((GameStatus::gameStat()->gameType & RichiMJ) && (i == 0) && (j == 4)) { return std::make_tuple(abs(score->digitGroup[0] / 100), 0, 0, sign); } else if ((GameStatus::gameStat()->gameType & GuobiaoMJ) && (i == 0) && (j == 2)) { return std::make_tuple(abs(score->digitGroup[0]), 0, 0, sign); } else if (score->digitGroup[i] / digit[j]) { unsigned digitCode = i * 8 + j; unsigned digits; if (j >= 2) { digits = abs(score->digitGroup[i] / digit[j - 2]); } else { assert(i > 0); digits = abs(score->digitGroup[i] * digit[2 - j]) + abs(score->digitGroup[i - 1] / digit[j + 6]); } if (digitCode % 4 == 3) return std::make_tuple(digits, digitCode / 4 + 1, -1, sign); else return std::make_tuple(digits, digitCode / 4, digitCode % 4, sign); } } } } throw _T("ScoreBoard::scoreInfo() : Unexpected control flow"); }
QString GameDBStorage::GetSetClause(MSqlBindings &bindings) const { QString playerID(":SETPLAYERID"); QString colTag(":SET" + GetColumnName().toUpper()); QString query("gameplayerid = " + playerID + ", " + GetColumnName() + " = " + colTag); bindings.insert(playerID, parent.getGamePlayerID()); bindings.insert(colTag, user->GetDBValue()); return query; }
void TableProtoScene::ScoreBoard::renderWind() { if ((myTimer.currTime() % 1000000 >= 500000) && (GameStatus::gameStat()->CurrentPlayer.Active == playerID())) return; // ツモ番の時は表示を点滅させる const seatAbsolute wind = GameStatus::gameStat()->playerwind(playerID()); if (GameStatus::gameStat()->chkGameType(Sanma4) && (wind == sNorth)) return; // 四人三麻の時の抜け番は何も表示しないようにする RECT rect = { static_cast<int32_t>(WindCharX + WindCharWidth * ((int)wind )), WindCharY, static_cast<int32_t>(WindCharX + WindCharWidth * ((int)wind + 1)), WindCharY + WindCharHeight }; SpriteRenderer::instantiate(myDevice)->ShowSprite(texture, (int)xpos + WindPosX, (int)ypos + WindPosY, WindCharWidth, WindCharHeight, (wind == sEast) ? ledColorRed : ledColorGreen, // 「東」のみ赤で、それ以外を緑で表示すればわかりやすいと思うのでそうする &rect, 0, 0, &myMatrix); }
//This function is called each time it is your turn. //Return true to end your turn, return false to ask the server for updated information. bool AI::run() { for(int i = 0; i < bots.size(); i++) { if(bots[i].owner() == playerID()) { bots[i].move(direction[rand()%4]); } if(bots[i].buildRate()) { bots[i].build(types[rand() % types.size()], bots[i].x() + 1, bots[i].y(), 1); } } return true; }
void TableProtoScene::ScoreBoard::renderScore() { unsigned digits, unitcode; signed decimalPos, sign; ArgbColor color; ScoreMode scoreMode = getScoreMode(); std::tie(digits, unitcode, decimalPos, sign) = scoreInfo(scoreMode); switch (scoreMode) { case scorePoints: if (utils::isAboveBase(GameStatus::gameStat(), playerID())) color = ledColorRed; // 浮いていれば赤 else color = ledColorGreen; // 沈みは緑 break; case scoreDiff: case scoreChip: if (sign == 1) color = ledColorRed; else if (sign == -1) color = ledColorGreen; else color = ledColorOrange; break; } if ((scoreMode != scoreDiff) || (playerID() != GameStatus::gameStat()->PlayerID)) { if (sign == 1) renderNumeral(ScorePosX - NumCharWidth , ScorePosY, digitPlus , color); else if (sign == -1) renderNumeral(ScorePosX - NumCharWidth , ScorePosY, digitMinus , color); if ((unitcode != 0) || (digits / 100)) renderNumeral(ScorePosX , ScorePosY, digits / 100, color); if ((unitcode != 0) || (digits / 100) || (digits % 100 / 10)) renderNumeral(ScorePosX + NumCharWidth , ScorePosY, digits % 100 / 10 , color); renderNumeral( ScorePosX + NumCharWidth * 2, ScorePosY, digits % 10 , color); if (unitcode != 0) renderNumeral(ScorePosX + NumCharWidth * decimalPos, ScorePosY, digitDecimal, color); if ((GameStatus::gameStat()->gameType & RichiMJ) && (scoreMode != scoreChip)) renderScoreUnit(unitcode, color); } }
//RUSKI FUNCTIONS void AI::update() { cout << "CLEARING CREATURE ARRAYS" << endl; myCreatures.erase(myCreatures.begin(), myCreatures.end()); enemyCreatures.erase(enemyCreatures.begin(), enemyCreatures.end()); cout << "BUILDING CREATURE ARRAYS" << endl; for(int i = 0; i < creatures.size(); i++) { //MY CREATURES if( creatures[i].owner() == playerID() ) { myCreatures.push_back( RuskiCre(&creatures[i]) ); } //ENEMY CREATURES else { enemyCreatures.push_back( &creatures[i] ); } } cout << "ENDED CREATURE ARRAY CREATION" << endl; }
//This function is called each time it is your turn. //Return true to end your turn, return false to ask the server for updated information. bool AI::run() { cout<<"Turn: "<<turnNumber()<<endl; vector<int> builders, uncombined, actors; for(unsigned int b=0;b<bots.size();b++) { // if it is my bot if(bots[b].owner()==playerID() && bots[b].partOf()==0) { bots[b].talk( "Hi there, I'm you're robot" ); if(bots[b].buildRate()>0 && builders.size()<4 && bots[b].size()==1) { builders.push_back(b); } else if(bots[b].size()==1) { uncombined.push_back(b); } else { actors.push_back(b); } } } // starting builders if(builders.size()<4) { for(unsigned int b=0;b<builders.size();b++) { int x=bots[builders[b]].x()+xMod[playerID()*2 +1]; int y=bots[builders[b]].y()+yMod[playerID()*2 +1]; bots[builders[b]].build(types[1], x, y, 1); } } // if there are 4 builders if(builders.size()==4) { // check if the builders are in their correct locations for(unsigned int b=0;b<builders.size();b++) { int dir=1; if(bots[builders[b]].y()==9) { bots[builders[b]].move("up"); } else if(bots[builders[b]].y()==10) { bots[builders[b]].move("down"); } if(bots[builders[b]].y()==8) { dir = 2; } else if(bots[builders[b]].y()==11) { dir = 0; } int x=bots[builders[b]].x()+xMod[dir]; int y=bots[builders[b]].y()+yMod[dir]; if(bots[builders[b]].actions()>0) { // builds 4 different guys bots[builders[b]].build(types[(built/4+b)%types.size()], x, y, 1); built++; } } } if(uncombined.size()==4) { /* for(unsigned int b=0;b<uncombined.size();b++) { if(bots[uncombined[b]].y()==9) { bots[uncombined[b]].move("down"); } else if(bots[builders[b]].y()==10) { bots[builders[b]].move("down"); } } */ bots[uncombined[0]].combine(bots[uncombined[1]],bots[uncombined[2]],bots[uncombined[3]]); } // Handles all of the non builders for(unsigned int b=0;b<actors.size();b++) { Unit* target = findNearestTarget(bots[actors[b]]); moveTowardsTarget(bots[actors[b]], *target); if(inRange(bots[actors[b]], *target)) { cout<<"In RANGE!"<<endl; unload(bots[actors[b]],*target); } } return true; }
//TODO Test if you can build something and act on it in one turn void AI::buildQueue() { for(unsigned int i=0;i<plants.size();i++) { //cout<<"Working on plant: "<<i<<endl; //cout<<"HP: "<<plants[i].health()<<endl; //if its my plant and it can do something if(plants[i].ownerID() == playerID() && plants[i].canAct()) { //Spam talk string message="This is plant[" + plants[i].objectID(); message+="] owned by Player: "+plants[i].ownerID(); message+=" on turn "+turnNumber(); //char * temp = message.c_str(); plants[i].talk((char*)(message.c_str())); if(i==0) { plants[i].talk((char*)("Did calling talk twice append or replace the usual string?")); } //if you don't have a leaf if(!plants[i].leaf()) { if(canDo(i,LEAF)) { //a place to try growing a leaf space sp(plants[i].x(), plants[i].y(),i,LEAF); sp.rating=evalTree(leafTree,sp); que.push(sp); } /* else { space sp(plants[i].x(), plants[i].y(),i,LEAF); cout<<"CANT DO: "; sp.display(); } */ } //if you want to generate light else { //cout<<"Pushing NOOP"<<endl; space sp(plants[i].x(), plants[i].y(),i,NOOP); sp.rating=evalTree(noopTree,sp); //que.push(sp); } //if it doesn't have a root if(!plants[i].root()) { //I can do a root if(canDo(i,ROOT)) { //a place to try growing a root space sp(plants[i].x(), plants[i].y(),i,ROOT); sp.rating=evalTree(rootTree,sp); que.push(sp); } /* else { space sp(plants[i].x(), plants[i].y(),i,ROOT); cout<<"CANT DO: "; sp.display(); } */ } //for expansion else { if(canDo(i,SPREAD)) { for(unsigned int r=0;r<4;r++) { space sp(plants[i].x()+xoff[r], plants[i].y()+yoff[r],i,SPREAD); if(canSpawnHere[sp.x+1][sp.y+1]) { sp.rating=evalTree(rootTree,sp); que.push(sp); } } } } //if it doesn't have a flower and can make one if(!plants[i].flower()) { if(canDo(i,FLOWER)) { //a place to try growing a flower space sp(plants[i].x(), plants[i].y(),i,FLOWER); sp.rating=evalTree(flowerTree,sp); que.push(sp); } } //if you have a flower and can spawn else { if(canDo(i,SPAWN)) { for(unsigned int r=0;r<4;r++) { space sp(plants[i].x()+xoff[r], plants[i].y()+yoff[r],i,SPAWN); if(canSpawnHere[sp.x+1][sp.y+1]) { sp.rating=evalTree(spawnTree,sp); que.push(sp); } } } } } } // //cout<<"Bot of Build QUE"<<endl; }
double AI::DLMM(boardState* nodeOrig, int depth, int QS_Depth, bool maximizingPlayer, double alpha, double beta){ bool terminal = false; double newAlpha = alpha; double newBeta = beta; double newVal = alpha; int moverid = playerID(); map<string, int>::iterator it1; if (!maximizingPlayer){ if (moverid == 0){ moverid = 1; } else{ moverid = 0; } } vector<fakePiece> blank; if (kingInCheckmate(nodeOrig, moverid)){ double retVal = calcHeuristic(moverid, nodeOrig, blank); return (retVal); } else if ((depth == 0 && nodeOrig->QS_State == false) || (depth == 0 && QS_Depth == 0)){ double retVal = calcHeuristic(moverid, nodeOrig, blank); return (retVal); } else if (maximizingPlayer){ newBeta = beta; newAlpha = alpha; newVal = alpha; possibleMovesStruct* possibleMovesMax = new possibleMovesStruct; allPossibleMoves(nodeOrig, possibleMovesMax, moverid); if (possibleMovesMax->availiableMoves.size() > 0){ int size = possibleMovesMax->availiableMoves.size() - 1; for (int i = size; i >= 0; i--){ boardState* nodeNew = new boardState; *(nodeNew) = *(nodeOrig); int fileFrom = possibleMovesMax->availiableMoves.top().fileFrom; int rankFrom = possibleMovesMax->availiableMoves.top().rankFrom; int fileTo = possibleMovesMax->availiableMoves.top().fileTo; int rankTo = possibleMovesMax->availiableMoves.top().rankTo; nodeNew->unofficialMove(fileFrom, rankFrom, fileTo, rankTo, moverid, 0, 2); if (depth != 0){ newVal = DLMM(nodeNew, depth, QS_Depth - 1, false, newAlpha, newBeta); } else{ newVal = DLMM(nodeNew, depth - 1, QS_Depth, false, newAlpha, newBeta); } if (newVal <= newAlpha){ // Fail low possibleMovesMax->availiableMoves.pop(); } else if (newVal >= newBeta){ //Fail high -> prune because fail high on max size = -1; it1 = myHistoryTable.find(possibleMovesMax->availiableMoves.top().historyTableVal); while (possibleMovesMax->availiableMoves.size() > 0){ possibleMovesMax->availiableMoves.pop(); } } else{ // New best value/alpha newAlpha = newVal; it1 = myHistoryTable.find(possibleMovesMax->availiableMoves.top().historyTableVal); possibleMovesMax->availiableMoves.pop(); } delete nodeNew; } delete possibleMovesMax; //History table updates and inserts int currentCount = it1->second; string currentString = it1->first; myHistoryTable.erase(currentString); myHistoryTable[currentString] = currentCount + 1; return newAlpha; } else{ return alpha; } } else{ //Min player newAlpha = alpha; newBeta = beta; if (alpha != 0){ newBeta = alpha; } else{ newBeta = 1000; } newVal = 0; possibleMovesStruct* possibleMovesMax = new possibleMovesStruct; allPossibleMoves(nodeOrig, possibleMovesMax, moverid); if (possibleMovesMax->availiableMoves.size() > 0){ int size = possibleMovesMax->availiableMoves.size() - 1; for (int i = size; i >= 0; i--){ boardState* nodeNew = new boardState; *(nodeNew) = *(nodeOrig); int fileFrom = possibleMovesMax->availiableMoves.top().fileFrom; int rankFrom = possibleMovesMax->availiableMoves.top().rankFrom; int fileTo = possibleMovesMax->availiableMoves.top().fileTo; int rankTo = possibleMovesMax->availiableMoves.top().rankTo; nodeNew->unofficialMove(fileFrom, rankFrom, fileTo, rankTo, moverid, 0, 2); if (depth == 0){ newVal = DLMM(nodeNew, depth, QS_Depth - 1, true, newAlpha, newBeta); } else{ newVal = DLMM(nodeNew, depth - 1, QS_Depth, true, newAlpha, newBeta); } if (newVal <= newAlpha){ // Fail low on min -> prune size = -1; it1 = myHistoryTable.find(possibleMovesMax->availiableMoves.top().historyTableVal); while (possibleMovesMax->availiableMoves.size() > 0){ possibleMovesMax->availiableMoves.pop(); } } else if (newVal >= newBeta){ //Fail high on min -> dont use this one possibleMovesMax->availiableMoves.pop(); } else{ //We found a new value which is lower than the highest beta newBeta = newVal; it1 = myHistoryTable.find(possibleMovesMax->availiableMoves.top().historyTableVal); possibleMovesMax->availiableMoves.pop(); } delete nodeNew; } delete possibleMovesMax; //History table updates and inserts int currentCount = it1->second; string currentString = it1->first; myHistoryTable.erase(currentString); myHistoryTable[currentString] = currentCount + 1; return (newBeta); } else{ return (beta); } } }
void AI::IDDLMM(boardState* nodeOrig, int depth, int QS_Depth, bool maximizingPlayer, double a, double b){ double bestVal = 0; //Tracks best heuristic values calculated yet int moverid = playerID(); //The player moving is us, so call playerID() to return our playerID int fileFromBest, rankFromBest, fileToBest, rankToBest; //The best moves to and from coordinates clock_t t; //Used to keep track offthe time we started at clock_t t2; // Used for tracking the duration of the current depth clock_t t3; vector<double> time; //Holds the times it took for each level of depth we search in order to calculate future depths double estimatedTime; possibleMovesStruct* possibleMovesMax = new possibleMovesStruct; allPossibleMoves(nodeOrig, possibleMovesMax, moverid); //Stores all possible moves for the given boardstate into possibleMovesMax map<string, int>::iterator it1; t = clock(); //Time we start the algorithm if (possibleMovesMax->availiableMoves.size() > 0){ for (int i = 1; i <= depth; i++){ delete possibleMovesMax; possibleMovesMax = new possibleMovesStruct; allPossibleMoves(nodeOrig, possibleMovesMax, moverid); if (possibleMovesMax->availiableMoves.size() > 0){ //Calculating time for this depth t2 = clock(); for (int j = possibleMovesMax->availiableMoves.size() - 1; j >= 0; j--){ double newVal; boardState* nodeNew = new boardState; *(nodeNew) = *(nodeOrig); int fileFrom = possibleMovesMax->availiableMoves.top().fileFrom; int rankFrom = possibleMovesMax->availiableMoves.top().rankFrom; int fileTo = possibleMovesMax->availiableMoves.top().fileTo; int rankTo = possibleMovesMax->availiableMoves.top().rankTo; if (!repeatedMovesLoss(fileFrom, rankFrom, fileTo, rankTo)){ nodeNew->unofficialMove(fileFrom, rankFrom, fileTo, rankTo, moverid, 0, 2); newVal = DLMM(nodeNew, i - 1, QS_Depth, false, bestVal, b); } else{ newVal = bestVal; possibleMovesMax->availiableMoves.pop(); } if (newVal <= bestVal){ possibleMovesMax->availiableMoves.pop(); // Move on } else{ bestVal = newVal; it1 = myHistoryTable.find(possibleMovesMax->availiableMoves.top().historyTableVal); fileFromBest = fileFrom; rankFromBest = rankFrom; fileToBest = fileTo; rankToBest = rankTo; possibleMovesMax->availiableMoves.pop(); } delete nodeNew; possibleMovesMax->availiableMoves.pop(); } //History table updates and inserts int currentCount = it1->second; string currentString = it1->first; myHistoryTable.erase(currentString); myHistoryTable[currentString] = currentCount + 1; /* // Time Heuristic area */ //End time for this depth -> pushes it on the time vector t2 = clock() - t2; double tempTime = ((double)t2 / CLOCKS_PER_SEC); //Time in sec double estTimePerNode; time.push_back(tempTime); double estBranch; if (time.size() > 3){ for (int n = time.size() - 1; n > 2; n--){ //Adds up the factor difference between the times //i.e. 15 sec turn 1 45 sec turn 2 135 sec turn 3 // => 0+ 135/45 = 3 + 45/15 = 6 estBranch += time[n] / time[n - 1]; } // Dividing by the number of calculations done to get us an estimated branching factor estBranch = (estBranch / (time.size() - 3)); for (int n = time.size() - 1; n >= 2; n--){ //Estimates the time per node by taking the time for a specific level // and dividing it by the branching factor ^ branch level it was at estTimePerNode += time[n] / (pow(estBranch, n + 1)); } //Divides by the number of calculations done / the size of the time array to get an average estTimePerNode = (estTimePerNode / (time.size() - 2)); // Gets the estimated time for the next layer estimatedTime = (estTimePerNode)* pow(estBranch, i + 1); t3 = clock() - t; double timeSinceStart = ((double)t3 / CLOCKS_PER_SEC); //If we have spent more than x seconds on this move then quit where x is a scaling value from 1 to 5 based on time left double timeToSpend = 4 * (double)(((players[moverid].time()) / 900)) + 1; if (t3 >= timeToSpend){ i = depth + 1; } //If making the next move is estimated to take longer than x seconds for this turn then quit and return // where x is a scaling value from 1 to 5 based on time left else if (timeSinceStart + estimatedTime >= (timeToSpend + .5)){ i = depth + 1; } estimatedTime = 0; estTimePerNode = 0; estBranch = 0; } else{ //Used for depths < 4 // Estimates that the time will be the time it took for this round * the number of availiable moves // as we assume here the branching factor will be about the same estimatedTime = (tempTime * (possibleMovesMax->availiableMoves.size())); t3 = clock() - t; double timeSinceStart = ((double)t3 / CLOCKS_PER_SEC); double timeToSpend = 4 * (double)(players[moverid].time() / 900) + 1; //If we have spent more than x seconds on this move then quit where x is a scaling value from 1 to 5 based on time left if (timeSinceStart >= timeToSpend){ i = depth + 1; } //If making the next move is estimated to take longer than x seconds for this turn then quit and return // where x is a scaling value from 1 to 5 based on time left else if (timeSinceStart + estimatedTime >= (timeToSpend + .5)){ i = depth + 1; } } } for (int i = 0; i < pieces.size(); i++){ //Make the move if (pieces[i].file() == fileFromBest && pieces[i].rank() == 9 - rankFromBest){ pieces[i].move(fileToBest, 9 - rankToBest, int('Q')); i = pieces.size(); } } } } else{ //Error - do an illegal move and view log Piece piecetoMove; piecetoMove = pieces[0]; piecetoMove.move(50, 50, int('Q')); } return; }
//This function is called each time it is your turn. //Return true to end your turn, return false to ask the server for updated information. bool AI::run() { Fish* coolFish = getFish(0, 0, fishes); if(coolFish != NULL) { coolFish->carryingWeight(); } for(int i = 0;i < tiles.size();i++) { if(tiles[i].owner() == playerID() && getFish(tiles[i].x(), tiles[i].y(), fishes) == NULL) { for(int p = 0;p<species.size(); p++) { if(species[p].season() == currentSeason()) { if(players[playerID()].spawnFood() >= species[p].cost() && tiles[i].hasEgg() == false) { species[p].spawn(tiles[i].x(), tiles[i].y()); } } } } } for(int i = 0;i < fishes.size();i++) { if(fishes[i].owner() == playerID()) { int x = fishes[i].x(); int y = fishes[i].y(); if(fishes[i].x() >= 1) { if(getTile(x - 1, y, mapHeight(), tiles).trashAmount() > 0 && fishes[i].carryingWeight() + 1 <= fishes[i].carryCap()) { fishes[i].pickUp(x - 1, y, 1); } } if(fishes[i].carryingWeight() > 0) { if(fishes[i].x() < mapWidth()/2 - boundLength() - 1) { if(fishes[i].y() != 0) { if(getTile(x,y - 1,mapHeight(),tiles).owner() == 2 && getFish(x,y + 1,fishes) == NULL) { fishes[i].drop(x, y - 1, fishes[i].carryingWeight()); } } else { if(getTile(x,y + 1,mapHeight(),tiles).owner() == 2 && getFish(x,y + 1,fishes) == NULL) { fishes[i].drop(x, y + 1, fishes[i].carryingWeight()); } } } } if(fishes[i].x() >= 1) { if(getTile(x - 1,y,mapHeight(),tiles).owner() != enemyAI_ID && getTile(x - 1,y,mapHeight(),tiles).trashAmount() == 0) { if(getFish(x - 1, y, fishes) == NULL && getTile(x - 1, y, mapHeight(), tiles).hasEgg() == false) { fishes[i].move(x - 1,y); } } } } } return true; }
//This function is called each time it is your turn. //Return true to end your turn, return false to ask the server for updated information. bool AI::run() { cout << "Turn " << turnNumber() << endl; // Future: tell the map to update itself (saving history) _map = Map(this); // Update convenience data structures. myBases.erase(myBases.begin(),myBases.end()); for (vector<Base>::iterator base = bases.begin(); base != bases.end(); base++) { if ((*base).owner() == playerID()) myBases.push_back(*base); } myViruses.erase(myViruses.begin(),myViruses.end()); for (vector<Virus>::iterator virus = viruses.begin(); virus != viruses.end(); virus++) { if ((*virus).owner() == playerID()) myViruses.push_back(*virus); } if (_config[string("preset")].compare(string("Coverage"))) { players[playerID()].talk((char*)"The General: 0.52 (Coverage)"); } else { players[playerID()].talk((char*)"The General: 0.52 (2xLem,1Rand)"); } // Let the General command the army. Commander_Washington.Command(); // The Old Way // // virus coverage strategy // build_shells(this,map); // // fewest spawns // distribute_base_spawning(this,map); // // loop through all of the bases // for(int i=0;i<bases.size();i++) // { // // check if you own that base // if(bases[i].owner() == playerID()) // { // // check to see if you have enough cycles to spawn a level 0 virus // if(baseCost() <= players[playerID()].cycles()) // { // // spawn a level 0 virus at that base // bases[i].spawn(0); // } // } // } // // loop through all of the viruses // for(int i=0;i<viruses.size();i++) // { // // if you own that virus // if(viruses[i].owner() == playerID()) // { // // if the tile you want to move to is NOT a wall // if(getTileAtLocation(viruses[i].x()+1, viruses[i].y()).owner() != 3) // { // // move the virus // viruses[i].move(viruses[i].x()+1, viruses[i].y()); // } // } // } // End your turn return true; }
//This function is called each time it is your turn. //Return true to end your turn, return false to ask the server for updated information. bool AI::run() { //Iterate through every creature for(int ii = 0; ii < creatures.size(); ii++) { //if I own the creature if (creatures[ii].owner() == playerID()) { /* roles 0 = herbivore 1 = carnivore 2 = breeder */ int role; // if herbivorism > carnivorism and has not much energy if (creatures[ii].herbivorism() > creatures[ii].carnivorism()) { if (creatures[ii].energy() < energyPerTurn() * 5) { // if the creature has enough energy to survive role = 2; // time to get kinky } else { // if the creature doesn't have much energy role = 0; // must get noms } } else if (creatures[ii].herbivorism() < creatures[ii].carnivorism()) { if (creatures[ii].energy() < energyPerTurn() * 5) { // if the creature has enough energy to survive role = 2; // time to get kinky } else { // if the creature doesn't have much energy role = 1; // must get noms } } //if (role == 0) { int plantLeft = getPlantAtLocation(creatures[ii].x() + 1, creatures[ii].y()); int plantTop = getPlantAtLocation(creatures[ii].x(), creatures[ii].y() - 1); int plantRight = getPlantAtLocation(creatures[ii].x() - 1, creatures[ii].y()); int plantDown = getPlantAtLocation(creatures[ii].x(), creatures[ii].y() + 1); if (plantLeft == 1 && creatures[ii].energy() < (5 * energyPerTurn()) && creatures[ii].canEat() == 1) { creatures[ii].eat(creatures[ii].x() + 1, creatures[ii].y()); } else if (plantTop == 1 && creatures[ii].energy() < (5 * energyPerTurn()) && creatures[ii].canEat() == 1) { creatures[ii].eat(creatures[ii].x(), creatures[ii].y() - 1); } else if (plantRight == 1 && creatures[ii].energy() < (5 * energyPerTurn()) && creatures[ii].canEat() == 1) { creatures[ii].eat(creatures[ii].x() - 1, creatures[ii].y()); } else if (plantDown == 1 && creatures[ii].energy() < (5 * energyPerTurn()) && creatures[ii].canEat() == 1) { creatures[ii].eat(creatures[ii].x(), creatures[ii].y() + 1); } else { switch((rand() % 3) + 1) { case 0: // left creatures[ii].move(creatures[ii].x() + 2, creatures[ii].y()); break; case 1: // up creatures[ii].move(creatures[ii].x(), creatures[ii].y() - 2); break; case 2: // right creatures[ii].move(creatures[ii].x() - 2, creatures[ii].y()); break; case 3: // down creatures[ii].move(creatures[ii].x(), creatures[ii].y() + 2); break; } } } if (creatures[ii].movementLeft() > 2) { return false; } /* //check if there is a plant to that creature's left int plantIn = getPlantAtLocation(creatures[ii].x() + 1, creatures[ii].y()); //if there is no plant to my left, or there is a plant of size 0, and there is no creature to my left if ((plantIn == -1 || (plantIn != 1 && plants[plantIn].size() == 0)) && getCreatureAtLocation(creatures[ii].x() + 1, creatures[ii].y()) == -1) { //if x is in the range of the map, and y is in the range of the map if(0 <= creatures[ii].x() + 1 && creatures[ii].x() + 1<mapWidth() && 0 <= creatures[ii].y() && creatures[ii].y() < mapHeight()) { //if I have ennough health to move, and have movment left if (creatures[ii].currentHealth() > healthPerMove() && creatures[ii].movementLeft() > 0) { //move creature to the left by incrementing its x cooridinate, and not changing its y creatures[ii].move(creatures[ii].x() + 1,creatures[ii].y()); } } } //check if there is a plant to my left plantIn = getPlantAtLocation(creatures[ii].x()+1,creatures[ii].y());*/ /* //check if there is a creature to my left int creatIn = getCreatureAtLocation(creatures[ii].x()+1,creatures[ii].y()); //if there is a plant to my left, and its size is > 0, and this creature has not already eaten this turn if (plantIn != -1 && plants[plantIn].size()>0 && creatures[ii].canEat()==1) { //eat the plant, using its x and y creatures[ii].eat(plants[plantIn].x(),plants[plantIn].y()); } //else if there is a creature to my left, and it is not my creature and this creature has not eaten yet else if (creatIn!=-1 && creatures[creatIn].owner()!=playerID() && creatures[ii].canEat()==1) { //take a bite out of this creature creatures[ii].eat(creatures[creatIn].x(),creatures[creatIn].y()); } //else if there is a creature to my left, and it is my creature, and neither has bred this turn else if (creatIn!=-1 && creatures[creatIn].owner()==playerID() && creatures[ii].canBreed()==1 && creatures[creatIn].canBreed()==1) { //if both creatures have enough health to breed if (creatures[ii].currentHealth()>healthPerBreed() && creatures[creatIn].currentHealth()>healthPerBreed()) { //breed with this creature creatures[ii].breed(creatures[creatIn]); } }*/ } } return true; }
QTSS_Error LogRequest(QTSS_ClientSessionObject inClientSession, QTSS_RTSPSessionObject inRTSPSession, QTSS_CliSesClosingReason *inCloseReasonPtr) { static StrPtrLen sUnknownStr(sVoidField); static StrPtrLen sTCPStr("TCP"); static StrPtrLen sUDPStr("UDP"); //Fetch the URL, user agent, movielength & movie bytes to log out of the RTP session enum { eTempLogItemSize = 256, // must be same or larger than others eURLSize = 256, eUserAgentSize = 256, ePlayerIDSize = 32, ePlayerVersionSize = 32, ePlayerLangSize = 32, ePlayerOSSize = 32, ePlayerOSVersSize = 32, ePlayerCPUSize = 32 }; char tempLogItemBuf[eTempLogItemSize] = { 0 }; StrPtrLen tempLogStr(tempLogItemBuf, eTempLogItemSize - 1); // // Check to see if this session is closing because authorization failed. If that's // the case, we've logged that already, let's not log it twice UInt32 theLen = 0; UInt32* authorizationFailed = NULL; (void)QTSS_GetValuePtr(inClientSession, sLoggedAuthorizationAttrID, 0, (void**)&authorizationFailed, &theLen); if ((authorizationFailed != NULL) && (*authorizationFailed > 0)) return QTSS_NoErr; ///inClientSession should never be NULL //inRTSPRequest may be NULL if this is a timeout OSMutexLocker locker(sLogMutex); CheckAccessLogState(false); if (sAccessLog == NULL) return QTSS_NoErr; //if logging is on, then log the request... first construct a timestamp char theDateBuffer[QTSSRollingLog::kMaxDateBufferSizeInBytes]; bool result = QTSSRollingLog::FormatDate(theDateBuffer, sLogTimeInGMT); //for now, just ignore the error. if (!result) theDateBuffer[0] = '\0'; theLen = sizeof(QTSS_RTSPSessionObject); QTSS_RTSPSessionObject theRTSPSession = inRTSPSession; if (theRTSPSession == NULL) (void)QTSS_GetValue(inClientSession, qtssCliSesLastRTSPSession, 0, (void*)&theRTSPSession, &theLen); // Get lots of neat info to log from the various dictionaries // Each attribute must be copied out to ensure that it is NULL terminated. // To ensure NULL termination, just memset the buffers to 0, and make sure that // the last byte of each array is untouched. Float32* packetLossPercent = NULL; Float64* movieDuration = NULL; UInt64* movieSizeInBytes = NULL; UInt32* movieAverageBitRatePtr = 0; UInt32 clientPacketsReceived = 0; UInt32 clientPacketsLost = 0; StrPtrLen* theTransportType = &sUnknownStr; SInt64* theCreateTime = NULL; SInt64* thePlayTime = NULL; UInt32 startPlayTimeInSecs = 0; char localIPAddrBuf[20] = { 0 }; StrPtrLen localIPAddr(localIPAddrBuf, 19); char localDNSBuf[70] = { 0 }; StrPtrLen localDNS(localDNSBuf, 69); char remoteDNSBuf[70] = { 0 }; StrPtrLen remoteDNS(remoteDNSBuf, 69); char remoteAddrBuf[20] = { 0 }; StrPtrLen remoteAddr(remoteAddrBuf, 19); char playerIDBuf[ePlayerIDSize] = { 0 }; StrPtrLen playerID(playerIDBuf, ePlayerIDSize - 1); // First, get networking info from the RTSP session (void)QTSS_GetValue(inClientSession, qtssCliRTSPSessLocalAddrStr, 0, localIPAddr.Ptr, &localIPAddr.Len); (void)QTSS_GetValue(inClientSession, qtssCliRTSPSessLocalDNS, 0, localDNS.Ptr, &localDNS.Len); (void)QTSS_GetValue(inClientSession, qtssCliSesHostName, 0, remoteDNS.Ptr, &remoteDNS.Len); (void)QTSS_GetValue(inClientSession, qtssCliRTSPSessRemoteAddrStr, 0, remoteAddr.Ptr, &remoteAddr.Len); (void)QTSS_GetValue(inClientSession, qtssCliRTSPSessRemoteAddrStr, 0, playerID.Ptr, &playerID.Len); UInt32* rtpBytesSent = NULL; UInt32* rtcpBytesRecv = NULL; UInt32* rtpPacketsSent = NULL; // Second, get networking info from the Client's session. // (Including the stats for incoming RTCP packets.) char urlBuf[eURLSize] = { 0 }; StrPtrLen url(urlBuf, eURLSize - 1); (void)QTSS_GetValue(inClientSession, qtssCliSesPresentationURL, 0, url.Ptr, &url.Len); (void)QTSS_GetValuePtr(inClientSession, qtssCliSesPacketLossPercent, 0, (void**)&packetLossPercent, &theLen); (void)QTSS_GetValuePtr(inClientSession, qtssCliSesMovieDurationInSecs, 0, (void**)&movieDuration, &theLen); (void)QTSS_GetValuePtr(inClientSession, qtssCliSesMovieSizeInBytes, 0, (void**)&movieSizeInBytes, &theLen); (void)QTSS_GetValuePtr(inClientSession, qtssCliSesMovieAverageBitRate, 0, (void**)&movieAverageBitRatePtr, &theLen); (void)QTSS_GetValuePtr(inClientSession, qtssCliSesCreateTimeInMsec, 0, (void**)&theCreateTime, &theLen); (void)QTSS_GetValuePtr(inClientSession, qtssCliSesFirstPlayTimeInMsec, 0, (void**)&thePlayTime, &theLen); (void)QTSS_GetValuePtr(inClientSession, qtssCliSesRTPBytesSent, 0, (void**)&rtpBytesSent, &theLen); (void)QTSS_GetValuePtr(inClientSession, qtssCliSesRTPPacketsSent, 0, (void**)&rtpPacketsSent, &theLen); (void)QTSS_GetValuePtr(inClientSession, qtssCliSesRTCPBytesRecv, 0, (void**)&rtcpBytesRecv, &theLen); if (theCreateTime != NULL && thePlayTime != NULL) startPlayTimeInSecs = (UInt32)(((*theCreateTime - *thePlayTime) / 1000) + 0.5); // We need a value of 'c-bytes' to report as a log entry. This is supposed to be the total number // of bytes the client has received during the session. Unfortunately, the QT client does not give // us this number. We will use the following heuristic formula to estimate the number of bytes the // client has received during the session: // // client-bytes-received = bytes-sent * (100.0 - percent-packet-lost) / 100.0 // // The 'percent-packet-lost' value has been calculated internally by QTSS based on the RTCP packets // sent to the server from the client. If those values are accurate then the above formula will not // be exactly correct but it will be nearly correct. UInt32 clientBytesRecv = (UInt32)((*rtpBytesSent * (100.0 - *packetLossPercent)) / 100.0); tempLogStr.Ptr[0] = 0; tempLogStr.Len = eUserAgentSize; (void)QTSS_GetValue(inClientSession, qtssCliSesFirstUserAgent, 0, tempLogStr.Ptr, &tempLogStr.Len); char userAgentBuf[eUserAgentSize] = { 0 }; StrPtrLen userAgent(userAgentBuf, eUserAgentSize - 1); ReplaceSpaces(&tempLogStr, &userAgent, "%20"); UserAgentParser userAgentParser(&userAgent); // StrPtrLen* playerID = userAgentParser.GetUserID() ; StrPtrLen* playerVersion = userAgentParser.GetUserVersion(); StrPtrLen* playerLang = userAgentParser.GetUserLanguage(); StrPtrLen* playerOS = userAgentParser.GetrUserOS(); StrPtrLen* playerOSVers = userAgentParser.GetUserOSVersion(); StrPtrLen* playerCPU = userAgentParser.GetUserCPU(); // char playerIDBuf[ePlayerIDSize] = {}; char playerVersionBuf[ePlayerVersionSize] = { 0 }; char playerLangBuf[ePlayerLangSize] = { 0 }; char playerOSBuf[ePlayerOSSize] = { 0 }; char playerOSVersBuf[ePlayerOSVersSize] = { 0 }; char playerCPUBuf[ePlayerCPUSize] = { 0 }; UInt32 size; // (ePlayerIDSize < playerID->Len ) ? size = ePlayerIDSize -1 : size = playerID->Len; // if (playerID->Ptr != NULL) memcpy (playerIDBuf, playerID->Ptr, size); (ePlayerVersionSize < playerVersion->Len) ? size = ePlayerVersionSize - 1 : size = playerVersion->Len; if (playerVersion->Ptr != NULL) memcpy(playerVersionBuf, playerVersion->Ptr, size); (ePlayerLangSize < playerLang->Len) ? size = ePlayerLangSize - 1 : size = playerLang->Len; if (playerLang->Ptr != NULL) memcpy(playerLangBuf, playerLang->Ptr, size); (ePlayerOSSize < playerOS->Len) ? size = ePlayerOSSize - 1 : size = playerOS->Len; if (playerOS->Ptr != NULL) memcpy(playerOSBuf, playerOS->Ptr, size); (ePlayerOSVersSize < playerOSVers->Len) ? size = ePlayerOSVersSize - 1 : size = playerOSVers->Len; if (playerOSVers->Ptr != NULL) memcpy(playerOSVersBuf, playerOSVers->Ptr, size); (ePlayerCPUSize < playerCPU->Len) ? size = ePlayerCPUSize - 1 : size = playerCPU->Len; if (playerCPU->Ptr != NULL) memcpy(playerCPUBuf, playerCPU->Ptr, size); // clientPacketsReceived, clientPacketsLost, videoPayloadName and audioPayloadName // are all stored on a per-stream basis, so let's iterate through all the streams, // finding this information char videoPayloadNameBuf[32] = { 0 }; StrPtrLen videoPayloadName(videoPayloadNameBuf, 31); char audioPayloadNameBuf[32] = { 0 }; StrPtrLen audioPayloadName(audioPayloadNameBuf, 31); UInt32 qualityLevel = 0; UInt32 clientBufferTime = 0; UInt32 theStreamIndex = 0; bool* isTCPPtr = NULL; QTSS_RTPStreamObject theRTPStreamObject = NULL; for (UInt32 theStreamObjectLen = sizeof(theRTPStreamObject); QTSS_GetValue(inClientSession, qtssCliSesStreamObjects, theStreamIndex, (void*)&theRTPStreamObject, &theStreamObjectLen) == QTSS_NoErr; theStreamIndex++, theStreamObjectLen = sizeof(theRTPStreamObject)) { UInt32* streamPacketsReceived = NULL; UInt32* streamPacketsLost = NULL; (void)QTSS_GetValuePtr(theRTPStreamObject, qtssRTPStrTotPacketsRecv, 0, (void**)&streamPacketsReceived, &theLen); (void)QTSS_GetValuePtr(theRTPStreamObject, qtssRTPStrTotalLostPackets, 0, (void**)&streamPacketsLost, &theLen); // Add up packets received and packets lost to come up with a session wide total if (streamPacketsReceived != NULL) clientPacketsReceived += *streamPacketsReceived; if (streamPacketsLost != NULL) clientPacketsLost += *streamPacketsLost; // Identify the video and audio codec types QTSS_RTPPayloadType* thePayloadType = NULL; (void)QTSS_GetValuePtr(theRTPStreamObject, qtssRTPStrPayloadType, 0, (void**)&thePayloadType, &theLen); if (thePayloadType != NULL) { if (*thePayloadType == qtssVideoPayloadType) (void)QTSS_GetValue(theRTPStreamObject, qtssRTPStrPayloadName, 0, videoPayloadName.Ptr, &videoPayloadName.Len); else if (*thePayloadType == qtssAudioPayloadType) (void)QTSS_GetValue(theRTPStreamObject, qtssRTPStrPayloadName, 0, audioPayloadName.Ptr, &audioPayloadName.Len); } // If any one of the streams is being delivered over UDP instead of TCP, // report in the log that the transport type for this session was UDP. if (isTCPPtr == NULL) { (void)QTSS_GetValuePtr(theRTPStreamObject, qtssRTPStrIsTCP, 0, (void**)&isTCPPtr, &theLen); if (isTCPPtr != NULL) { if (*isTCPPtr == false) theTransportType = &sUDPStr; else theTransportType = &sTCPStr; } } Float32* clientBufferTimePtr = NULL; (void)QTSS_GetValuePtr(theRTPStreamObject, qtssRTPStrBufferDelayInSecs, 0, (void**)&clientBufferTimePtr, &theLen); if ((clientBufferTimePtr != NULL) && (*clientBufferTimePtr != 0)) { if (*clientBufferTimePtr > clientBufferTime) clientBufferTime = (UInt32)(*clientBufferTimePtr + .5); // round up to full seconds } } // Add the client buffer time to our client start latency (in whole seconds). startPlayTimeInSecs += clientBufferTime; if (*rtpPacketsSent == 0) // no packets sent qualityLevel = 0; // no quality else { if ((clientPacketsReceived == 0) && (clientPacketsLost == 0)) // no info from client qualityLevel = 100; //so assume 100 else { float qualityPercent = (float)clientPacketsReceived / (float)(clientPacketsReceived + clientPacketsLost); qualityPercent += (float).005; // round up qualityLevel = (UInt32)((float) 100.0 * qualityPercent); // average of sum of packet counts for all streams } } //we may not have an RTSP request. Assume that the status code is 504 timeout, if there is an RTSP //request, though, we can find out what the real status code of the response is static UInt32 sTimeoutCode = 504; UInt32* theStatusCode = &sTimeoutCode; theLen = sizeof(UInt32); (void)QTSS_GetValuePtr(inClientSession, qtssCliRTSPReqRealStatusCode, 0, (void **)&theStatusCode, &theLen); // qtss_printf("qtssCliRTSPReqRealStatusCode = %" _U32BITARG_ " \n", *theStatusCode); if (inCloseReasonPtr) do { if (*theStatusCode < 300) // it was a succesful RTSP request but... { if (*inCloseReasonPtr == qtssCliSesCloseTimeout) // there was a timeout { *theStatusCode = sTimeoutCode; // qtss_printf(" log timeout "); break; } if (*inCloseReasonPtr == qtssCliSesCloseClientTeardown) // there was a teardown { static QTSS_CliSesClosingReason sReason = qtssCliSesCloseClientTeardown; QTSS_CliSesClosingReason* theReasonPtr = &sReason; theLen = sizeof(QTSS_CliSesTeardownReason); (void)QTSS_GetValuePtr(inClientSession, qtssCliTeardownReason, 0, (void **)&theReasonPtr, &theLen); // qtss_printf("qtssCliTeardownReason = %" _U32BITARG_ " \n", *theReasonPtr); if (*theReasonPtr == qtssCliSesTearDownClientRequest) // the client asked for a tear down { // qtss_printf(" client requests teardown "); break; } if (*theReasonPtr == qtssCliSesTearDownUnsupportedMedia) // An error occured while streaming the file. { *theStatusCode = 415; // qtss_printf(" log UnsupportedMedia "); break; } if (*theReasonPtr == qtssCliSesTearDownBroadcastEnded) // a broadcaster stopped broadcasting { *theStatusCode = 452; // qtss_printf(" log broadcast removed "); break; } *theStatusCode = 500; // some unknown reason for cancelling the connection } // qtss_printf("return status "); // just use the qtssCliRTSPReqRealStatusCode for the reason } } while (false); // qtss_printf(" = %" _U32BITARG_ " \n", *theStatusCode); // Find out what time it is SInt64 curTime = QTSS_Milliseconds(); UInt32 numCurClients = 0; theLen = sizeof(numCurClients); (void)QTSS_GetValue(sServer, qtssRTPSvrCurConn, 0, &numCurClients, &theLen); /* IMPORTANT!!!! Some values such as cpu, #conns, need to be grabbed as the session starts, not when the teardown happened (I think) */ #if TESTUNIXTIME char thetestDateBuffer[QTSSRollingLog::kMaxDateBufferSizeInBytes]; TestUnixTime(QTSS_MilliSecsTo1970Secs(*theCreateTime), thetestDateBuffer); qtss_printf("%s\n", thetestDateBuffer); #endif float zeroFloat = 0; UInt64 zeroUInt64 = 0; Float32 fcpuUtilized = 0; theLen = sizeof(fcpuUtilized); (void)QTSS_GetValue(sServer, qtssSvrCPULoadPercent, 0, &fcpuUtilized, &theLen); UInt32 cpuUtilized = (UInt32)fcpuUtilized; char lastUserName[eTempLogItemSize] = { 0 }; StrPtrLen lastUserNameStr(lastUserName, eTempLogItemSize); char lastURLRealm[eTempLogItemSize] = { 0 }; StrPtrLen lastURLRealmStr(lastURLRealm, eTempLogItemSize); //qtss_printf("logging of saved params are in dictionary \n"); tempLogStr.Ptr[0] = 0; tempLogStr.Len = eTempLogItemSize; (void)QTSS_GetValue(inClientSession, qtssCliRTSPSesUserName, 0, tempLogStr.Ptr, &tempLogStr.Len); ReplaceSpaces(&tempLogStr, &lastUserNameStr, "%20"); //qtss_printf("qtssRTSPSesLastUserName dictionary item = %s len = %" _S32BITARG_ "\n",lastUserNameStr.Ptr,lastUserNameStr.Len); tempLogStr.Ptr[0] = 0; tempLogStr.Len = eTempLogItemSize; (void)QTSS_GetValue(inClientSession, qtssCliRTSPSesURLRealm, 0, tempLogStr.Ptr, &tempLogStr.Len); ReplaceSpaces(&tempLogStr, &lastURLRealmStr, "%20"); //qtss_printf("qtssRTSPSesLastURLRealm dictionary item = %s len = %" _S32BITARG_ "\n",lastURLRealmStr.Ptr,lastURLRealmStr.Len); char respMsgBuffer[1024] = { 0 }; StrPtrLen theRespMsg; (void)QTSS_GetValuePtr(inClientSession, qtssCliRTSPReqRespMsg, 0, (void**)&theRespMsg.Ptr, &theRespMsg.Len); StrPtrLen respMsgEncoded(respMsgBuffer, 1024 - 1); SInt32 theErr = StringTranslator::EncodeURL(theRespMsg.Ptr, theRespMsg.Len, respMsgEncoded.Ptr, respMsgEncoded.Len); if (theErr <= 0) respMsgEncoded.Ptr[0] = '\0'; else { respMsgEncoded.Len = theErr; respMsgEncoded.Ptr[respMsgEncoded.Len] = '\0'; } //cs-uri-query char urlQryBuf[eURLSize] = { 0 }; StrPtrLen urlQry(urlQryBuf, eURLSize - 1); (void)QTSS_GetValue(inClientSession, qtssCliSesReqQueryString, 0, urlQry.Ptr, &urlQry.Len); char tempLogBuffer[1024]; char logBuffer[2048]; // compatible fields (no respMsgEncoded field) ::memset(logBuffer, 0, 2048); qtss_sprintf(tempLogBuffer, "%s ", (remoteAddr.Ptr[0] == '\0') ? sVoidField : remoteAddr.Ptr); //c-ip* ::strcpy(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (theDateBuffer[0] == '\0') ? sVoidField : theDateBuffer); //date* time* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (remoteDNS.Ptr[0] == '\0') ? sVoidField : remoteDNS.Ptr); //c-dns ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (url.Ptr[0] == '\0') ? sVoidField : url.Ptr); //cs-uri-stem* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _U32BITARG_ " ", startPlayTimeInSecs); //c-starttime ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _U32BITARG_ " ", theCreateTime == NULL ? (UInt32)0 : (UInt32)(QTSS_MilliSecsTo1970Secs(curTime) - QTSS_MilliSecsTo1970Secs(*theCreateTime))); //x-duration* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _S32BITARG_ " ", (UInt32)1); //c-rate ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _S32BITARG_ " ", *theStatusCode); //c-status* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (playerIDBuf[0] == '\0') ? sVoidField : playerIDBuf); //c-playerid* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (playerVersionBuf[0] == '\0') ? sVoidField : playerVersionBuf); //c-playerversion ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (playerLangBuf[0] == '\0') ? sVoidField : playerLangBuf); //c-playerlanguage* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (userAgent.Ptr[0] == '\0') ? sVoidField : userAgent.Ptr); //cs(User-Agent) ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (playerOSBuf[0] == '\0') ? sVoidField : playerOSBuf); //c-os* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (playerOSVersBuf[0] == '\0') ? sVoidField : playerOSVersBuf); //c-osversion ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (playerCPUBuf[0] == '\0') ? sVoidField : playerCPUBuf); //c-cpu* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%0.0f ", movieDuration == NULL ? zeroFloat : *movieDuration); //filelength in secs* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _64BITARG_ "d ", movieSizeInBytes == NULL ? zeroUInt64 : *movieSizeInBytes); //filesize in bytes* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _U32BITARG_ " ", movieAverageBitRatePtr == NULL ? (UInt32)0 : *movieAverageBitRatePtr); //avgbandwidth in bits per second ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", "RTP"); //protocol ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (theTransportType->Ptr[0] == '\0') ? sVoidField : theTransportType->Ptr); //transport ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (audioPayloadName.Ptr[0] == '\0') ? sVoidField : audioPayloadName.Ptr); //audiocodec* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (videoPayloadName.Ptr[0] == '\0') ? sVoidField : videoPayloadName.Ptr); //videocodec* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _U32BITARG_ " ", rtpBytesSent == NULL ? (UInt32)0 : *rtpBytesSent); //sc-bytes* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _U32BITARG_ " ", rtcpBytesRecv == NULL ? (UInt32)0 : *rtcpBytesRecv); //cs-bytes* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _U32BITARG_ " ", clientBytesRecv); //c-bytes ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _U32BITARG_ " ", rtpPacketsSent == NULL ? (UInt32)0 : *rtpPacketsSent); //s-pkts-sent* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _U32BITARG_ " ", clientPacketsReceived); //c-pkts-recieved ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _U32BITARG_ " ", clientPacketsLost); //c-pkts-lost-client* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _U32BITARG_ " ", (UInt32)1); //c-buffercount ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _U32BITARG_ " ", clientBufferTime); //c-totalbuffertime* ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _U32BITARG_ " ", qualityLevel); //c-quality ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (localIPAddr.Ptr[0] == '\0') ? sVoidField : localIPAddr.Ptr); //s-ip ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (localDNS.Ptr[0] == '\0') ? sVoidField : localDNS.Ptr); //s-dns ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _U32BITARG_ " ", numCurClients); //s-totalclients ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%" _U32BITARG_ " ", cpuUtilized); //s-cpu-util ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (urlQry.Ptr[0] == '\0') ? sVoidField : urlQry.Ptr); //cs-uri-query ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (lastUserName[0] == '\0') ? sVoidField : lastUserName); //c-username ::strcat(logBuffer, tempLogBuffer); qtss_sprintf(tempLogBuffer, "%s ", (lastURLRealm[0] == '\0') ? sVoidField : lastURLRealm); //sc(Realm) ::strcat(logBuffer, tempLogBuffer); ::strcat(logBuffer, "\n"); Assert(::strlen(logBuffer) < 2048); //finally, write the log message sAccessLog->WriteToLog(logBuffer, kAllowLogToRoll); return QTSS_NoErr; }
int TableProtoScene::ScoreBoard::getScoreSign() { for (int i = DigitGroups - 1; i >= 0; --i) if (GameStatus::gameStat()->Player[playerID()].PlayerScore.digitGroup[i] > 0) return 1; else if (GameStatus::gameStat()->Player[playerID()].PlayerScore.digitGroup[i] < 0) return -1; return 0; }
//This function is called each time it is your turn. //Return true to end your turn, return false to ask the server for updated information. bool AI::run() { //loop through all of the tiles for(int i = 0;i < tiles.size();i++) { //if this tile is one of my coves and does not have a fish on it if(tiles[i].owner() == playerID() && getFishIndex(tiles[i].x(), tiles[i].y()) == -1) { if(getSpecies(SEA_STAR).spawn(tiles[i].x(),tiles[i].y())) std::cout<<"I am fish"<<std::endl; /* //loop through all of the species for(int p = 0;p<species.size(); p++) { //if the current species is in season if(species[p].season() == currentSeason()) { //if I have enough food to spawn the fish in and there is not //an egg on that tile already if(players[playerID()].spawnFood() >= species[p].cost() && tiles[i].hasEgg() == false) { //spawn the fish on that tile species[p].spawn(tiles[i].x(), tiles[i].y()); } } }*/ } } //loop through all of the fish for(int i = 0;i < fishes.size();i++) { //if this is my fish if(fishes[i].owner() == playerID()) { int x = fishes[i].x(); int y = fishes[i].y(); if(fishes[i].x() >= 1) { //if the tile to the left has trash and the current fish can //carry at least one more trash if(getTile(x - 1, y).trashAmount() > 0 && fishes[i].carryingWeight() + 1 <= fishes[i].carryCap()) { //if the fish has enought health to pick up trash if(1 * trashDamage() < fishes[i].currentHealth()) { //pick up trash to the left of the fish fishes[i].pickUp(x - 1, y, 1); } } } //if the fish carrying any trash if(fishes[i].carryingWeight() > 0) { //if the fish in the enemy's side if((fishes[i].x() < mapWidth()/2 - boundLength() - 1 && enemyAI_ID == 0) || (fishes[i].x() > mapWidth()/2 + boundLength() + 1 && enemyAI_ID == 1)) { if(fishes[i].y() != 0) { //if the tile above the fish is not a cove and has no fish if(getTile(x, y - 1).owner() == 2 && getFishIndex(x, y + 1) == -1) { //drop all of the trash the fish is carrying fishes[i].drop(x, y - 1, fishes[i].carryingWeight()); } } else if(fishes[i].y() != mapHeight() - 1) { //if the tile below the fish is not a cove and has no fish if(getTile(x,y + 1).owner() == 2 && getFishIndex(x,y + 1) == -1) { //drop all of the trash the fish is carrying fishes[i].drop(x, y + 1, fishes[i].carryingWeight()); } } } } if(fishes[i].x() >= 1) { //if the tile to the left is not an enemy cove and there is no trash if(getTile(x - 1,y).owner() != enemyAI_ID && getTile(x - 1,y).trashAmount() == 0) { //if the tile to the left does not have a fish and does not have an //egg if(getFishIndex(x - 1, y) == -1 && getTile(x - 1, y).hasEgg() == false) { //move to the left fishes[i].move(x - 1, y); } } //get the fish to the left int target = getFishIndex(x - 1, y); //if there is a fish to the left and the fish has attacks left if(target != -1 && fishes[i].attacksLeft() > 0) { //if the fish is not a cleaner shrimp if(fishes[i].species() != CLEANER_SHRIMP) { //if the fish to the left is an enemy fish if(fishes[target].owner() == enemyAI_ID) { //attack the fish fishes[i].attack(fishes[target]); } } else { //this is if the fish is a cleaner shrimp //if the fish to the left is a friendly fish if(fishes[target].owner() != enemyAI_ID) { //heal the fish fishes[i].attack(fishes[target]); } } } } } } return true; }