/** * @param numbers: Give an array numbersbers of n integer * @param target: you need to find four elements that's sum of target * @return: Find all unique quadruplets in the array which gives the sum of * zero. */ vector<vector<int> > fourSum(vector<int> nums, int target) { ans.clear(); vector<int> &a = nums; vector<int> v(4); int n = nums.size(); int i1, i2, i3, i4; sort(a.begin(), a.end()); i1 = 0; while(i1 < n) { i4 = n - 1; while (i4 > i1) { i2 = i1 + 1; i3 = i4 - 1; while (i2 < i3) { if (a[i1] + a[i2] + a[i3] + a[i4] < target) { ++i2; } else if (a[i1] + a[i2] + a[i3] + a[i4] > target) { --i3; } else { v[0] = a[i1]; v[1] = a[i2]; v[2] = a[i3]; v[3] = a[i4]; ans.push_back(v); i2 = nextPos(a, n, i2); } } i4 = lastPos(a, i1, i4); } i1 = nextPos(a, n, i1); } return ans; }
/** * Resolve o Sudoku. * Retorna indica��o de sucesso ou insucesso (sudoku imposs�vel). */ bool Sudoku::solve() { int nx,ny; if(!nextPos(nx,ny)){ return true; } for(int n = 1; n <= 9;n++){ if(check(n,nx,ny)){ numbers[nx][ny] = n; countFilled++; if(solve()){ return true; } numbers[nx][ny] = 0; countFilled--; } } return false; }
MatrixPos Surrounder::nextPos() { int dia = 3 + round * 2; int x, y; if (count == 0) { x = 0; y = 1; } else if (count < dia - 1) { x = 1; y = 0; } else if (count < 2 * dia - 2) { x = 0; y = -1; } else if (count < 3 * dia - 3) { x = -1; y = 0; } else if (count < 4 * dia - 4) { x = 0; y = 1; } else { round++; count = 0; return nextPos(); } count++; return MatrixPos(x, y); }
/** * * @brief read Motorpositions from File */ eveVariant evePosCalc::stepfuncList(){ eveVariant nextPos(currentPos); // posCounter == 0 => start Position, if (axisType == eveSTRING){ if (posCounter < positionList.count()) nextPos.setValue(positionList.at(posCounter)); } else if (axisType == eveINT){ if (posCounter < posIntList.count()){ if (absolute) nextPos.setValue(posIntList.at(posCounter)); else nextPos.setValue(posIntList.at(posCounter) + offSet.toDouble());; } } else if (axisType == eveDOUBLE){ if (posCounter < posDoubleList.count()){ if (absolute) nextPos.setValue(posDoubleList.at(posCounter)); else nextPos.setValue(posDoubleList.at(posCounter) + offSet.toDouble());; } } return nextPos; }
/** * @brief stepfunction moves the axis to the position offset plus reference axis * */ eveVariant evePosCalc::stepfuncReferenceAdd(){ eveVariant nextPos(currentPos); if (referencePosCalc != NULL) nextPos = referencePosCalc->getCurrentPos() + referenceOffset; else sendError(ERROR, "ReferenceAdd: invalid reference axis"); return nextPos; }
/** * @brief stepfunction moves the axis to a multiple of the reference axis * */ eveVariant evePosCalc::stepfuncReferenceMultiply(){ eveVariant nextPos(currentPos); if (referencePosCalc != NULL) nextPos = referencePosCalc->getCurrentPos() * multiplyFactor; else sendError(ERROR, "ReferenceMultiply: invalid reference axis"); return nextPos; }
void mouseMoveCB(int x, int y) { math::vec2 nextPos(x, y); if (shouldRot) { math::vec2 delta = (nextPos - mousePos) * rotSpeed; delta.x *= -1; app->renderer.moveCamera(math::vec2(0, 0), delta); } mousePos = nextPos; }
Point<float> Bullet::next() { float x, y; life--; x = cos(angle) * speed + pos.getx(); y = sin(angle) * speed + pos.gety(); Point<float> nextPos(x, y); pos = nextPos; drawBullet(pos, 2); return nextPos; }
/** * * @brief set the next valid motorposition */ eveVariant evePosCalc::stepfuncMultiply(){ eveVariant nextPos(currentPos); if ((axisType != eveINT) && (axisType != eveDOUBLE)){ sendError(ERROR, "stepfunction Multiply may be used with integer or double values only"); } else { multiplyFactor += stepWidth.toDouble(); if (donefuncMultiply()) multiplyFactor = endPos.toDouble(); nextPos.setValue(offSet.toDouble() * multiplyFactor); } return nextPos; }
QPointF Unit::generateNextValidPos() { QPointF nextPos(0, 0); bool continua; QRectF escRect = scene()->sceneRect(); int intentos = 0; do{ if(intentos < 3){ nextPos = pos() + generateRandomPosition(100, angRange); intentos++; }else{ nextPos = pos() + generateRandomPosition(100, 0, 360); } continua = !((nextPos.x() > escRect.x()) && (nextPos.x() < escRect.x() + escRect.width()) && (nextPos.y() > escRect.y()) && (nextPos.y() < escRect.y() + escRect.height())); }while(continua); return nextPos; }
void CSelectedUnitsAI::MakeFrontMove(Command* c,int player) { centerPos.x=c->params[0]; centerPos.y=c->params[1]; centerPos.z=c->params[2]; rightPos.x=c->params[3]; rightPos.y=c->params[4]; rightPos.z=c->params[5]; float3 nextPos(0.0f, 0.0f, 0.0f);//it's in "front" coordinates (rotated to real, moved by rightPos) if(centerPos.distance(rightPos)<selectedUnits.netSelected[player].size()+33) { //Strange line! treat this as a standard move if the front isnt long enough for(vector<int>::iterator ui = selectedUnits.netSelected[player].begin(); ui != selectedUnits.netSelected[player].end(); ++ui) { CUnit* unit=uh->units[*ui]; if(unit) { unit->commandAI->GiveCommand(*c, false); } } return; } frontLength=centerPos.distance(rightPos)*2; addSpace = 0; if (frontLength > sumLength*2*8) { addSpace = (frontLength - sumLength*2*8)/(selectedUnits.netSelected[player].size() - 1); } sideDir=centerPos-rightPos; sideDir.y=0; float3 sd = sideDir; sd.y=frontLength/2; sideDir.ANormalize(); frontDir=sideDir.cross(float3(0,1,0)); numColumns=(int)(frontLength/columnDist); if(numColumns==0) numColumns=1; std::multimap<float,int> orderedUnits; CreateUnitOrder(orderedUnits,player); for (std::multimap<float,int>::iterator oi=orderedUnits.begin(); oi!=orderedUnits.end(); ++oi) { nextPos = MoveToPos(oi->second, nextPos, sd, c); } }
/** * * @brief set the next valid motorposition by adding stepwidth to current position */ eveVariant evePosCalc::stepfuncAdd(){ eveVariant nextPos(currentPos); if (axisType == eveSTRING){ sendError(ERROR, "stepfunction add may be used with integer, double or datetime values only"); } else { if ((nextPos.getType() == eveDateTimeT) && (stepWidth.getType() == eveDOUBLE)){ sendError(DEBUG, QString("adding stepwidth %1 to current position %2").arg(stepWidth.toDouble()).arg(nextPos.toDateTime().toString())); nextPos.setValue(currentPos.toDateTime().addMSecs((qint64)(stepWidth.toDouble(NULL)*1000.0))); } else { nextPos = currentPos + stepWidth; } if (donefuncAdd()) nextPos=endPosAbs; } return nextPos; }
void Matrix::BFS(Point start, int rows, int cols, LinkedList<Point>& path) { if (matrix[start.getX()][start.getY()] == '#') { cout << "The position is invalid!\n"; return; } int dr[] = { 0, -1, 0, 1 }; int dc[] = { -1, 0, 1, 0 }; Queue<Point> queue; queue.Enqueue(start); matrix[start.getX()][start.getY()] = '?'; cout << "Starting from point: "; cout << "(" << start.getX() << ", " << start.getY() << ")" << " : " << endl; while (!queue.isEmpty()) { start = queue.Front(); queue.Dequeue(); for (int d = 0; d < 4; d++) { Point nextPos(start.getX() + dr[d], start.getY() + dc[d]); if (canPass(rows, cols, nextPos)) { path.Push_Back(nextPos); queue.Enqueue(nextPos); matrix[nextPos.getX()][nextPos.getY()] = '?'; } } } }
void CSelectedUnitsAI::MakeFrontMove(Command* c,int player) { centerPos.x=c->params[0]; centerPos.y=c->params[1]; centerPos.z=c->params[2]; rightPos.x=c->params[3]; rightPos.y=c->params[4]; rightPos.z=c->params[5]; float3 nextPos(0.0f, 0.0f, 0.0f);//it's in "front" coordinates (rotated to real, moved by rightPos) if(centerPos.distance(rightPos)<selectedUnits.netSelected[player].size()+33) { //Strange line! treat this as a standard move if the front isnt long enough for(std::vector<int>::iterator ui = selectedUnits.netSelected[player].begin(); ui != selectedUnits.netSelected[player].end(); ++ui) { CUnit* unit=uh->units[*ui]; if(unit) { unit->commandAI->GiveCommand(*c, false); } } return; } frontLength=centerPos.distance(rightPos)*2; addSpace = 0; if (frontLength > sumLength*2*8) { addSpace = (frontLength - sumLength*2*8)/(selectedUnits.netSelected[player].size() - 1); } sideDir=centerPos-rightPos; sideDir.y=0; float3 sd = sideDir; sd.y=frontLength/2; sideDir.ANormalize(); frontDir=sideDir.cross(float3(0,1,0)); numColumns=(int)(frontLength/columnDist); if(numColumns==0) numColumns=1; std::multimap<float,int> orderedUnits; CreateUnitOrder(orderedUnits,player); std::multimap<float, std::vector<int> > sortUnits; std::vector<std::pair<int,Command> > frontcmds; for (std::multimap<float,int>::iterator oi = orderedUnits.begin(); oi != orderedUnits.end();) { bool newline; nextPos = MoveToPos(oi->second, nextPos, sd, c, &frontcmds, &newline); // mix units in each row to avoid weak flanks consisting solely of e.g. artillery units std::multimap<float, std::vector<int> >::iterator si = sortUnits.find(oi->first); if(si == sortUnits.end()) si = sortUnits.insert(std::pair<float, std::vector<int> >(oi->first, std::vector<int>())); si->second.push_back(oi->second); ++oi; if(oi != orderedUnits.end()) MoveToPos(oi->second, nextPos, sd, c, NULL, &newline); if(oi == orderedUnits.end() || newline) { std::vector<std::vector<int>*> sortUnitsVector; for (std::multimap<float, std::vector<int> >::iterator ui = sortUnits.begin(); ui!=sortUnits.end(); ++ui) { sortUnitsVector.push_back(&(*ui).second); } std::vector<int> randunits; int sz = sortUnitsVector.size(); std::vector<int> sortPos(sz, 0); for (std::vector<std::pair<int,Command> >::iterator fi = frontcmds.begin(); fi != frontcmds.end(); ++fi) { int bestpos = 0; float bestval = 1.0f; for (int i = 0; i < sz; ++i) { const int n = sortUnitsVector[i]->size(); const int k = sortPos[i]; if (k < n) { const float val = (0.5f + k) / (float)n; if (val < bestval) { bestval = val; bestpos = i; } } } int pos = sortPos[bestpos]; randunits.push_back((*sortUnitsVector[bestpos])[pos]); sortPos[bestpos] = pos + 1; } sortUnits.clear(); int i = 0; for (std::vector<std::pair<int,Command> >::iterator fi = frontcmds.begin(); fi != frontcmds.end(); ++fi) { uh->units[randunits[i++]]->commandAI->GiveCommand(fi->second, false); } frontcmds.clear(); } } }
int main(int argc, char** argv){ int sock = 0; // declaración del socket e inicializado a 0 int error = 0; /** declaramos una variable que nos servirá para detectar * errores */ socklen_t length = (socklen_t) sizeof (struct sockaddr_in); // tamaño del paquete struct sockaddr_in addr; // definimos el contenedor de la dirección unsigned int port = 5678; /** creamos la variable que identifica el puerto * de conexión, siendo el puerto por defecto 5678 */ int connPos = 0; // primera posición libre en el array de conexiones int connTam = 10; // tamaño actual del array de conexiones int connGrow = 10; // factor de crecimiento del array user* conn = NULL; // array de conexiones con los clientes room rooms[DIM]; user auxConn; // conexion auxiliar sms auxMsj; fd_set connList, connListCopy; // definimos un descriptor que contendrá nuestros sockets int nbytes = 0; // contador de bytes leidos y escritos int dbName = 0; // variable que nos permitirá configurar el nombre de la base de datos sqlite3* db = NULL; // descriptor de la base de datos char cert[DIM] = "cert"; // nombre del certificado del servidor char pkey[DIM] = "pkey"; // nombre del archivo con la clave privada // <editor-fold defaultstate="collapsed" desc="Interpretado de parámetros de entrada"> //analizamos los parámetros de entrada int i = 0; for(; i < argc; i++){ if(strcmp(argv[i], "-p") == 0){ // leemos el puerto if(argc <= i + 1 || isNum(argv[i+1]) == 0){ perror("Se esperaba un número después de -p"); exit(-1); }else{ PDEBUG("ARGS: Se detectó un puerto\n"); i++; port = atoi(argv[i]); } continue; }else if(strcmp(argv[i], "-ls") == 0){ // leemos el tamaño inicial de la lista if(argc <= i + 1 || isNum(argv[i+1]) == 0){ perror("Se esperaba un número después de -ls"); exit(-1); }else{ PDEBUG("ARGS: Se detectó un tamaño inicial\n"); i++; connTam = atoi(argv[i]); } continue; }else if(strcmp(argv[i], "-lg") == 0){ // leemos el factor de creciemiento de la lista de conexiones if(argc <= i + 1 || isNum(argv[i+1]) == 0){ perror("Se esperaba un número después de -lg\n"); exit(-1); }else{ PDEBUG("ARGS: Se detectó un crecimiento\n"); i++; connGrow = atoi(argv[i]); } continue; }else if(strcmp(argv[i], "-db") == 0){ // leemos el nombre de la base de datos que queremos utilizar if(argc <= i + 1){ perror("Se esperaba una cadena depués de -db\n"); exit(-1); }else{ PDEBUG("ARGS: Se detectó un crecimiento\n"); i++; dbName = i; } continue; }else if(strcmp(argv[i], "-cert") == 0){ // leemos el nombre del archivo del certificado if(argc <= i + 1){ perror("Se esperaba una cadena depués de -cert\n"); exit(-1); }else{ PDEBUG("ARGS: Se detectó un certificado\n"); i++; strcpy(cert, argv[i]); } continue; }else if(strcmp(argv[i], "-pkey") == 0){ // leemos el nombre del archivo de que contiene la clave privada if(argc <= i + 1){ perror("Se esperaba una cadena depués de -pkey\n"); exit(-1); }else{ PDEBUG("ARGS: Se detectó una clave privada\n"); i++; strcpy(pkey, argv[i]); } continue; } } //</editor-fold> db = db_open( (dbName == 0) ? "chat.db" : argv[dbName] ); PDEBUG("INFO: Convertimos el proceso en un demonio\n"); //make_daemon(); /*******************************SSL****************************************/ PDEBUG("INFO: Inicializando la libreria SSL\n"); SSL_library_init(); PDEBUG("INFO: Cargamos los algoritmos SSL y los mensajes de error\n"); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); PDEBUG("INFO: Seleccionamos SSLv2, SSLv3 y TLSv1\n"); SSL_METHOD *method; method = SSLv23_server_method(); PDEBUG("INFO: Creamos el nuevo contexto\n"); SSL_CTX *ctx; ctx = SSL_CTX_new(method); if(ctx == NULL) { // error ERR_print_errors_fp(stderr); _exit(-1); } PDEBUG("INFO: Comprobando el certificado\n"); if ( SSL_CTX_use_certificate_chain_file(ctx, cert) <= 0) { ERR_print_errors_fp(stderr); _exit(-1); } PDEBUG("INFO: Comprobando la clav eprivada\n"); if ( SSL_CTX_use_PrivateKey_file(ctx, pkey, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); _exit(-1); } PDEBUG("INFO: Comprobando que las claves pueden trabajar juntas\n"); if ( !SSL_CTX_check_private_key(ctx) ) { fprintf(stderr, "Clave privada incorrecta.\n"); _exit(-1); } /*******************************SSL****************************************/ //Creamos el socket PDEBUG("INFO: Creando el socket\n"); sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); //Comprobamos si ha ocurrido un error al crear el socket if(sock < 0){ write(2, strcat("ERROR: creación del socket {{socket()}}: %s\n", strerror(errno)), DIM); // terminamos la ejecución del programa exit(-1); } PDEBUG("INFO: Estableciendo el puerto, origenes,...\n"); addr.sin_family = AF_INET; // familia AF_INET addr.sin_port = htons(port); // definimos el puerto de conexión addr.sin_addr.s_addr = htonl(INADDR_ANY); // permitimos conexion de cualquiera /* hacemos este "apaño" porque según hemos leido, http://www.wlug.org.nz/EADDRINUSE * hay un timeout para liberar el socket */ unsigned int opt = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))==-1) { write(2, "ERROR: al permitir la reutiización del puerto {{setsockopt()}}\n", DIM); exit(-1); } // le asignamos una dirección al socket PDEBUG("INFO: Asignando una dirección al socket\n"); error = bind(sock, (struct sockaddr *)&addr, length); //Comprobamos si ha ocurrido un error al hacer el bind if(error < 0){ write(2, strcat("ERROR: {{bind()}}: %s\n", strerror(errno)), DIM); // terminamos la ejecución del programa exit(-1); } //Ponemos el servidor a escuchar para buscar nuevas conexiones PDEBUG("INFO: Comenzamos la escucha de l programa\n"); error = listen(sock, Q_DIM); //Comprobamos si ha ocurrido un error al ponernos a escuchar if(error < 0){ write(2, strcat("ERROR: al iniciar la escucha{{listen()}}: %s\n", strerror(errno)), DIM); // terminamos la ejecución del programa exit(-1); } // realizamos la asignación inicial de memoria PDEBUG("INFO: Realizando asignación inicial de memoria, tamaño inicial 10\n"); connTam = 10; conn = malloc(connTam * sizeof(user)); // rellenamos el array con -1 memset(conn, 0, connTam * sizeof(user)); //inicializamos la lista de conexiones FD_ZERO(&connList); // Inicio del bit descriptor connList con el valor de sock FD_SET (sock, &connList); PDEBUG("INFO: Creamos la sala de chat general\n"); bzero(rooms, DIM * sizeof(room)); strcpy(rooms[0].name, "general"); // <editor-fold defaultstate="collapsed" desc="Bucle de escucha"> //comenzamos a analizar conexiones PDEBUG("INFO: Comenzamos a analizar los sockets\n"); while(1){ // hacemos una copia de seguridad para asegurarnos de no perder los datos connListCopy = connList; // ¿Hay algún socket listo para leer? PDEBUG("INFO: ¿Hay algún socket listo para leer?\n"); error = select(connTam + 1, &connListCopy, NULL, NULL, NULL); //Comprobamos si ha ocurrido un error al ponernos a escuchar if(error < 0){ write(2, strcat("ERROR: al realizar la selección {{select()}}: %s\n" , strerror(errno)), DIM); // terminamos la ejecución del programa exit(-1); } // recorriendo los sockets para ver los que están activos PDEBUG("INFO: recorriendo los sockets para ver los que están activos\n"); int i = 0; // definimos un índice for (; i <= connTam; i++){ // este socket está preparado para leer los datos if(FD_ISSET(i, &connListCopy)){ // vemos si el socket preparado para leer es el de aceptar peticiones if(i == sock){ PDEBUG("INFO: Nuevo cliente detectado, comprobando...\n"); auxConn.sock = accept(sock, (struct sockaddr *) &addr, &length); if(auxConn.sock < 0){ write(2, "ERROR: al realizar la aceptación {{accept()}}: %s\n" , *strerror(errno)); // terminamos la ejecución del programa exit(-1); } /************************SSL*******************************/ PDEBUG("INFO: Creando conexion ssl\n"); PDEBUG("INFO: Creando conexion SSL\n"); auxConn.ssl = SSL_new(ctx); PDEBUG("INFO: Asignando la conexión a SSL\n"); SSL_set_fd(auxConn.ssl, auxConn.sock); PDEBUG("INFO: Aceptando la conexión SSL\n"); error = SSL_accept(auxConn.ssl); if(error < 0){ ERR_print_errors_fp(stderr); exit(-1); } /************************SSL*******************************/ PDEBUG("INFO: Conexión establecida, autenticando...\n"); memset(&auxMsj, 0, sizeof(auxMsj)); // incializamos la estructura PDEBUG("INFO: Solicitando autenticación\n"); strcpy(auxMsj.text, "Usuario: "); // establecemos el texto que queremos que se muestre auxMsj.flag = REQ_TEXT; // le indicamos que requerimos una respuesta con texto strcpy(auxMsj.name, SERVER); // nos identificamos como el servidor SSL_write(auxConn.ssl, &auxMsj, sizeof(sms)); // enviamos la información // metemos los datos de la conexión en nuestro array de conexiones strcpy((*(conn + connPos)).name, auxMsj.text); (*(conn + connPos)).sock = auxConn.sock; (*(conn + connPos)).ssl = auxConn.ssl; (*(conn + connPos)).prov = PROV; // Añadimos el socket a nuestra lista PDEBUG("INFO: Insertando socket en la lista de monitoreo\n"); FD_SET (auxConn.sock, &connList); // como la peticion se ha aceptado incrementamos el contador de conexiones PDEBUG("INFO: Cálculo del nuevo offset\n"); nextPos(conn, &connPos, &connTam, connGrow); }else{ // si no, es un cliente ya registrado PDEBUG("DATA: Nuevo mensaje detectado\n"); nbytes = SSL_read((*(conn+searchConn(conn, connTam, i))).ssl, &auxMsj, sizeof(sms)); if(nbytes > 0){ // si hemos leido más d eun byte... switch(auxMsj.flag){ case CLI_EXIT: // desconexión del cliente closeConn(conn, &connPos, connTam, i, &connList, db); break; case SERV_ADMIN: // parámetros que ha de ejecutr el servidor execParams(conn, connTam, auxMsj.text, i, sock, db, rooms, DIM); break; case MSJ: // mensaje multicast(conn, &connTam, auxMsj, i, db, (*(conn+searchConn(conn, connTam, i))).room); break; case REQ_AUTH: // vamos a leer el nombre de usuario auth(conn, &connTam, i, auxMsj, db, rooms, DIM); break; case CHECK_ROOM: // vamos a leer el nombre de usuario roomCheckIn(conn, &connTam, i, auxMsj, db, rooms, DIM); break; case CHECK_PASS: authPassword(conn, &connTam, i, auxMsj, db, rooms, DIM); break; case MP: mp(conn, &connTam, auxMsj, i, db); break; default: write(2, "ERROR: Recibido un mensaje mal formado\n", 39); break; } }else{ // hemos detectado una desconexión por el cerrado de la conexión closeConn(conn, &connPos, connTam, i, &connList, db); } } } } }//</editor-fold> return 0; }
void TestFindQuestionableNode() { COsGame game; game.Initialize("8"); CQPosition initialPos(game, 0); CQPosition questionablePosition; CBook book; bool drawToMover; // The position is not in book. FindQuestionableNode should return NULL. bool isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(!isQuestionable); // add the initial position to the book. FindQuestionableNode should return the initial position. const CBitBoard initialBitBoard(initialPos.BitBoard()); CMinimalReflection mr(initialBitBoard); CHeightInfoX heightInfoX(2, 4, false, initialBitBoard.NEmpty()); book.StoreLeaf(CMinimalReflection(initialBitBoard), heightInfoX, 0); isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(isQuestionable); TEST(questionablePosition==initialPos); // add the initial position to the book with a deviation of the deviation cutoff // Since this is bigger than the threshold for deviations, we won't count it. book.StoreLeaf(CMinimalReflection(initialBitBoard), heightInfoX, deviationCutoff); isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(!isQuestionable); // but if it's one less than the deviation cutoff, it's questionable book.StoreLeaf(CMinimalReflection(initialBitBoard), heightInfoX, deviationCutoff-1); isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(isQuestionable); TEST(questionablePosition==initialPos); // Also if it's negative... at the deviation cutoff is ok, one more is questionable book.StoreLeaf(CMinimalReflection(initialBitBoard), heightInfoX, -deviationCutoff); isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(!isQuestionable); book.StoreLeaf(CMinimalReflection(initialBitBoard), heightInfoX, 1-deviationCutoff); isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(isQuestionable); TEST(questionablePosition==initialPos); // This node is a draw, at +3/-3.. so it's ok const CBookData* bookData = book.FindData(initialBitBoard); // casting to remove const is a really bad idea... but no other easy way to test CBookValue& bookValue = (CBookValue&)(bookData->Values()); bookValue.vHeuristic = 0; bookValue.vMover = drawCutoff; bookValue.vOpponent = - drawCutoff; isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(!isQuestionable); TEST(questionablePosition==initialPos); CQPosition nextPos(initialPos); nextPos.MakeMove(CMove("F5")); const CBitBoard f5 = nextPos.BitBoard(); nextPos.MakeMove(CMove("D6")); const CBitBoard f5d6 = nextPos.BitBoard(); nextPos = initialPos; nextPos.MakeMove(CMove("F5")); nextPos.MakeMove(CMove("F6")); const CBitBoard f5f6 = nextPos.BitBoard(); // Now we have a questionable position, but it's not at the initial node // tree is: // f5 d6 : proven draw // f5 f6 : deviation with value drawValue book.StoreRoot(initialBitBoard, heightInfoX, 0, -16400); book.StoreRoot(f5, heightInfoX, 0, -16400); CHeightInfoX hixSolved = CHeightInfoX(f5f6.NEmpty(), 0, false, f5f6.NEmpty()); book.StoreLeaf(f5f6, hixSolved, 0); book.StoreLeaf(f5d6, heightInfoX, drawCutoff); book.NegamaxAll(); isQuestionable = book.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(isQuestionable); TEST(CMinimalReflection(questionablePosition.BitBoard())==CMinimalReflection(f5d6)); // This position has a questionable node, but it's not on the draw tree so it's not returned CBook book2; book2.StoreRoot(initialBitBoard, heightInfoX, -deviationCutoff, -16400); book2.StoreRoot(f5, heightInfoX, deviationCutoff, -16400); book2.StoreLeaf(f5f6, heightInfoX, -deviationCutoff); book2.StoreLeaf(f5d6, heightInfoX, 0); book2.NegamaxAll(); isQuestionable = book2.FindQuestionableNode(questionablePosition, drawToMover, initialPos, drawCutoff, deviationCutoff); TEST(!isQuestionable); }
int32 CreatureAI::VisualizeBoundary(uint32 duration, Unit* owner, bool fill) const { typedef std::pair<int32, int32> coordinate; if (!owner) return -1; if (!_boundary || _boundary->empty()) return LANG_CREATURE_MOVEMENT_NOT_BOUNDED; std::queue<coordinate> Q; std::unordered_set<coordinate> alreadyChecked; std::unordered_set<coordinate> outOfBounds; Position startPosition = owner->GetPosition(); if (!CheckBoundary(&startPosition)) // fall back to creature position { startPosition = me->GetPosition(); if (!CheckBoundary(&startPosition)) { startPosition = me->GetHomePosition(); if (!CheckBoundary(&startPosition)) // fall back to creature home position return LANG_CREATURE_NO_INTERIOR_POINT_FOUND; } } float spawnZ = startPosition.GetPositionZ() + BOUNDARY_VISUALIZE_SPAWN_HEIGHT; bool boundsWarning = false; Q.push({ 0,0 }); while (!Q.empty()) { coordinate front = Q.front(); bool hasOutOfBoundsNeighbor = false; for (coordinate off : std::initializer_list<coordinate>{{1,0}, {0,1}, {-1,0}, {0,-1}}) { coordinate next(front.first + off.first, front.second + off.second); if (next.first > BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.first < -BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.second > BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.second < -BOUNDARY_VISUALIZE_FAILSAFE_LIMIT) { boundsWarning = true; continue; } if (alreadyChecked.find(next) == alreadyChecked.end()) // never check a coordinate twice { Position nextPos(startPosition.GetPositionX() + next.first*BOUNDARY_VISUALIZE_STEP_SIZE, startPosition.GetPositionY() + next.second*BOUNDARY_VISUALIZE_STEP_SIZE, startPosition.GetPositionZ()); if (CheckBoundary(&nextPos)) Q.push(next); else { outOfBounds.insert(next); hasOutOfBoundsNeighbor = true; } alreadyChecked.insert(next); } else if (outOfBounds.find(next) != outOfBounds.end()) hasOutOfBoundsNeighbor = true; } if (fill || hasOutOfBoundsNeighbor) if (TempSummon* point = owner->SummonCreature(BOUNDARY_VISUALIZE_CREATURE, Position(startPosition.GetPositionX() + front.first*BOUNDARY_VISUALIZE_STEP_SIZE, startPosition.GetPositionY() + front.second*BOUNDARY_VISUALIZE_STEP_SIZE, spawnZ), TEMPSUMMON_TIMED_DESPAWN, duration * IN_MILLISECONDS)) { point->SetObjectScale(BOUNDARY_VISUALIZE_CREATURE_SCALE); point->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_STUNNED | UNIT_FLAG_IMMUNE_TO_NPC); if (!hasOutOfBoundsNeighbor) point->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } Q.pop(); } return boundsWarning ? LANG_CREATURE_MOVEMENT_MAYBE_UNBOUNDED : 0; }
void GameState::update(unsigned int lastInterval) { //TODO: Completar el método... //Vector3 nextPos(_terrain->getOrigin()); if (!Logic::MissionManager::GetInstance()->getBifurcation()){ Vector3 nextPos(Logic::MissionManager::GetInstance()->getGameCamera()->getCenter()); float speed = Logic::MissionManager::GetInstance()->getSpeed(); nextPos.z -= speed * lastInterval; Logic::MissionManager::GetInstance()->setCenter(nextPos);//Logic::MissionManager::GetInstance()->getPlayer()->getComponentAs<Logic::Position>("Position")->getPosition()); Logic::MissionManager::GetInstance()->getPlayer()->getComponentAs<Logic::PhysicCharacter>("PhysicCharacter")->setMovement(Vector3(0,0,-speed * lastInterval)); }else{ Vector3 step(Logic::MissionManager::GetInstance()->bifurcationStep(lastInterval)); Logic::MissionManager::GetInstance()->setCenter(Logic::MissionManager::GetInstance()->getGameCamera()->getCenter() + step); Logic::MissionManager::GetInstance()->getPlayer()->getComponentAs<Logic::PhysicCharacter>("PhysicCharacter")->setMovement(step); } // Entrada del teclado if(Core::Keyboard::IsKeyReleased(Core::Key::KEY_ESCAPE)) { // Establecemos el nuevo estado _application->pushState(MISSION_MENU_STATE_NAME); } /* else if(Core::Keyboard::IsKeyReleased(Core::Key::KEY_F12)) { _viewDebugInfo = !_viewDebugInfo; Logic::MissionManager::GetInstance()->getHUDController()->showInfoDebug(_viewDebugInfo); } */ Logic::MissionManager::GetInstance()->prepareUpdate(lastInterval); // Simulación física Physics::CServer::getSingletonPtr()->update(lastInterval*0.001f); // Actualizamos la lógica de juego. Logic::MissionManager::GetInstance()->update(lastInterval); _time += lastInterval; //std::stringstream text; //text << "Time: " << _time/1000; //_timeWindow->setText(text.str()); // Otenemos los frames por segundo if(_viewDebugInfo) { Ogre::RenderTarget::FrameStats info = _renderWin->getStatistics(); Logic::MissionManager::GetInstance()->getHUDController()->updateInfoDebug(info.lastFPS, (unsigned int) info.triangleCount); } // Mostramos la puntuación actual Logic::MissionManager::GetInstance()->getHUDController()->setScore((unsigned int) Logic::MissionManager::GetInstance()->getActualBonus()); //_time/1000); //Comprobamos si el jugador ha muerto. En ese caso, GAME OVER if (Logic::MissionManager::GetInstance()->getPlayer() && Logic::MissionManager::GetInstance()->getPlayer()->getComponentAs<Logic::Death>("Death")->isDead()) { _application->changeState(MISSION_FAILED_STATE_NAME); } /* Core::Entity * player = Logic::MissionManager::GetInstance()->getPlayer(); if(player) { Logic::Death * compDeath = player->getComponentAs<Logic::Death>("Death"); if(compDeath && compDeath->isDead()) { } } //*/ //Comprobamos si se ha llegado al final del nivel. if(Logic::MissionManager::GetInstance()->getEndOfLevel()) { _application->changeState(SHOW_STATISTICS_STATE_NAME); } }