I came across using insert and removeAt methods to make 2 elements swap their position in a list, like in the following code example:
var list = [1, 2];
list.insert(1, list.removeAt(0));
I did my best to grasp the logic behind, but I can't no matter what.
there is insert at position 1 and then remove at position 2. Is that mean that we insert in P1 what we remove from P2?
Could you explain how it works. Thanks
list.removeAt(int index1) removes the value at and returns the value at given index1.
Similarly list.insert(int index2, E element) inserts element E at given index2.
So what's happening is, when you call
var list = [1, 2];
list.insert(1, list.removeAt(0));
list.removeAt(0) removes the element at index 0 first and then returns 1(the element at position 0) then the list looks like [2] and the statement looks like list.insert(1,1); and , with element 2 at index 0, now the statement means to insert element 1 at index 1 so the list will be updated to [2,1] which is equivalent to swapping.
This works only because the element at position 0 is 1 what if there is some other element at position 0 then the insertion would result in undesired output.
Hope you get my point.
Related
Fairly new to Delphi, so forgive me if this is a trivial question.
I have the following:
TMsgDlgBtn = (mbYes, mbNo, mbOK, mbCancel, mbAbort, mbRetry, mbIgnore,
mbAll, mbNoToAll, mbYesToAll, mbHelp, mbClose);
TMsgDlgButtons = set of TMsgDlgBtn;
and this loop:
//Buttons is of type TMsgDlgButtons and value is [mbRetry, mbCancel]
for B := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do
if B in Buttons then
//Do something with the button B
It seems like no matter which order Buttons is in, it is always processed with mbCancel first, then mbRetry second. I saw that this is because of the order of TMsgDlgBtn so I tried this instead:
for B in Buttons do
//Do something with the button B
but it seems to iterate the same way - cancel first, then retry.
Is this because Buttons is a set? Is there any way to iterate through Buttons such that the order is respected?
Is there any way to iterate through Buttons such that the order is respected?
No, because the set doesn't hold the information of, in which order the set members were assigned to the set.
Explanation:
First you declare an enumeration type, TMsgDlgBtn. As you did not define any specific values, they are given the values 0, 1, 2, 3 ...
Then you declare the set type, TMsgDlgButtons. For members of sets, one bit is reserved for each value. So, 12 bits represent the membership of the buttons in the set.
When you assign Buttons := [mbRetry, mbCancel] the corresponding bits of those buttons are set in the Buttons set. The implementation of the first for loop checks the membership from the lowest to the highest bit, so it is natural that the test is performed on mbCancel before mbRetry. The implementation of the second for loop, is likely done in the same order, from lower to higher bits.
Using CGContext, drawing a dashed line starting with a painted segment is easy:
using (var ctx = UIGraphics.GetCurrentContext())
{
ctx.BeginPath();
//... draw a path here
var pattern = new float[] { 2, 2 };
ctx.SetLineDash(0, pattern);
ctx.DrawPath(CGPathDrawingMode.Stroke);
}
This draws a line looking like this "xx--xx--xx--xx--", where "x" means painted, and "-" means not painted.
Now I want to draw a line starting with an unpainted segment, that is: "--xx--xx--xx--xx". Is there an elegant way to achieve this? E.g. by telling iOS to start with an unpainted segment?
Given our example, a line starting with unpainted segments can be achieved using the phase parameter:
using (var ctx = UIGraphics.GetCurrentContext())
{
ctx.BeginPath();
//... draw a path here
var pattern = new float[] { 2, 2 };
ctx.SetLineDash(2, pattern);
ctx.DrawPath(CGPathDrawingMode.Stroke);
}
However, for more complex patterns (something like { 2, 4, 3, 7, 5, 6 }) using the phase parameter becomes more cumbersome. The pattern probably needs to be shifted in addition to the phase parameter.
To wrap up: Is it possible to elegantly create a line dash starting with an unpainted segment, without using the phase parameter?
Note: The code examples are written in C# (MonoTouch), but the question applies to native iOS code as well.
Simple solution
Using only the line dash feature, the given problem cannot be solved without the phase parameter. It can be solved by re-ordering the dash array, and setting a phase.
To start with an unpainted segment, move the last dash array entry to the front, and set a phase with the same value. E.g. when the pattern -xx-xx-xx-xx-xx... is desired, the dash array 1, 2 with phase 0 would lead to a pattern like x--x--x--x--.... The dash array 2, 1 with phase 2 would lead to the pattern -xx-xx-xx-xx-xx..., as desired.
Extended solution with adapted pattern repeating
It seems iOS always alternates between painted and unpainted segments, and does not reset when the dash array is repeated. So e.g. the dash array 1, 2, 1 would result in a line pattern looking like x--x-xx-x--x.... In our case, we wanted the whole pattern to repeat. That is, with the given dash array, the line pattern should look like x--xx--xx--xx....
To achieve that, we need to ensure that the dash array always has an even number of elements. In addition to re-ordering the dash array and setting a phase, we need to adapt and remove elements. There are four cases to consider.
1. Start with painted segment, even number of segments.
Nothing to do here. Use dash array as is. Phase is 0.
2. Start with unpainted segment, even number of segments.
Move the last dash array entry to the front, and set a phase with the same value. Refer to the simple example above.
3. Start with painted segment, odd number of segments.
Add the last dash array entry to the first entry. Remove the last entry. Set a phase equal to the original last dash array entry.
E.g. the dash array 1, 2, 1 would normally lead to a pattern x--x-xx-.... The dash array 2, 2 with a phase of 1 leads to the desired pattern x--xx--xx--....
4. Start with unpainted segment, odd number of segments.
Add the first dash array entry to the last entry. Remove the first entry. Set a phase equal to the sum of all entries minus the original first dash array entry (this essentially lets the pattern start near the end, exactly where we added the original first entry to the last entry).
E.g. the dash array 1, 2, 1 would normally lead to a pattern x--x-xx-.... The pattern 2, 2 with a phase of 3 leads to the desired pattern -xx--xx--xx....
Alternatives
An alternative which does not use line dash feature could be the one described by #user2320861. #user2320861 suggests to paint over a solid line with a patterned line, using the background color. This should work well when the background color is known, and a uniform background is used.
A variant for diverse backgrounds (e.g. images) could be to set a clipping mask (CGContextClipToMask) by drawing a patterned line. Then a solid line could be drawn with this clipping mask.
Let's say I have a collection of 10 objects, each with a unique position attribute 1-10.
If I would iterate the collection beginning from position 1, I would simply do:
collection.order(position: :asc).each
But how would I cycle through the collection but begin on another position, say position 5 (and consequently end on position 4)?
This should work:
collection.order(position: :asc).rotate(5).each
Docs
Working with Steema TeeChart graphs. (In particular objects: TChart, TChartSeries, TBarSeries, TLineSeries)
My task is to dynamically combine graphs when user selects some of the them, their values are added or subtracted based on XLabel value.
So this is what I get after selecting a couple of graphs and then deselecting them (which does the following:
Sets Series with DefaultBar/LineSeries
Adds values of selected graphs to the DefaultBar/LineSeries
Subtracts values of deselected graphs from the DefaultBar/LineSeries)
Result (logically) has to be 0 for all XLabels
But here is what I get:
Same graph without marks
Here are some of the values:
Can I somehow keep the actual values instead of rounded values (the ones represented on the graph), so that I will not have any rest after subtraction procedure?
I could do something like this to get rid of the rest (I know that the values will be big):
//bad solution
for Serie := 0 to Chart.SeriesCount - 1 do
for YValue := 0 to Chart.Series[Serie].YValues.Count - 1 do
if StrToFloat(FormatFloat('0.00', Chart.Series[Serie].YValue[YValue])) = 0 then
Chart.Series[Serie].YValue[YValue] := 0;
But this is not a very great solution - not scalable.
Probably related:
When I select only 1 graph and deselect it, then all the values are 0, the problem occurs when multiple graphs are selected (addition occurs)
I have a little logical problem over here.
As the title says, I try to build a boardgame as a computer-program (maybe with internet-support, but thats another story)
As for now, I have a map, which has some crossroads in it, hence I cannot simply define the fields as '1, 2, 3, 4, ...' because if there is a crossroad at field 10, I would have more than one field which has to be labeled 11 (Because then there is a field left and right of field 10, for example.)
So the problem is, if I cannot define the Board in numbers then I cannot simply get the possible positions a player can take when he rolls 2d6-dices with calculating 'Field-Nr. + RandomRange(1,6) + RandomRange(1,6)'
Does anybody have an idea, how to define a Map like this on another way, where I still can calculate the possible new-fields for Player X with a 2d6-dice-roll?
Thanks in advance.
If i understand well... (i don't thing so) this might help you. Just use dynamic arrays for your boardgame field and change your actions after the dimensions x,y .... Look at this "type Name = array of {array of ...} Base type; // Dynamic array"
It sounds like you have a graph of connected vertices. When a player is at a particular vertex of N edges, assuming N < 12, the new Field will be reached from traversing edge number N % ( rand(6) + rand(6) ).
You could also just do rand(12), but that would have an even distribution, unlike 2d6.
Instead of dynamic arrays, I would recommend using a linked-list of records to describe the surrounding cells, and traverse the player's location and possible moves using that linked-list.
First, define a record that describes each cell in your board's playable grid (the cells on the grid can be four-sided like a chessboard, or hexagonal like in Civilization V) ... each cell record should contain info such as coordinates, which players are also in that cell, any rewards/hazards/etc that would affect gameplay, etc. (you get the idea).
Finally, the linked-list joins all of these cells, effectively pointing to any connected cells. That way, all you'd need is the cell location of Player X and calculate possible moves over n amount of cells (determined by the dice roll), traversing the adjoining cells (that don't have hazards, for example).
If all you want is to track the possible roads, you can also use this approach to identify possible paths (instead of cells) Player X can travel on.