Not really a c/c++ person so I was hoping someone could direct me to the files that contain the main calculations of the game?
I am specifically interested in how things are calculated when deciding if the person 'wins' or 'loses' (generally speaking) during events like running/standing/etc.
In other words, winning/losing will be based on many factors: what are they? What are the formulae?
You didn't reference the source, so I Googled DopeWars and found this:
http://dopewars.sourceforge.net/
Looking into the source, serverside.h/c seems to be what you are looking for. But keep in mind a lot of the limits are already predefined in dopewars.c. Take a look at the drug prices in this struct:
struct DRUG DefaultDrug[] = {
/* The names of the default drugs, and the messages displayed when they
* are specially cheap or expensive */
{N_("Acid"), 1000, 4400, TRUE, FALSE,
N_("The market is flooded with cheap home-made acid!")},
{N_("Cocaine"), 15000, 29000, FALSE, TRUE, ""},
}
Note: sample struct is not complete. Please review the source to see the full listing.
The actual functionality that validates the actions chosen by the player exists in serverside.c.
It is up to the "server" (game engine) to validate the players choice and next step to be taken and communicate it back to the client. The client in this case can be a GUI or Curses (command line) driven client. It is the clients responsibility to update the screen, get new input from the server (be it typing characters for input or mouse clicks).
Related
colleagues! We are developing a web application which has functionality to represent the organizational structure of current organization(a bank, for example). Organizational structure is represented as a parent-child relationships where each node has only one parent and each parent may have zero or more children. When the amount of entities(orgUnits) was comparable small, about 500 entities, our old method worked well. Generally, we used recursion to get all parent-child entities and passed it as a JSON document to browser where frontend part parsed this document and rendered it for user. Problems started when we uploaded the organizational structure of another organization(another bank) and had 6000 active orgUnits. Obviously fetching all orgUnits was not an option. We started to use request param depth to control recursion level but it didn't solve the problem of fetching child entities because each parent can have one or more children. For example, we had a parent orgUnit that had 100 children and any of this child could have one or more children. This method also loaded all orgUnits on this level even if it wasn't necessary. Right now i'm looking for solution that will keep number of orgUnits per HTTP request relatively small and browser won't freeze while rendering it. My idea is simple:
Paginate results somehow;
Only return additional child orgUnits when user wants it;
Our OrgUnitDTO looks like this:
{
"id": "a4f51de5-36f3-258c-232d-3d617c07fefc",
"extId": null,
"type": "OrgUnit",
"orgId": "99beadc8-831a-f6ab-fee9-11143d43ccd1",
"parentId": "99beadc8-831a-f6ab-fee9-11143d43ccd1",
"code": "second-level-test-department",
"name": "name",
"note": "note",
"manager": null,
"children": [], // children property has objects of the same type
"createdBy": "userName",
"updatedBy": "userName",
"createdAt": "2020-09-04T06:23:53.793Z",
"updatedAt": "2020-09-04T06:23:53.795Z",
"sortOrder": 0,
"isManager": false
}
That's how it looks in GUI:
screenshot
I'm looking for your suggestions for backend and frontend as well!
In case it matters we use Spring-Boot and Hibernate.
Here is not a matter of framework used or technology.
Your question is more about the solution.
Rule of thumb: A human can interact only with few data at a time, so don't fetch or display a lot of data, is useless and slow.
I've dealt with a similar problem in the past and solved this way, but there may be better solutions of course:
I've created a backend function that a client can call to fill the page the first time is loaded so that you can get the first N levels of depth with an integer parameter (ie. 2 or 3) starting from a node of the tree (null if you want to start from the top).
I've added a search function (both on FE and BE) to let the user jump immediately to a position he already knows (ie. an employee name): the function returns only the JSON of the nodes that are composing the path to the founded node. Other nodes can be expanded with a [+] button or something like that, just to be hyperfast and concise in outputting data. Usually, if you search for a person in an org chart, you want to know immediately who are his bosses and nothing else.
Children for each node were not so many in my case, so I've not optimized here, but in your case, you can implement lazy loading of data with pagination if you have more than X children at the same level. You can use a \/ icon to load more nodes when the user clicks or you can do it automagically when the user scrolls down the page. It is up to you. It is up to you decide also the number of nodes to load after paging. You can make this responsive, you load more nodes if the screen has space to display them.
To open each subsequent node call the function you used at the first-page loading only when the user clicks on the [+] passing the current node id and 1 as parameters to specify you want only one level more.
To implement the FE part I've used jstree and jstreegrid.
General hint: choose the FE part library first, THEN create backend functions, it will be easier and you'll make fewer refactorings.
Let's say I am the technical lead for a software company specializing in writing applications for chefs that help organize recipes. Starting out we are developing one app for bakers who make cakes and another for sushi chefs. One of the requirements is to create a standard file format for importing and exporting recipes. (This file format will go on to be an industry standard with other companies using it to interface with our products) we are faced with two options: Make a standard recipes format (lets say .recipe) which uses common properties where applicable and optional properties where they differ, or making independent formats for each application (let us say .sushi and .cake).
Imagine the file format would look something like this for sushi:
{
"name":"Big California",
"type":"sushi",
"spiciness": 0,
"ingredients": [
{
"name":"rice"
"amount": 20.0,
"units": "ounces"
},
{
...
}
],
}
and imagine the file format would look something like this for cakes:
{
"name":"Wedding Cake",
"type":"cake",
"layers": 3,
"ingredients": [
{
"name":"flour"
"amount": 40.0,
"units": "ounces"
},
{
...
}
],
}
Notice the file formats are very similar with only the spiciness and layers properties differing between them. Undoubtedly as the applications grow in complexity and sophistication, and will cause many more specialized properties to be added. There will also be more applications added to the suite for other types of chefs. With this context,
Is it wiser to have each application read/write .recipe files that adhere to a somewhat standardized interface, or is it wiser to remove all interdependence and have each application read/write their respective .sushi and .cake file types?
This kind of thing get be a very, very deep thing to get right. I think a lot of it depends on what you want to be able to do with recipes beyond simply displaying them for use by a chef.
For example, does one want to normalise data across the whole system? That is, when a recipe specifies "flour", what do you want to say about that flour, and how standardised do you want that to be? Imagine a chef is preparing an entire menu, and wants to know how much "plain white high gluten zero additives flour" is used by all the recipes in that menu. They might want to know this so they know how much to buy. There's actually quite a lot you can say about just flour that means simply having "flour" as a data item in a recipe may not go far enough.
The "modern" way of going about these things is to simply have plain text fields, and rely on some kind of flexible search to make equivalency associations between fields like "flour, white, plain, strong" and "high gluten white flour". That's what Google does...
The "proper" way to do it is to come up with a rigid schema that allows "flour" to be fully specified. It's going to be hard to come up with a file / database format schema that can exhaustively and unambiguously describe every single possible aspect of "flour". And if you take it too far, then you have the problem of making associations between two different records of "flour" that, for all reasonable purposes are identical, but differ in some minor aspect. Suppose you had a field for particle size; the search would have to be clever enough to realise that there's no real difference in flours that differ by, for example, 0.5 micrometer in average particle size.
We've discussed the possible extent to the definition of a "flour". One also has to consider the method by which the ingredient is prepared. That adds a whole new dimension of difficulty. And then one would have to desribed all the concievable kitchen utensils too. One can see the attractions of free text...
With that in mind, I would aim to have a single file format (.recipe), but not to break down the data too much. I would forget about trying to categorise each and every ingredient down to the last possible level of detail. Instead, for each ingredient I'd have a free text description, then perhaps a well structured quantity field (e.g. a number and a unit, 1 and cup), and finally a piece of free text describing the ingredient preparation (e.g. sieved). Then I'd have something that describes a preparation step, referencing the ingredients; that would have some free text fields and structured fields ("sieve the", , "into a bowl"). The file will contain a list of these. You might also have a list of required utensils, and a general description field too. You'll be wanting to add structured fields for recipe metadata (e.g. 'cake', or 'sushi', or serves 2).
Or something like that. Having some structure allows some additional functionality to be implemented (e.g. tidy layout of the recipe on a screen). Just having a single free-text field for the whole thing means that it'd be difficult to add, say, an ingredient ordering feature - who is to say what lines in the text represent ingredients?
Having separate file formats would involve coming up with a large number of schema. It would be even more unmanagable.
Suppose I have a resource called Person. I can update Person entities by doing a POST to /data/Person/{ID}. Suppose for simplicity that a person has three properties, first name, last name, and age.
GET /data/Person/1 yields something like:
{ id: 1, firstName: "John", lastName: "Smith", age: 30 }.
My question is about updates to this person and the semantics of the services that do this. Suppose I wanted to update John, he's now 31. In terms of design approach, I've seen APIs work two ways:
Option 1:
POST /data/Person/1 with { id: 1, age: 31 } does the right thing. Implicitly, any property that isn't mentioned isn't updated.
Option 2:
POST /data/Person/1 with the full object that would have been received by GET -- all properties must be specified, even if many don't change, because the API (in the presence of a missing property) would assume that its proper value is null.
Which option is correct from a recommended design perspective? Option 1 is attractive because it's short and simple, but has the downside of being ambiguous in some cases. Option 2 has you sending a lot of data back and forth even if it's not changing, and doesn't tell the server what's really important about this payload (only the age changed).
Option 1 - updating a subset of the resource - is now formalised in HTTP as the PATCH method. Option 2 - updating the whole resource - is the PUT method.
In real-world scenarios, it's common to want to upload only a subset of the resource. This is better for performance of the request and modularity/diversity of clients.
For that reason, PATCH is now more useful than PUT in a typical API (imo), though you can support both if you want to. There are a few corner cases where a platform may not support PATCH, but I believe they are rare now.
If you do support both, don't just make them interchangeable. The difference with PUT is, if it receives a subset, it should assume the whole thing was uploaded, so should then apply default properties to those that were omitted, or return an error if they are required. Whereas PATCH would just ignore those omitted properties.
I read quite a lot about the visitor pattern and its supposed advantages. To me however it seems they are not that much advantages when applied in practice:
"Convenient" and "elegant" seems to mean lots and lots of boilerplate code
Therefore, the code is hard to follow. Also 'accept'/'visit' is not very descriptive
Even uglier boilerplate code if your programming language has no method overloading (i.e. Vala)
You cannot in general add new operations to an existing type hierarchy without modification of all classes, since you need new 'accept'/'visit' methods everywhere as soon as you need an operation with different parameters and/or return value (changes to classes all over the place is one thing this design pattern was supposed to avoid!?)
Adding a new type to the type hierarchy requires changes to all visitors. Also, your visitors cannot simply ignore a type - you need to create an empty visit method (boilerplate again)
It all just seems to be an awful lot of work when all you want to do is actually:
// Pseudocode
int SomeOperation(ISomeAbstractThing obj) {
switch (type of obj) {
case Foo: // do Foo-specific stuff here
case Bar: // do Bar-specific stuff here
case Baz: // do Baz-specific stuff here
default: return 0; // do some sensible default if type unknown or if we don't care
}
}
The only real advantage I see (which btw i haven't seen mentioned anywhere): The visitor pattern is probably the fastest method to implement the above code snippet in terms of cpu time (if you don't have a language with double dispatch or efficient type comparison in the fashion of the pseudocode above).
Questions:
So, what advantages of the visitor pattern have I missed?
What alternative concepts/data structures could be used to make the above fictional code sample run equally fast?
For as far as I have seen so far there are two uses / benefits for the visitor design pattern:
Double dispatch
Separate data structures from the operations on them
Double dispatch
Let's say you have a Vehicle class and a VehicleWasher class. The VehicleWasher has a Wash(Vehicle) method:
VehicleWasher
Wash(Vehicle)
Vehicle
Additionally we also have specific vehicles like a car and in the future we'll also have other specific vehicles. For this we have a Car class but also a specific CarWasher class that has an operation specific to washing cars (pseudo code):
CarWasher : VehicleWasher
Wash(Car)
Car : Vehicle
Then consider the following client code to wash a specific vehicle (notice that x and washer are declared using their base type because the instances might be dynamically created based on user input or external configuration values; in this example they are simply created with a new operator though):
Vehicle x = new Car();
VehicleWasher washer = new CarWasher();
washer.Wash(x);
Many languages use single dispatch to call the appropriate function. Single dispatch means that during runtime only a single value is taken into account when determining which method to call. Therefore only the actual type of washer we'll be considered. The actual type of x isn't taken into account. The last line of code will therefore invoke CarWasher.Wash(Vehicle) and NOT CarWasher.Wash(Car).
If you use a language that does not support multiple dispatch and you do need it (I can honoustly say I have never encountered such a situation though) then you can use the visitor design pattern to enable this. For this two things need to be done. First of all add an Accept method to the Vehicle class (the visitee) that accepts a VehicleWasher as a visitor and then call its operation Wash:
Accept(VehicleWasher washer)
washer.Wash(this);
The second thing is to modify the calling code and replace the washer.Wash(x); line with the following:
x.Accept(washer);
Now for the call to the Accept method the actual type of x is considered (and only that of x since we are assuming to be using a single dispatch language). In the implementation of the Accept method the Wash method is called on the washer object (the visitor). For this the actual type of the washer is considered and this will invoke CarWasher.Wash(Car). By combining two single dispatches a double dispatch is implemented.
Now to eleborate on your remark of the terms like Accept and Visit and Visitor being very unspecific. That is absolutely true. But it is for a reason.
Consider the requirement in this example to implement a new class that is able to repair vehicles: a VehicleRepairer. This class can only be used as a visitor in this example if it would inherit from VehicleWasher and have its repair logic inside a Wash method. But that ofcourse doesn't make any sense and would be confusing. So I totally agree that design patterns tend to have very vague and unspecific naming but it does make them applicable to many situations. The more specific your naming is, the more restrictive it can be.
Your switch statement only considers one type which is actually a manual way of single dispatch. Applying the visitor design pattern in the above way will provide double dispatch.
This way you do not necessarily need additional Visit methods when adding additional types to your hierarchy. Ofcourse it does add some complexity as it makes the code less readable. But ofcourse all patterns come at a price.
Ofcourse this pattern cannot always be used. If you expect lots of complex operations with multiple parameters then this will not be a good option.
An alternative is to use a language that does support multiple dispatch. For instance .NET did not support it until version 4.0 which introduced the dynamic keyword. Then in C# you can do the following:
washer.Wash((dynamic)x);
Because x is then converted to a dynamic type its actual type will be considered for the dispatch and so both x and washer will be used to select the correct method so that CarWasher.Wash(Car) will be called (making the code work correctly and staying intuitive).
Separate data structures and operations
The other benefit and requirement is that it can separate the data structures from the operations. This can be an advantage because it allows new visitors to be added that have there own operations while it also allows data structures to be added that 'inherit' these operations. It can however be only applied if this seperation can be done / makes sense. The classes that perform the operations (the visitors) do not know the structure of the data structures nor do they have to know that which makes code more maintainable and reusable. When applied for this reason the visitors have operations for the different elements in the data structures.
Say you have different data structures and they all consist of elements of class Item. The structures can be lists, stacks, trees, queues etc.
You can then implement visitors that in this case will have the following method:
Visit(Item)
The data structures need to accept visitors and then call the Visit method for each Item.
This way you can implement all kinds of visitors and you can still add new data structures as long as they consist of elements of type Item.
For more specific data structures with additional elements (e.g. a Node) you might consider a specific visitor (NodeVisitor) that inherits from your conventional Visitor and have your new data structures accept that visitor (Accept(NodeVisitor)). The new visitors can be used for the new data structures but also for the old data structures due to inheritence and so you do not need to modify your existing 'interface' (the super class in this case).
In my personal opinion, the visitor pattern is only useful if the interface you want implemented is rather static and doesn't change a lot, while you want to give anyone a chance to implement their own functionality.
Note that you can avoid changing everything every time you add a new method by creating a new interface instead of modifying the old one - then you just have to have some logic handling the case when the visitor doesn't implement all the interfaces.
Basically, the benefit is that it allows you to choose the correct method to call at runtime, rather than at compile time - and the available methods are actually extensible.
For more info, have a look at this article - http://rgomes-info.blogspot.co.uk/2013/01/a-better-implementation-of-visitor.html
By experience, I would say that "Adding a new type to the type hierarchy requires changes to all visitors" is an advantage. Because it definitely forces you to consider the new type added in ALL places where you did some type-specific stuff. It prevents you from forgetting one....
This is an old question but i would like to answer.
The visitor pattern is useful mostly when you have a composite pattern in place in which you build a tree of objects and such tree arrangement is unpredictable.
Type checking may be one thing that a visitor can do, but say you want to build an expression based on a tree that can vary its form according to a user input or something like that, a visitor would be an effective way for you to validate the tree, or build a complex object according to the items found on the tree.
The visitor may also carry an object that does something on each node it may find on that tree. this visitor may be a composite itself chaining lots of operations on each node, or it can carry a mediator object to mediate operations or dispatch events on each node.
You imagination is the limit of all this. you can filter a collection, build an abstract syntax tree out of an complete tree, parse a string, validate a collection of things, etc.
I am a factory employee who's done just a little programming. I want to suggest that our computer shift reports do a couple calculations for us so I don't have to punch them into a calculator several times a day. Rather than just saying "I would like the computer to take the net net weight and tare weight I entered elsewhere and tell me the gross weight", I would like to submit some code or pseudocode with my suggestion:
function calculategross () {
int gross = fldshf_skidnet + fldshf_tare;
//use fldshf_skidnet, not fldshf_net in case of multiple rolls per skid.
}
Since I know exactly which calculations I need done and which variables are available in the database table, pseudocode could save the application programmer a lot of thought. It should make my suggestion look more viable as well, and writing new code is just fun. But a real programmer might rather have a detailed spec or something without my opinion on the technical features. If a manager asked you to code something and submitted some non-compiling "code", would you say "hey, good roadmap" or "geez, get a clue"?
Background: The shift report is a tabbed form view of a database table, made in Alpha V5. So you have a front end that looks somewhat like the first result here, and if you hit F8 you are looking at the underlying table in the database. (This is how I know all the variable names.) My calculator page would be on its own tab. Some of the data it uses will be user-entered in other tabs, some on the page itself.
Here's some of the "first draft code" I'm considering. The interface stuff that I'm shakier on is near the top, some of the calculator functions are at the bottom.
Button GetDataButton = new Button();
GetDataButton.onclick() = UpdateAllUneditedVariables() {
//Populate all fields on this tab with data entered elsewhere
//Don't update fields the user changed on this page.
//I didn't actually write this function, I'm just describing it.
}
Button CalculateAll = new Button();
CalculateAll.onclick() {
FillEmptyFieldsWithDefaultValues();
CallAllCalculatorFunctions();
DisplayAllCalculationResults();
}
sub CallAllCalculatorFunctions() {
CalculateGross();
CalculateAverage();
CalculateNetPoundsPerHour();
//I feel like this is a non-programmer way to structure this...
}
//Here's a couple of the mathier functions -- not that hard, but complicated
//enough that I'd rather not have the programmer have to think through them.
function SkidsPerJob () {
//How many skids must we divide this job into based on weight limits?
int max_by_weight = ceil (fldshf_total_lbs / max_lbs_skid);
//How many based on height limits?
float total_height = fldshf_gauge * fldshf_total_sheets;
int max_by_height = ceil(total_height / max_height / stacks_per_skid);
int total_skids = max (max_by_weight, max_by_height);
}
function CalculateNetPoundsPerHour () {
int netpph = sheet_weight / sheet_length * feet_per_minute * 12 * 60;
if (number_of_webs > 1) {netpph *= number_of_webs;
}
If you don't think this is good, would you recommend just refreshing my coding ability by brushing up on Microsoft Access forms? (I have made them before, with dropdowns and everything, just not recently.) Get an editor from Scriptlance to fix naming conventions and coding errors? Or should I just concentrate on the look of the page and describing the functions I need and not try to design it myself?
When writing a specification, you have to express what you want in a language that both you and the developer understands. I think it is a good idea to make use of your programming experience and express the business logic in a programming-like language. I wouldn't bother with coding errors or naming conventions: It is more important that you get the naming right (from a domain perspective) than syntactical correctness.
Don't spend too much time on this, though. Focus on the things that are unique to your domain.
In the agile world you would tend to avoid trying to spec everything up front, accepting that this is nigh on impossible, and instead allow the design to evolve through continual prototyping and interaction with the developer (see Scrum or DSDM for example).
My advice is to focus on the business requirements and allow the developer to decide exactly how best to implement them, that's his job and he will know how to do it better than you. Doubtless he will also have things like coding standards and existing libraries of code he may want to re-use. You should be primarily concerned with working closely with him to ensure that he understands your requirements (I would advise you to break them up into small, discrete 'chunks') so that what he produces addresses your needs and there are no surprises come delivery day.
As others have already said (Anders Lindahl & Simon), you should be focusing on making sure the programmer understands your business requirements.
As a progammer, I'd rather see the spec as a screeen diagram, with descriptions of what each button (or other active control) does, than screen-creation pseudocode. However, I see nothing wrong with specifying the calculations in pseudocode, particularly if they're tricky. If the order of operations is critical (either from a user perspecitve or a "this value depends on that calculation" one), I'd also welcome high-level English-like pseudocode to specify the crucial bits.