Iterate through Set in order - delphi

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.

Related

MQL4 - How to hide some segments of an Indicator line?

I'm making a custom indicator.
I want to show theoretical brake out lines. So like, straight horizontal line segments. At the moment I have it working, using the semantics of DRAW_SECTION, except - obviously - all my segments are connected.
Is there a way to hide sections of the line that I don't need?
Or is there a better way to do it?
Two scenarios:
1.
SetIndexStyle( i, DRAW_NONE ); where i is the number of your buffer.
2.
#property indicator_buffers 3
IndicatorBuffers(4);
where
3 is a number of buffers to display,
4 is a total number of buffers. Even though you cannot see the buffer line on the chart, it is still accessed by iCustom( _Symbol, 0, indicator_name, ..., 3, shift );
where 3 is a zero-based reference to the buffer #4.
There is a way in MQL4 Indicators :
As documented, there is a special value == EMPTY_VALUE to serve exactly this purpose.
The EMPTY_VALUE constant usually corresponds to the values of indicators that are not shown in the chart.
Just assign, where plausible in your indicator code - either per-bar in assignment BreakOutBUFFER[i] = ( isHereBreakOut( i ) ) ? aLevel : EMPTY_VALUE;
or
by a pre-initialised ArrayInitialize( BreakOutBUFFER, EMPTY_VALUE ); and re-assigning only those cells, where your BreakOut-logic is POSACK'd, yet this is not a preferred way, as the first sooner-or-later coming ( automatic or not ) ArrayResize() will extend this Buffer, as documented:
... the elements will be added at the end of the array, their values will be undefined and in most cases will not be equal to init_value.
but .... not with the pre-set EMPTY_VALUE initialiser...
My option is, obviously, to go the former way

How do I create a calculator that with one input populates several label fields with different values?

I am new to using Xcode, slowly learning as I go. Attempting to create a calculator where I input a weight which will cause multiple different labels to display different values.
StoryBoard
This is how I have the storyboard setup. Basically behind the scenes I need the values calculated for each item. For example, I want to take the user input ("weight in kilograms" x 80) / 24 and have the result show up on the label to the right of "Fluid Rate". At the same time I will need to have a different calculation for each label.
Here is my code so far.
ViewController
One of the big issues I'm running into so far is that even when I set a value like, let fluid = 80, when I try to setup a calculation with it, Xcode tells me I cannot use a textfield with integers or binary operators. How do I go about making Xcode recognize the user input from the textfield as an integer?
I go through the problem you are facing I am giving the sample code snippet which might be helpful to you.
var fluidRate = 0
var GIR = 0
var enteredValue = 10
{
didSet {
fluidRate = enteredValue * 10 //consider your formula calculations
GIR = enteredValue * 50 //consider your formula calculations
//you can do like that
//self.fluidlabel.text = "\(fluidRate)"
}
}
enteredValue = 30
GIR
fluidRate
How do I go about making Xcode recognize the user input from the textfield as an integer?
Read the section Converting Strings in the documentation for Int.
That will get you from text to integer and it looks like you already know how to go the other way
HTH

view as property of model object alternative

I'm building an arithmetic app & in it there are subclasses of NSObject for Numbers and Digits.Both of these have corresponding view objects which take a Datasource (either number or digit) and a delegate, the view controller.
I have found that it is useful in getting the views & the model to work together to set the digit views as a property of their corresponding digits.
For example, the Number class has an NSMutableArray property that holds its digits.
If I want to find the size for the corresponding NumberView, I write can write code like this in the controller:
-(void) updateNumberViewFrameSize:(ACNumberView*) sender
{
NSUInteger i;
float width = 0, height = 0;
for (ACDigit* digit in [sender.dataSource returnNumberViewDataSource].digitArray)
{
width += digit.digitView.size.width;
height += digit.digitView.size.width;
}
sender.frame = CGRectMake(sender.frame.origin.x, sender.frame.origin.y, width, height);
}
The code works just fine, but I feel that it is not good practice to hold that pointer to the view from the model, even if the model isn't using it itself.
If it is bad practice, what are the potential pitfalls, and Is there a better way to achieve this type end ?
First: You are right. This is no good design.
Second: You calculate the size of a number view inside the model. But a number view should know its size itself. It knows the number through its data source and can get the digits. So it has all information for calculating its size.
To show the problem, just imagine (even this situation is on iOS not that common), that you display the same number at two places (= with to different number views). This would break your model. Why?
Solution: Put all code related to a graphic state (drawing, size, …) into the number view and digit view. On half of the way that will be additional work. But at the end, when every code is migrated to the view layer, it is as easy as computing it inside the model.

Boardgame-Map with crossroads etc

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.

How to get rid of the empty space in the right part of DBGrid Delphi

Although the question seems simple, I couldn't find the answer to it.
I have a DBGrid component with lots of columns, and as a result they don't fit into the page and scrollbar appears. I also have column-autofix mechanism, which makes each column have width of the longest element in the table. When I scroll DBGrid to the right-end there is an empty space after the last column. How to get rid of this space?
One solution that I see is to stretch the last column to fit the empty space. But I don't know how to find the length of this empty space! DbGrid.Width and DbGrid.ClientWidth only give length of the component part, but not the real length of the table. Any hints??
It's not always easy to get DBGrid to behave the way you want it to behave. I decided to use alternative db grids after one project with the standard implementation and I never looked back.
If you can use an alternative grid, you have many options to choose from. There's even a topic here on SO with lots of pointers. Among the free-with-source options, I've always been quite fond of the JVCL project.
Just one last tip: there are grids that offer options and customizing possibilities beyond what you can dream of. Be aware that there's a cost attached to this degree of freedom, e.g. it can make the component slow, hard to integrate in your code, or both.
I think I have found a solution (although it seems a little strange). In order to find the difference between column widths and real width of the DBgrid (that means find the width of the empty space left after last column), we need to keep track of which column is shown on the left now (what is current column that is scrolled to). We can do that using OnDrawColumnCell event, since it will draw only columns which are scrolled on now. Then we need to calculate sum of widths of all visible columns, and subtract that from DBGrid's width. P.S. Sorry for bad english
Ex code:
For i:=0 to Last do
if Vis[i] then
Begin
Sum:=Sum+DBG.Columns[i].Width;
Inc(Cnt);
End;
if dgColLines in DBG.Options then
Sum := Sum + Cnt;
//add indicator column width
if dgIndicator in DBG.Options then
Sum := Sum + IndicatorWidth;
Dif:=DBG.ClientWidth - Sum;
The below answer is quite good, but not effective at all because it is placed in the OnDrawColumnCell event, so if there are a large number of rows and/or collumns, the performance might fall.
Instead of that, place the same code not in a painting event, but int the AfterOpen (and AfterRefresh) event of the source dataset in order to execute it only once for each resultset.

Resources