void Enemy::patrol() { std::discrete_distribution<int> dir_distribution({ 60, 10, 10, 10, 10 }); std::uniform_int_distribution<int> distance_distribution(50, 100); std::uniform_real_distribution<float> wait_time_distribution(1.f, 3.f); Direction dir = static_cast<Direction>(dir_distribution(mt)); int distance = distance_distribution(mt); stop_time = sf::seconds(wait_time_distribution(mt)); //Action selection Action patrol; patrol.thread_id = 1; patrol.action = get_action([this, dir, distance](sf::Time dt) { if (dir == Direction::Left) { moveLeft(distance); } else if (dir == Direction::Right) { moveRight(distance); } else if (dir == Direction::Up) { moveUp(distance); } else if (dir == Direction::Down) { moveDown(distance); } //else if (dir == Direction::None) { std::cout << "Stop time" << stop_time.asSeconds() << std::endl; wait(stop_time); } return false; }); //When we have 2 actions we stop action addition unsigned int max_actions = 2; if (action_tree.threadSize(patrol.thread_id) < max_actions) { pushAction(patrol); } //Action updating, each frame Action patrol_update; patrol_update.thread_id = 0; patrol_update.action = get_action([this](sf::Time dt) { if (getCurrentDirection() == Direction::Left) { goLeft(dt); } else if (getCurrentDirection() == Direction::Right) { goRight(dt); } else if (getCurrentDirection() == Direction::Up) { goUp(dt); } else if (getCurrentDirection() == Direction::Down) { goDown(dt); } return false; }); pushAction(patrol_update); }
void Enemy::chase(sf::Vector2f pos) { action_tree.deleteThread(1); Action chase; chase.thread_id = 1; chase.action = get_action([this, pos](sf::Time dt) { sf::Vector2f normal = normalize(pos.x - getPosition().x, pos.y - getPosition().y); float x = normal.x; float y = normal.y; if ((isCollisionDirection(Direction::Left) && x < 0.f) || (isCollisionDirection(Direction::Right) && x > 0.f)) { x = 0.f; if (y > 0.f) y = 1.f; else if (y < 0.f) y = -1.f; } if ((isCollisionDirection(Direction::Up) && y < 0.f) || (isCollisionDirection(Direction::Down) && y > 0.f)) { y = 0.f; if (x > 0.f)x = 1.f; else if (x < 0.f) x = -1.f; } x = x * 100.f * dt.asSeconds(); y = y * 100.f * dt.asSeconds(); playAnimation(); if (x > 0 && abs(x) > abs(y)) { if (getCurrentDirection() != Direction::Right) { setCurrentDirection(Direction::Right); changeAnimation(static_cast<int>(Animations::GoRight)); } } if (x < 0 && abs(x) > abs(y)) { if (getCurrentDirection() != Direction::Left) { setCurrentDirection(Direction::Left); changeAnimation(static_cast<int>(Animations::GoLeft)); } } if (y > 0 && abs(x) < abs(y)) { if (getCurrentDirection() != Direction::Down) { setCurrentDirection(Direction::Down); changeAnimation(static_cast<int>(Animations::GoDown)); } } if (y < 0 && abs(x) < abs(y)) { if (getCurrentDirection() != Direction::Up) { setCurrentDirection(Direction::Up); changeAnimation(static_cast<int>(Animations::GoUp)); } } //std::cout <<x << " " << y << std::endl; //std::cout << this->isCollisionDirection(Direction::Left) << " " << this->isCollisionDirection(Direction::Right) << " " << isCollisionDirection(Direction::Down) << " " << isCollisionDirection(Direction::Up) << std::endl; move(sf::Vector2f(x, y)); return false; }); pushAction(chase); }
int BACIComponent::registerAction(const BACIValue::Type type, Callback_ptr callback_p, const CBDescIn descIn, ActionImplementator* actionImplementator_p, int actionFunction) { ACS_TRACE("baci::BACIComponent::registerAction"); int callbackID = registerCallback(type, callback_p, descIn); if (callbackID==0) { return 0; } BACIAction* action_p = new BACIAction(actionImplementator_p, actionFunction, callbackID); if (action_p==0) { removeCallback(callbackID); return 0; } pushAction(action_p); return callbackID; }
/* function : leap_O_faith () called when there's no absolute choice to be made. this function chooses the cell with minimum number of possible values and assigns it a random value. it then pushes a LEAP_OF_FAITH action record on top of the action tracker. if this function fails, it sets the state flag _BAD_OPERATION. return value : Succeeded -> true. Failed -> false. */ bool sudokuBoard::leap_O_faith() { Cell *minPossib = &Data[0][0]; // find the minnimum possibilities cell that is free. for(Index i=0 ; i<9 ; i++) { for(Index j=0 ; j<9 ; j++) { if( Data[i][j] == sudokuValue::UNSET ) if( Data[i][j].countPossibilities() < minPossib->countPossibilities() ) minPossib = &Data[i][j]; } } // re-validate the chosen cell to check for errors. expectFor( *minPossib ); // if the possibilities have changed, then the current state of the board is invalid. if(minPossib->countPossibilities() == 0) { // set the bad operation flag and push a bad operation action. this->state |= sudokuState::_BAD_OPERATION; pushAction ( actionRecord( actionRecord::BAD_OPERATION , Cell() , false ) ); return false; } // else if the possibilities are correct : else { for(int i=1 ; i<10 ; i++) // cycle through the possibilities of the cell { if(minPossib->possible[i]) // find the first possible value. { Data[minPossib->row][minPossib->col].v = i; // return an action indicating the leap of faith. pushAction ( actionRecord( actionRecord::LEAP_OF_FAITH , Data[minPossib->row][minPossib->col] , true) ); return true; } } } // if couldn't find a guess, then report failure. return false; }
/* function : Correct_LeapOfFaith () pre-condition : the top of the action tracker is a wrong leap of faith action. this function corrects the error made at the last leap of faith, by choosing a value that is valid and not specified in the faultyValues vector. if this function fails, it sets the error stat _BAD_OPERATION and registers a BAD_OPERATION actionRecord on top of the action course. return value : - if succeeded and changed the value . . . . : true - if the value wasn't changed due to any circumstance : false */ bool sudokuBoard::Correct_LeapOfFaith() { actionRecord last = lastAction(); // check for a faulty LEAP_OF_FAITH action if( last != actionRecord::LEAP_OF_FAITH ) { pushAction( actionRecord ( actionRecord::BAD_OPERATION , Cell() , false) ); return false; } // check if the current leap is actually faulty, // by checking if it has any faulty values. if( last.faultyValues.size() == 0 ) { pushAction( actionRecord ( actionRecord::BAD_OPERATION , Cell() , false) ); return false; } // cycle through the possibilities for( Index i = 0 ; i<10 ; i++ ) { // if the number contained in (i) is a valid in the subject cell: if( last.subject->possible[i] ) { // validate the cell to avoid any possible errors in expectations : expectFor( *last.subject ); // check if that number exists in the faulty values: bool IsFaulty = false; for( Index j = 0 ; j < last.faultyValues.size() ; j++) { if( i == static_cast<int>(last.faultyValues[j]) ) { IsFaulty = true; break; } } // if the value is a faulty one, then look for another : if (IsFaulty) continue; // else, make this value the new choice of this leap : else { // set the new value : last.subject->v = i; // re-validate the cell : expectFor( *last.subject ); // report success : return true; } } } // if execution reaches this point, then a value hasn't been changed. // report failure. return false; }
void ControllerThread::Main() { PTime tBase; // base time for tStep multiplier PTimeInterval tStep(1); // 1ms, loop step (1Hz); up to 14 bytes per step for 115200 serial line PTime tNow; // current time PTime tThen; // expected execution time unsigned short i = 0; // multiplier for tStep // initialize PTRACE(1, "Arduino initialization"); char buffer[256]; PINDEX iRead = 0; PINDEX len = 0; // reset serial port pserial->ClearDTR(); pserial->ClearRTS(); pserial->ClearBreak(); pserial->SetDTR(); pserial->SetRTS(); // drop junk from serial port do { if (shutdown.Wait(0)) { return; }; pserial->Read(buffer, 256); // flush serial data } while (pserial->GetLastReadCount()); memset(buffer, 0, 256); // waiting for 3 heat beat do { if (shutdown.Wait(0)) { return; }; pserial->Read(buffer, 256); iRead = pserial->GetLastReadCount(); if (iRead == 2 && buffer[0] == 0 && buffer[1] == 0) { len += iRead; PTRACE(1, "HeatBeat from Arduino #" << len/2); }; } while(len < 6); PTRACE(1, "Arduino initialization done"); fReady = PTrue; // reset Arduino pushAction(0xFF, CMD_RESET); pushAction(0xFF, CMD_SETBASE0); // X1 pushAction(0xFF, calibrationTable[0]->GetAt(10000)); pushAction(0xFF, CMD_SETBASE1); // Y1 pushAction(0xFF, calibrationTable[1]->GetAt(10000)); pushAction(0xFF, CMD_SETBASE2); // X2 pushAction(0xFF, calibrationTable[2]->GetAt(10000)); pushAction(0xFF, CMD_SETBASE3); // Y2 pushAction(0xFF, calibrationTable[3]->GetAt(10000)); pushAction(0xFF, CMD_SETBASE4); // LT pushAction(0xFF, calibrationTable[4]->GetAt(10000)); pushAction(0xFF, CMD_SETBASE5); // RT pushAction(0xFF, calibrationTable[5]->GetAt(10000)); pushAction(0xFF, CMD_RESET); // main loop do { bool fNewActions = false; BYTE naction; PInt32l value; /* * get x, y, button and other events */ PTRACE(6, "Main\t" << dumpAction("actions before population: ")); while(popAction(&naction, &value)) { PIntArray *actionQueue = actionQueuePool[naction]; fNewActions = true; PTRACE(6, "Main\tadd new value to actionQueuePool[" << (int)naction << "] with queue size " << actionQueue->GetSize()); actionQueue->SetAt(actionQueue->GetSize(), value); }; if (fNewActions) { PTRACE(6, "Main\t" << dumpAction("actions after population: ")); summarizeActions(); // summarize action events by type PTRACE(6, "Main\t" << dumpAction("actions after summarization: ")); }; /* * process actions: * send current state to arduino * then receive state from arduino * and update actions after sucsessful transmit */ processActions(); /* * wait next tStep ms */ i++; tThen = tBase + tStep * i; tNow = PTime(); // reset multiplier if (i >= 255) { i = 0; tBase = tThen; }; // step was too long (tThen less than tNow) if (tNow.Compare(tThen) != LessThan) { PTRACE(6, "Main\tnow: " << tNow.AsString("h:m:s.uuuu") << " then: " << tThen.AsString("h:m:s.uuuu") << " i: " << (int)i << " diff: " << (tNow - tThen).GetMilliSeconds() << "ms"); i += (tNow - tThen).GetMilliSeconds() / tStep.GetMilliSeconds() + 1; // number of steps + 1 step tThen = tBase + tStep * i; PTRACE(6, "Main\tcorrected then: " << tThen.AsString("h:m:s.uuuu") << " i: " << (int)i); }; PTRACE(7, "Main\tstep " << (tThen - tNow).GetMilliSeconds() << "ms"); } while(!shutdown.Wait((tThen - tNow).GetMilliSeconds())); }