Arduino method making - c++

The code below is part of my "safe" program. I have to make 4 "guesses" (the password consists of 4 numbers). For each guess I use a few if statements but i was wondering if there is a way to make a method for each "guess". This way instead of these 4 sections of if-statements i would just have one Method.
if (turn == 1) {
if ((buttonState != lastButtonState) && buttonState == 1) {
guess1 = newValue;
turn = 2;
Printer();
}
lastButtonState = buttonState;
}
if (turn == 2) {
if ((buttonState != lastButtonState) && buttonState == 1) {
guess2 = newValue;
turn = 3;
Printer();
}
lastButtonState = buttonState;
}
if (turn == 3) {
if ((buttonState != lastButtonState) && buttonState == 1) {
guess3 = newValue;
turn = 4;
Printer();
}
lastButtonState = buttonState;
}
if (turn == 4) {
if ((buttonState != lastButtonState) && buttonState == 1) {
gok4 = nieuwewaarde;
beurt = 5;
Printer();
}
lastButtonState = buttonState;
}

Theoretically it should be possible to shrink it to something like this. Note you should use an array instead of a series of guess1, guess2, … variables.
int guess[4];
if ((buttonState != lastButtonState) && buttonState == 1) {
guess[turn-1] = newValue;
if (turn == 4)
{
gok4 = nieuwewaarde;
beurt = 5;
}
else
turn = turn+1;
Printer();
}
lastButtonState = buttonState;
You can adjust the +1/-1 if you count turn from 0. But with a broader view of what you would like to achieve, there might be other ways to write things.
Besides, Arduino code is not in C++, but AVR. The “user” code is Processing.

Related

Reassigning position within an array

I've been working on a dungeon crawling game, and I've hit an issue with moving the player's coordinates throughout my 2-d array. Currently, when choosing a move, the move is passed into the function, but the position is not reassigned. I've tried both pass my reference and by value.
Currently as written, the program gets the players move, but I don't think it's actually being passed into the updateMove function. I tried having the function cout << playerMove, but it doesn't show anything. Am I doing something to cause the move to not be passed into the updateMove function? I'm guessing this is why the move isn't updating.
I've added my main and the function in question:
int main()
{
// initialize random #
srand(static_cast<int>(time(NULL)));
do // play again loop
{
// define variables
bool win, lose;
char playerMove;
char dungeon[MAX_ROW][MAX_COL];
int cash;
displayInstructions(); // display instructions
initializeDungeon(dungeon); // initialize dungeon
do
{
setTraps(dungeon); // set traps
displayDungeon(dungeon); // display dungeon
playerMove = getMove(playerMove);
// check for valid move
// reassign player to new position
updateMove(playerMove, dungeon);
//update map now that move is legit
if (!win && !lose)
{
updateDungeon();
}
} while (!win && !lose);
} while (repeat());
}
void updateMove(char & playerMove, char dungeon[MAX_ROW][MAX_COL])
{
int px, py;
int dx = 0, dy = 0;
if(playerMove == UP && px != 0)
{
dx--;
}
else if (playerMove == DOWN && px != 7)
{
dx++;
}
else if (playerMove == LEFT && py != 0)
{
dy--;
}
else if (playerMove == RIGHT && py != 8)
{
dy++;
}
if(dx != 0 || dy != 0)
{
dungeon[px][py] = SPACE; // I updated this to be an 'empty' space based on my variables
px += dx;
py += dy;
dungeon[px][py] = PLAY;
}
} ````
Needing to iterate over the entire map to find the player is rather wasteful and slow. It also makes coding harder as you're seeing here.
You should store the player's position somewhere so you know it at a glance and can refer back to it for clearing the old position.
Something like this:
int px, py;
void updateMove(char playerMove, char dungeon[MAX_ROW][MAX_COL])
{
int dx = 0, dy = 0;
if(playerMove == 'u' && px != 0)
{
dx--;
}
else if (playerMove == 'd' && px != 8)
{
dx++;
}
else if (playerMove == 'l' && py != 0)
{
dy--;
}
else if (playerMove == 'r' && py != 9)
{
dy++;
}
if(dx != 0 || dy != 0) {
dungeon[px][py] = EMPTY;
px += dx;
py += dy;
dungeon[px][py] = PLAY;
}
}

Arduino Autonmous car if statements (ultrasonic)

I have run into a problem while creating the if statements for the autonomous car. The car skips most of the if statements and immeaditly goes to the else statement. The sensors give of the right values. Is it because i use "else if" statements or something else? The car is supposed to react to its surroundings, so i had to give it many if statements as possible. But instead it just does the last bit where it goes backwards waits goes backwards left and backwards right. So my question is do i have to add more if statements so it reacts better to its surroundings or is there more to it? Here is the code of the if statements:
if (sensors[0] >= 50 ) { //if the distance of the front sensor is greater than 50cm, than set Fwd true. Otherwise its false.
Fwd = true;
} else {
Fwd = false;
}
delay(50);
if ((Fwd == true) && (sensors[1] > 50) && (sensors[2] > 50)) {
fwd();
} else if ((Fwd == true) && (sensors[1] < 50)) {
fwdRight();
} else if ((Fwd == true) && (sensors[2] < 50)) {
fwdLeft();
} else if ((Fwd == false) && (sensors[1] < 50) && (sensors[2] < 50)) {
Stp();
} else if ((Fwd == false) && (sensors[1] < 50)) {
bwdRight();
} else if ((Fwd == false) && sensors[2] < 50) {
bwdRight();
} else {
Stp();
delay(1000);
bwd();
delay(500);
bwdLeft();
delay(500);
bwdRight();
}
Start by tidying up your code, and it may be obvious where things may be going wrong. For example, you are calling multiple checks to Fwd by doing:
if ((Fwd == true) && ... ) {
...
} else if ((Fwd == true) && ... ) {
...
} else if ((Fwd == true) && ... ) {
...
} else if ((Fwd == false) && ... ) {
...
} else if ((Fwd == false) && ... ) {
...
}
This uses up valuable resources in your program memory. It would be much more efficient to do a single check, and evaluate from there:
if (Fwd){
// Check sensor conditions here
} else {
// Check more sensor conditions here
}
In fact, you could probably omit the Fwd variable (unless you are using it elsewhere) altogether, saving you more memory space:
// Check whether to go forward or backwards.
// >= 50 - forward
// < 50 - backward
if (sensors[0] >= 50) {
// Check sensor conditions here
} else {
// Check more sensor conditions here
}
Overall, you could end up with something like:
// Check whether to go forward or backwards.
// >= 50 - forward
// < 50 - backward
if (sensors[0] >= 50) {
// Going forward, but which direction?
if (sensors[1] < 50) {
fwdRight();
} else if (sensors[2] < 50) {
fwdLeft();
} else {
// sensors[1] >= 50 AND sensors[2] >= 50
// Going straight forward
fwd();
}
} else {
// Check backward sensor conditions here
}
This answer might not directly answer your question, but it should help you diagnose better what is going on.

mesh.delete_face() caused abort()

I have tried to run the code below but got a error when using mesh.delete_face(*it, false);
vector<TriMesh::FaceHandle> terminalFaces;
OpenMesh::FPropHandleT<int> faceType;
OpenMesh::FPropHandleT<bool> faceChecked;
mesh.add_property(faceType, "face-type");
mesh.add_property(faceChecked, "face-checked");
tFillFacesProperty(mesh, faceChecked, false);
tClassifyFaces(mesh, faceType);
terminalFaces = tSplitJointFaces(mesh, faceType);
tClassifyFaces(mesh, faceType);
tAdjustAllVertices(mesh);
for (int i = 0; i < terminalFaces.size(); i++)
{
if (mesh.property(faceType, terminalFaces[i]) != FT_TERMINAL)
continue;
if (mesh.property(faceChecked, terminalFaces[i]))
continue;
vector<TriMesh::VertexHandle> collectedVs;
vector<TriMesh::FaceHandle> collectedFs;
for (TriMesh::FaceVertexIter fvi = mesh.fv_begin(terminalFaces[i]);
fvi != mesh.fv_end(terminalFaces[i]);
++fvi)
{
if (mesh.valence(*fvi) == 2) {
collectedVs.push_back(*fvi);
break;
}
}
assert(collectedVs.size() == 1);
while(1){
bool mustStop = false;
if (collectedFs.empty())
collectedFs.push_back(terminalFaces[i]);
else {
TriMesh::FaceHandle nextFh;
for (TriMesh::FaceFaceIter ffi = mesh.ff_begin(collectedFs.back());
ffi != mesh.ff_end(collectedFs.back());
++ffi)
{
if ((find(collectedFs.begin(), collectedFs.end(), *ffi) == collectedFs.end())
&& mesh.is_valid_handle(*ffi)
&& mesh.property(faceType, *ffi) != FT_NEW)
{
nextFh = *ffi;
break;
}
}
if (mesh.is_valid_handle(nextFh))
collectedFs.push_back(nextFh);
else
mustStop = true;
}
TriMesh::FaceHandle curfh = collectedFs.back();
mesh.property(faceChecked, curfh) = true;
int t = mesh.property(faceType, curfh);
if (t == FT_SLEEVE || t == FT_TERMINAL) {
TriMesh::HalfedgeHandle hh2check;
for (TriMesh::FaceHalfedgeIter fhi = mesh.fh_begin(curfh);
fhi != mesh.fh_end(curfh);
++fhi)
{
TriMesh::FaceHandle oppof = mesh.opposite_face_handle(*fhi);
if (mesh.is_valid_handle(oppof)
&& (find(collectedFs.begin(), collectedFs.end(),oppof) == collectedFs.end()))
{
hh2check = *fhi;
break;
}
}
assert(mesh.is_valid_handle(hh2check) && !mesh.is_boundary(hh2check));
// add new vertices
TriMesh::VertexHandle right, left;
right = mesh.from_vertex_handle(hh2check);
left = mesh.to_vertex_handle(hh2check);
assert(mesh.is_valid_handle(left) && mesh.is_valid_handle(right));
if ((find(collectedVs.begin(), collectedVs.end(), left) == collectedVs.end())
&& mesh.is_valid_handle(left))
collectedVs.insert(collectedVs.begin(), left);
if ((find(collectedVs.begin(), collectedVs.end(), right) == collectedVs.end())
&& mesh.is_valid_handle(right))
collectedVs.push_back(right);
bool inCircle = true;
TriMesh::Point center = (mesh.point(right) + mesh.point(left)) / 2.0;
double diamSq = tSqDist(mesh.point(right), mesh.point(left));
for (int i = 1; i < collectedVs.size() - 1; i++)
{
TriMesh::VertexHandle vh = collectedVs[i];
if (tSqDist(mesh.point(vh), center) * 4 > diamSq) {
inCircle = false;
break;
}
}
if (inCircle && !mustStop) {
continue;
}
else {
OpenMesh::IO::write_mesh(mesh, "outputtr.off");
for (vector<TriMesh::FaceHandle>::iterator it = collectedFs.begin(); it != collectedFs.end(); ++it){
mesh.delete_face(*it, false);
}
I used delete_face() in openmesh to remove one of the faces in mesh.
However, debugging always shows abort() and the error panel just like:
R6010 -abort() has been called
and the breakpoint was triggered by _CrtDbgBreak():
case 1: _CrtDbgBreak(); msgshown = 1;
Maybe the error is caused by a dangling reference/pointer, or an invalidated iterator. How could I fix it?
Just add "mesh.request_face_status();" and solved.

Tests randomly fails

I'm writing board game and I need following functionality: player rolls two dices, if he rolled doubles (same number on both dice), he gets to roll again, if he rolled doubles again, he goes to jail.
In my Game class it looks like that
void logic::Game::rollTheDice() {
m_throwsInCurrentTurn++;
int firstThrow = m_firstDice.roll();
int secondThrow = m_secondDice.roll();
m_totalRollResult += firstThrow + secondThrow;
if (firstThrow == secondThrow) m_doublesInCurrentTurn++;
}
std::string logic::Game::checkForDoubles() {
std::string message;
if (m_doublesInCurrentTurn == 0 && m_throwsInCurrentTurn == 1) {
m_canThrow = false;
m_canMove = true;
}
if (m_doublesInCurrentTurn == 1 && m_throwsInCurrentTurn == 1) {
message = "Doubles! Roll again.";
m_canThrow = true;
m_canMove = false;
}
if (m_doublesInCurrentTurn == 1 && m_throwsInCurrentTurn == 2) {
m_canThrow = false;
m_canMove = true;
}
if (m_doublesInCurrentTurn == 2 && m_throwsInCurrentTurn == 2) {
message = "Doubles again! You are going to jail.";
m_canThrow = false;
m_canMove = false;
getActivePlayer().lockInJail();
}
return message;
}
void logic::Game::setInMotion(unsigned number) {
m_players[m_activePlayer].startMoving();
m_players[m_activePlayer].incrementPosition(number);
}
m_canThrow basicly enables or disables ability to click "Roll the Dice" button, m_canMove decides if player token can start moving, m_players[m_activePlayer] is std::vector<Player>, startMoving() does that,
void logic::Player::startMoving() {
m_isMoving = true;
}
needed for token movement, so baiscly not relevant here.
Last function from Game class I need to show you is reset(), used mainly for testing purposes
void logic::Game::reset() {
m_throwsInCurrentTurn = 0;
m_doublesInCurrentTurn = 0;
m_totalRollResult = 0;
}
Now finnaly Unit Test that sometimes goes wrong. Sometimes, I mean completely random, like 1 out of 10-20 times.
//first throw is double, second throw is not
TEST_F(GameTestSuite, shouldFinishAfterSecondRollAndMove) {
auto game = m_sut.get();
do {
if (game.getThrowsInCurrentTurn() == 2) game.reset();
game.rollTheDice();
game.checkForDoubles();
if (game.getThrowsInCurrentTurn() == 1 && game.getDoublesInCurrentTurn() == 1) {
ASSERT_EQ(game.canThrow(), true);
ASSERT_EQ(game.canMove(), false);
}
} while (game.getThrowsInCurrentTurn() != 2 && game.getDoublesInCurrentTurn() != 1);
ASSERT_EQ(game.canThrow(), false);
ASSERT_EQ(game.canMove(), true);
game.setInMotion(game.getTotalRollResult());
ASSERT_EQ(game.getActivePlayer().isMoving(), true);
ASSERT_EQ(game.getActivePlayer().getPosition(), game.getTotalRollResult());
}
This line exactly, ASSERT_EQ(game.canThrow(), false); sometimes is equal true after do-while loop that should end once m_canThrow is set to false
Shouldn't:
} while (game.getThrowsInCurrentTurn() != 2 && game.getDoublesInCurrentTurn() != 1);
be
} while (game.getThrowsInCurrentTurn() != 2 && game.getDoublesInCurrentTurn() <= 1);
You want to allow up to two turns but 0 or 1 doubles.

Swapping a boolean value

I have been working on a menu that is injected with a dll into call of duty modern warfare 3. As I added options to the menu, I wanted to create a void that allows me to swap a bool value.
I have tried that:
void swapBool(bool& xbool)
{
if (xbool)
!xbool;
else if (!xbool)
xbool;
}
However, it isn't working.
This is what I want it to achieve:
if (displayInfoBox)
displayInfoBox = false;
else if (!displayInfoBox)
displayInfoBox = true;
Because of that many bools and many more coming i wanted to create a void...
if (offHostScroll == 0)
{
if (rgbEffects)
rgbEffects = false;
else if (!rgbEffects)
rgbEffects = true;
}
else if (offHostScroll == 1)
{
if (rgbMenu)
rgbMenu = false;
else if (!rgbMenu)
rgbMenu = true;
}
else if (offHostScroll == 2)
{
if (rgbBakcground)
rgbBakcground = false;
else if (!rgbBakcground)
rgbBakcground = true;
}
else if (offHostScroll == 3)
{
if (rgbMaps)
rgbMaps = false;
else if (!rgbMaps)
rgbMaps = true;
}
else if (offHostScroll == 4)
{
if (rgbInGameIcons)
rgbInGameIcons = false;
else if (!rgbInGameIcons)
rgbInGameIcons = true;
}
else if (offHostScroll == 5)
{
swapBool(displayInfoBox);
/*if (displayInfoBox)
displayInfoBox = false;
else if (!displayInfoBox)
displayInfoBox = true;*/
}
Simply:
displayInfoBox = !displayInfoBox;
or
xbool = !xbool;
! by itself does not change the value of the variable, it just creates a new value by negating it, so you have to reassign it.
You also will have to make swapBool pass xbool by reference.
void swapBool(bool& xbool);