multiple hits in loop after the break command - c#

I've got a strange problem. I'm creating a NUI for application and I binded some simple gestures to right and left arrow. The problem is when I start application. When I make gesture for the first time my application is hitting 2 times in a row. After that it works 100% as I want. Only the start is the problem.
I'm adding two Joints and timestamp to my history struct which is put into the ArrayList
this._history.Add(new HistoryItem()
{
timestamp = timestamp,
activeHand = hand,
controlJoint = controlJoint
}
);
then in foreach loop I'm comparing data
if (Math.Abs((hand.Position.X - item.controlJoint.Position.X)) < MainWindow.treshold && Math.Abs((hand.Position.Y - item.controlJoint.Position.Y)) < MainWindow.verticalTreshold)
If it hits I instantly break the lopp with
break;
after that I clear the history ArrayList
this._history.Clear();
So I don't get it. Why after the start it hits two times in a row ?
// edit
history ArrayList initialization
private List<HistoryItem> _history = new List<HistoryItem>(16);
in loop
foreach (HistoryItem item in this._history)
{
if ((hand.Position.X - item.controlJoint.Position.X) < MainWindow.treshold)
{
float tmp = (hand.Position.X - controlJoint.Position.X);
MainWindow.slideNumber++;
this._logger.Log("Next slide: " + MainWindow.slideNumber);
this._logger.Log(hand.Position.X + " - " + controlJoint.Position.X + " = " + tmp + " | " + MainWindow.treshold);
this.startTime = 0;
this.gestureStart = false;
answerFlag = true;
System.Windows.Forms.SendKeys.SendWait("{Right}");
break;
}
}
Now. As you can see i'm breaking here. So this code shouldn't be invoked second time in a row
How this clears something
// edit 2
I'll also add that to get into this part of code the gestureStart flag need to be set to true. As you can see after getting into the 'if' part here I'm setting it to false. So it is impossible that the code instantly can get to this part
// edit 3 WORKING WORKAROUND
I've created kind of workaround. I've added time control. I'm comparing timestamp of invoking the code and timestamp of last gesture recognition. If its too fast ( i meen couple of ms which it impossible to make ) I don't allow to hit an arrow. I'm not sure if it's a perfect solution but it is a working solution

Ok my problem was the code. Ofc a small bug untracable in the debug. I used one function to analyse a history of frames.
The method was working in 2 modes. I`ve detached that and created 2 diffrent methods, each for each task and now it works great

Related

C# Sudoku puzzle solver gets stuck while trying to backtrack to avoid bad values

I'm trying to get better at understanding recursion and I'm working on a program that is supposed to solve Sudoku puzzles by iterating over each cell in the puzzle and trying a value out of a list of possible values. After it drops in a value, it checks if doing so has solved the puzzle. If not, it continues on adding values and checking if doing so has solved the puzzle. There's a problem, though - I can see in my app's GUI that it eventually gets confused or stuck and starts attempting the same value insertion over and over. For example, here's an example of some logging that shows it being stuck:
Possible values: F
Old string: 086251B7D93+++C4
New string: 086251B7D93F++C4
As you can see, it's looking to see what value could possibly go into the cell after the 3 without violating the row, column, or box constraints. The only possible value is F, so it places it in there. But then it does the same thing over and over, and randomly starts attempting to edit other cells in other lines even though there are still +'s in this first row. It'll try to edit a row a few rows down, and it'll swap between doing that and then attempting this same scenario with the F repeatedly until the app crashes because of what Visual Studio thinks is a ContextSwitchDeadlock error.
What have I missed in my algorithm? Here is my method that tries to fill in the Sudoku puzzle:
public bool SolveGrid(List<Row> rows, List<Box> boxes)
{
textBox1.Clear()
foreach (var row in rows)
{
textBox1.AppendText(row.content + "\n");
}
if (ValidatorAgent.IsGridSolved(rows, boxes))
{
textBox2.AppendText("Success!");
successGrid = rows;
return true;
}
foreach (var row in rows)
{
foreach (var cell in row.content)
{
if (cell.Equals('+'))
{
var possibleValues = availableValues.Where(v => !ValidatorAgent.AreGridConstraintsBreached(cell, v, row, rows, boxes)).ToList();
if (!possibleValues.Any())
{
return false;
}
Console.WriteLine("Possible values: ");
possibleValues.ForEach(v => Console.Write(v.ToString()));
List<char> values = new List<char>();
possibleValues.ForEach(v => values.Add(v));
foreach (var possibleValue in values)
{
var oldContent = row.content;
var stringBuilder = new StringBuilder(row.content);
var indexToChange = row.content.IndexOf(cell);
stringBuilder[indexToChange] = possibleValue;
Console.WriteLine("Old string: " + oldContent);
Console.WriteLine("New string: " + stringBuilder.ToString());
var alteredPuzzle = BuilderAgent.BuildPuzzleCopy(rows);
alteredPuzzle.Single(r => r.yCoord == row.yCoord).content = stringBuilder.ToString();
var newBoxes = BuilderAgent.BuildBoxes(alteredPuzzle);
SolveGrid(alteredPuzzle, newBoxes);
}
}
}
}
return false;
}
I am pretty confident that my IsGridSolved method works correctly because I've tested it on puzzle solutions and found that it reported whether or not a puzzle was already solved. I've also tested my AreGridConstraintsBreached method with unit tests and also by eyeballing the results of the code, so I'm fairly confident in that code. It basically checks whether or not a cell's potential value is redundant due to the relevant row, column, or box already having that value. In Sudoku, when you place a value you need to make sure that the value 1) doesn't already exist in the row 2) doesn't already exist in the column and 3) doesn't already exist in the small box surrounding the cell. I feel like I'm missing something obvious in the algorithm itself, and that it isn't backtracking properly. I've tried fiddling with the SolveGrid method so that it takes in a list of validValues that are based off of the availableValues, with some pruning so that failed values are pruned out after each recursive call to SolveGrid but that didn't do anything besides keep the puzzle from even getting as far as it currently does. Any tips would be appreciated.

Programmatically check textboxes for completeness

I am looking for a way to figure out if textboxes are filled in in a specific way.
I have the following textboxes:
X1 Y1 Z1
X2 Y2 Z2
X3 Y3 Z3
Users are expected to input into them continuously. For example, if only X1,Y1 have texts, it's valid. While if X1,Z1 have texts while Y1 hasn't, it's invalid.
The reason for this is because:
string G1
if(!string.IsNullOrWhiteSpace(X1.Text) && string.IsNullOrWhiteSpace(Y1.Text))
{
G1 = "<" + X1.Text + ">";
}
else if(!string.IsNullOrWhiteSpace(X1.Text) && !string.IsNullOrWhiteSpace(Y1.Text))
{
G1 = "<" + X1.Text + ">, ";
}
If they skip around then what is printed in the end will not be what is expected.
If you can think of an easier way to do all of this, please share. I am sure that my way of attacking this problem is quite simplistic and inefficient.
The answer I found is to use an array of the text boxes, then to iterate over that to determine the text of the filled out boxes. Then add the text from those boxes to a list.
Finally I used joined all of the items of that list, in a way that made the final output correct.
Code I used in the end:
string[] cells = new string[] { X1.Text, Y1.Text, Z1.Text, X2.Text, Y2.Text, Z2.Text, X3.Text, Y3.Text, Z3.Text };
List<string> final_cells = new List<string>();
//Process array to determine which cells are full, adds full cells to list
for (int i = 0; i < cells.Length; i++)
{
if(cells[i].Length == 0)
{
//If cell is empty, continue to the next one
continue;
}
else
{
// If cell is full add its contents to the final_cells list
final_cells.Add(cells[i]);
}
}
//Join the list to one string
string content = string.Join(">, <", final_cells);
Also I am sorry that I did not better explain the original situation.
The purpose of the final application is to output text in a specific format for a minecraft plugin to read. The 3x3 of text boxes is meant to mimic the crafting grid from the game.
The type of recipe this part of the application is supposed to add does not need to use 9 items/blocks, and is not shaped (so it doesn't technically matter where the user inputs each item name). Because of this, the empty boxes have to be completely ignored, and the program needs to know if there is something coming next, so I could not simply say that the recipe ended at the first empty box.
An output of <item1> <item2> is not valid, the correct format is <item1>, <item2>. However the input can also be a single item... so this <only_item> is a valid format.
I hope it is clear both what the function of this is, but also why this was important for my application.

How to compare and detect overlapping gameObject Prefabs using maths

For some reason i my code doesn't properly compare when an instantiated object is being overlapped.
What i want to do is, to generate random platforms with different positions and scale (X).
And since its random, it is possible of overlapping happening. So in order to solve this problem, ive tried to compare each and every platform and see if it overlaps and when it does, it will delete itself and instantiate another one.
An addition to this question is,
If i have the overlapping problem solved, is it possible to make it so the platforms are at a certain distance away from each other, for X Y and Z.
So . .
What have i done wrong ?
What can i do ?
void Platform_Position_Scale_Generator(int i) {
posX[i] = Random.Range(minPosRange, maxPosRange + 1);
posY[i] = Random.Range(minPosRange, maxPosRange + 1);
posZ[i] = 0;
scaleX[i] = Random.Range(minScaleRange, maxScaleRange + 1);
scaleY[i] = 1;
scaleZ[i] = 1;
}
void Platform_Generator(int i) {
platformPrefabPosition[i].x = posX[i];
platformPrefabPosition[i].y = posY[i];
platformPrefabPosition[i].z = posZ[i];
Instantiate(platformPrefab, platformPrefabPosition[i], Quaternion.identity);
platformPrefab.transform.localScale = new Vector3(scaleX[i], 1, 1);
}
// Error with this
void Detect_Collision(int i) {
for(int f = 0; f < i; f++) {
for(int s = f + 1; s < i; s++) {
bool xOverlap = (posX[s] > posX[f] && posX[s] < posX[f] + scaleX[i]) || (posX[f] > posX[s] && posX[f] < posX[s] + scaleX[i]);
bool yOverlap = (posY[s] > posY[f] && posY[s] < posY[f] + scaleY[i]) || (posY[f] > posY[s] && posY[f] < posY[s] + scaleY[i]);
if(xOverlap && yOverlap) {
Debug.Log("xOverlap: " + xOverlap + " yOverlap: " + yOverlap);
}
else {
//Debug.Log("xOverlap: " + xOverlap + " yOverlap: " + yOverlap);
}
}
}
}
I wouldn't recommend using completely random generation for something like this, as it can easily create something totally unplayable, and making it playable can be more difficult than trying a more methodical approach.
One interesting approach could be the one shown in this video:
https://www.youtube.com/watch?v=VkGG9Umag0M
That approach is using pre-built chunks of levels manually generated to be playable, that are later randomly chosen in run-time, to create infinite levels.
Another approach could be dynamically generating a sequence of "viable" platforms.
I'm assuming this is a 2D platform game, but the same logic could apply to other types.
For example, the following sequence:
Add a platform on the left edge (random Y position and size, if desired).
Determine viable positions of the next platform to the right and vertically, taking into account both the end position of the previous platform and other things, such as jumping distance. That would give you a max position at which you can place things and still have the player make it. You can use that max and possibly a min. distance to chose a random value between them and still have a viable platform without overlaps.
Repeat step 2 until you reach some end condition, such as size of level, amount of platforms, etc.
You can also add a more complex logic, such as allowing overlaps on one axis as long as there isn't any on the other axis, or a minimum separation between both. That way you could get two nearly parallel platforms, and things like that.
Other rules could be more complex, expecting an actual specific solution from the player, such as double-jumps, bouncing off walls, etc. In that scenario you could have item 2 just be one of many generation strategies from which to chose from.
This type of generation would also be much less expensive than actual instantiation and deletion in case of collisions.
NOTE:
If you still want to stick to 100% random generation, but guarantee gaps between platforms. Just assume an "imaginary" border surrounding the actual platform. Instead of just taking into account current real points, just add offsets to them when testing collisions.
You should be able to test intersection without physics, using something similar to what is show here:
http://answers.unity3d.com/questions/581014/2d-collision-detection-box-intersection-without-ph.html
if (object1.renderer.bounds.Intersects(object2.renderer.bounds)) {
// Do some stuff
}

Select text from line A to line B in richtextbox

i'm looking for a way to select text between two lines (A and B) in a richtextbox.
I tried something like this:
richTextBox1.Select
(
richTextBox1.GetFirstCharIndexFromLine(parentesi_inizio[current_idx]),
(
richTextBox1.GetFirstCharIndexFromLine(parentesi_fine[current_idx]) -
richTextBox1.GetFirstCharIndexFromLine(parentesi_inizio[current_idx]) + 1
)
);
Inside parentesi_inizio and parentesi_fine i have the line number, i should select from line A (parentesi_inizio) to B (parentesi_fine).
After some tests i think the problem is this:
richTextBox1.GetFirstCharIndexFromLine(parentesi_fine[current_idx]) -
richTextBox1.GetFirstCharIndexFromLine(parentesi_inizio[current_idx]) + 1
This code works fine at first, but I noticed that after a while 'begins to show results stoner.
I did further testing and the lines are correct (ie, refer to the right spot) whereas "Select" does not select the entire portion or does it incorrectly (selecting parts that do not have to)
( I used google translate for the last part )
EDIT:
Imagine this text:
Hello
World || A points here (Line 1)
Guys!
This
is
a || B points here (Line 5)
line
I need to Select (not get text) this text:
World
Guys!
This
is
a
in the richtextbox.
Example images:
Case 1:
Case 2:
Thats is what i want and what the code i posted do, but after a while the code starts to bug as i said above (at the start).
EDIT 2:
I changed my code to this after varocarbas reply
richTextBox1.Select (
richTextBox1.GetFirstCharIndexFromLine(parentesi_inizio[current_idx]),
richTextBox1.GetFirstCharIndexFromLine(parentesi_inizio[current_idx])
+ count_length(parentesi_inizio[current_idx], parentesi_fine[current_idx]) );
where count_length is
private int count_length(int A, int B)
{
// A => first line
// B => last line
int tot = 0;
for (int i = A; i <= B; ++i)
{
// read the length of every line between A and B
tot += richTextBox1.Lines[i].Length - 1;
}
// return it
return tot;
}
but now the code not work in every case.. anyway here is a screen of a bugged case using the old code (the code posted at the start of the question)
(source: site11.com)
it select right from the first { but not reach the last } (i do some checks here and the problem is the subtraction not the lines num.)
EDIT 3:
I'm ready sorry varocarbas, i think i just wasted your time.. after see my screen i noticed the problem might be the word wrap i tried to disable it and seems now works ok.. sorry for your time.
Why not relying on the lines[] array directly?
string line2 = richTextBox1.lines[1];
Bear in mind that it has its own indexing, that is, to get the first character in the third line you can do:
int firstChar3 = richTextBox1.lines[2].Substring(0, 1);
To refer to the whole richTextBox indexing system, you can rely also on GetFirstCharIndexFromLine. That is:
int startIndexLine2 = richTextBox1.GetFirstCharIndexFromLine(1); //Start index line2
int endIndexLine2 = startIndexLine2 + richTextBox1.lines[1].length - 1; //End index line2
-------- AFTER UPDATED QUESTION
Sorry about that, but I cannot see the code in the links you provided. But the code below should deliver the outputs you want:
int curStart = richTextBox1.GetFirstCharIndexFromLine(2);
richTextBox1.Select(curStart, richTextBox1.Lines[2].Length);
string curText = richTextBox1.SelectedText; -> "Guys!"
curStart = richTextBox1.GetFirstCharIndexFromLine(3);
richTextBox1.Select(curStart, richTextBox1.Lines[3].Length);
curText = richTextBox1.SelectedText; -> "This"
curStart = richTextBox1.GetFirstCharIndexFromLine(4);
richTextBox1.Select(curStart, richTextBox1.Lines[4].Length);
curText = richTextBox1.SelectedText; -> "is"

Determine if correct route was taken

I'm developing a C# Winforms app where I need to determine if a truck took a specifed route, and passed through the points in the correct order. An example of valid routes would be as follows:
ROUTE 1
Entry gate 1
Scale gate entry side
Scale gate exit side
Exit gate 1
ROUTE 2
Entry gate 2
Scale gate entry side
Scale gate exit side
Exit gate 2
The scale gates are the same for both routes, but the entry and exit gates are what I need to worry about. If a truck enters in through gate 1 and exits through the gate 1, then the route followed was correct. However, if a truck enters gate 2 and exits through gate 1, then I need to send a notification.
Each gate has hardware configured as a read point. When the truck passes the read point a record is created in the database with the timestamp. I have a timer set up so that at the specified interval it retrieves a list of the valid the truck ID's. It then retrieves the read points that each truck passed within a specified time period and stores those in a list as well. What I'm not sure of is how to compare the "correct route" list with the list of read points that the truck passed. Right now I'm going on the basis that each truck will only make the trip once a day, and will tweak for additional trips after I get this covered.
Here's my code for the timer
private void tmr_Tick(object sender, EventArgs e)
{
int maxTime = int.Parse(AppSettings.GetAppSetting("MaxTime"));
List<string> _assets = new List<string>();
List<ReadPoint> _assetReads = new List<ReadPoint>();
//Get the list of assets to process
DataSet ds = du.ExecuteTextCommand("SELECT DISTINCT AssetId FROM " +
"(SELECT a.TagId, a.AssetId, a.Description, rp.Comments, DateScanned " +
"FROM AssetsReads ar JOIN Assets a on ar.AssetTagID = a.AssetTagID " +
"JOIN ReadPointLocations rp on " +
"ar.ReadPointLocationsID = rp.ReadPointLocationsID) AS AssetResult " +
"ORDER BY AssetId");
if (ds != null && ds.Tables[0].Rows.Count > 0)
{
foreach (DataRow dr in ds.Tables[0].Rows)
{
_assets.Add(dr["AssetId"].ToString());
}
}
//Loop through and process the assets
foreach (string asset in _assets)
{
ds = du.ExecuteTextCommand("SELECT a.TagId, a.AssetId, a.Description, " +
"rp.ReadPointLocationId, rp.Comments, DateScanned " +
"FROM AssetsReads ar JOIN Assets a on ar.AssetTagID = a.AssetTagID " +
"JOIN ReadPointLocations rp on " +
"ar.ReadPointLocationsID = rp.ReadPointLocationsID " +
"WHERE a.AssetID = '" + asset + "' ORDER BY DateScanned");
if (ds != null && ds.Tables[0].Rows.Count > 0)
{
_assetReads.Clear();
foreach (DataRow dr in ds.Tables[0].Rows)
{
ReadPoint ar = new ReadPoint();
ar.ReadPointLocationId = int.Parse(dr["ReadPointLocationId"].ToString());
ar.ReadpointName = dr["Comments"].ToString();
ar.DateScanned = DateTime.Parse(dr["DateScanned"].ToString());
_assetReads.Add(ar);
}
//Check to see if the asset has been seen in the last (MaxTime) minutes
if (DateTime.Parse(_assetReads[0].DateScanned.ToString()) < DateTime.Now)
{
///////////////////////
//Send notification
///////////////////////
continue;
}
//Determine the correct route to follow
Route currentRoute = null;
foreach (Route rt in _routes)
{
foreach (ReadPoint rp in rt.ReadPoints)
{
if (_assetReads[0].ReadPointLocationId == rp.ReadPointLocationId)
{
currentRoute = rt;
break;
}
}
if (currentRoute != null)
break;
}
//Check if the route was correctly followed
if (currentRoute != null)
{
//////////////////////////////
//This is where I'm stuck
//////////////////////////////
}
}
}
}
Well, I think you're really close here. You have a list of the ReadPointLocations (gates) the Asset (truck) has been through, in the order the truck went through the gates. You also have a list of the "proper" paths through these gates, and can identify which one should have been followed, based on which gate the truck went through first. The only thing left to do is to line up the truck's gate reads next to the expected reads, and verify that the truck went through all the gates it should have, in order:
//Check if the route was correctly followed
if (currentRoute != null)
{
var gatesInOrder = 0;
for(var i=0; i<_assetReads.Length; i++)
{
if(_assetReads[i].ReadPointLocationId == currentRoute[gatesInOrder])
//gate crossed in order; increment to next gate
gatesInOrder++;
}
//if we didn't get to the end of the route, send a notification
if(gatesInOrder != currentRoute.Length)
{
///////////////////////
//Send notification
///////////////////////
}
}
Now, this assumes two things. First, that all reads are performed without error. I can tell you from experience that location scans are missed with a very high frequency, even in automated systems. This means that if your entry gate scan was missed, you won't be able to determine which gate the truck should have exited through; you'll pick a Route (probably Gate 1) based on the first read you have, which is the scale entry gate, but because that node is common to both the Gate 1 and Gate 2 paths, you'll falsely notify that the truck exited through the wrong gate if the truck exits through Gate 2, even if it entered through Gate 2. In order to avoid this, you'll have to be able to identify gates in each Route that are unique to that Route (in this case, the entry and exit gates) and identify the proper route to use based on the first gate scan for one of those locations, and not just any location. You'll now have picked the proper route, but you won't find the entry gate scan; you can detect this and send a different "gate scan missed" notification.
Second, we assume that once a truck enters a route, that it must continue through that path and cannot deviate at any point. Nothing can be done out of order. So, in a more complex example, let's say the truck also goes through a simple inspection (taillights working, no visible leaks, tire tread OK, no billowing smoke at idle, etc). If the inspection and weighing can happen in either order, you would falsely send a notification with the above algorithm if the weighing and inspection happened in the opposite order than expected. You can avoid this naively by simply checking that all of the proper path's locations were scanned at some point, but that wouldn't catch, for instance, a truck going the wrong way through the whole thing. If that's possible then you'll need something more complex, such as an overall route map with conditional paths (you may proceed either to the weighing or the inspection gate from either entry gate, then from the inspection exit if you haven't been weighed you must proceed to the weighing entry and vice-versa, while if you have been through both sub-paths, you must proceed to exit gate 1 if you went through entry gate 1, or exit 2 if you entered through entry 2.

Categories