How should I organize multiple static objects with similar methods? - c#

I'm making a tile-based train game in C#, and I've decided that the track types should be written as static classes (in my mind, every "Straight" track should exhibit the same behavior, as should every "LargeTurnLeft", "SmallTurnRight", etc.)
The train follows the track by passing a variable "w" into whatever kind of track it is currently riding. Each type of Track has a function called trackLogic that returns different (X,Y) coordinates based on the shape of the track. "trackLogic" is always available for each type of track, but the function differs from type to type (sometimes it returns a straight line, sometimes a curve, maybe a loop-the-loop).
In my mind, the best way to organize this is to have a static, virtual "Track" with functions that are overridden with the specific methods for each kind of track ("LargeTurnRight.trackLogic", etc). This would make making new track types easier. But, as I'm sure y'all already know, static, virtual classes don't exist in C#.
Because this game will eventually involve thousands and thousands of track pieces, I don't want instances of each one. But for multiple track types to have a uniform function structure, they can't be static either.
Should I scrap the individual classes, throw switch cases in the original "Track" class for each type, and update the function with each new piece, or is there a more elegant way to organize multiple functions with the same method name?

Related

Keeping class state valid vs performance

If i have public method that returns a reference type value, which is private field in the current class, do i need to return a copy of it? In my case i need to return List, but this method is called very often and my list holds ~100 items. The point is that if i return the same variable, everybody can modify it, but if i return a copy, the performance will degrade. In my case im trying to generate sudoku table, which is not fast procedure.
Internal class SudokuTable holds the values with their possible values. Public class SudokuGame handles UI requests and generates/solves SudokuTable. Is it good practice to chose performance instead OOP principles? If someone wants to make another library using my SudokuTable class, he wont be aware that he can brake its state with modifying the List that it returns.
Performance and object-oriented programming are not mutually exclusive - your code can be object-oriented and perform badly, etc.
In the case you state here I don't think it would be wise to allow external parts edit the internal state of a thing, so I would return an array or ReadOnlyCollection of the entries (it could be a potential possibility to use an ObservableCollection and monitor for tampering out-of-bounds, and 'handling' that accordingly (say, with an exception or something) - unsure how desirable this would be).
From there, you might consider how you expose access to these entries, trying to minimise the need for callers to get the full collection when all they need is to look up and return a specific one.
It's worth noting that an uneditable collection doesn't necessarily mean the state cannot be altered, either; if the entries are represented by a reference type rather than a value type then returning an entry leaves that open to tampering (potentially, depending on the class definition), so you might be better off with structs for the entry types.
At length, this, without a concrete example of where you're having problems, is a bit subjective and theoretical at the moment. Have you tried restricting the collection? And if so, how was the performance? Where were the issues? And so on.

Maintaining modularity in Main()?

I'm writing the simple card game "War" for homework and now that the game works, I'm trying to make it more modular and organized. Below is a section of Main() containing the bulk of the program. I should mention, the course is being taught in C#, but it is not a C# course. Rather, we're learning basic logic and OOP concepts so I may not be taking advantage of some C# features.
bool sameCard = true;
while (sameCard)
{
sameCard = false;
card1.setVal(random.Next(1,14)); // set card value
val1 = determineFace(card1.getVal()); // assign 'face' cards accordingly
suit = suitArr[random.Next(0,4)]; // choose suit string from array
card1.setSuit(suit); // set card suit
card2.setVal(random.Next(1,14)); // rinse, repeat for card2...
val2 = determineFace(card2.getVal());
suit = suitArr[random.Next(0,4)];
card2.setSuit(suit);
// check if same card is drawn twice:
catchDuplicate(ref card1, ref card2, ref sameCard);
}
Console.WriteLine ("Player: {0} of {1}", val1, card1.getSuit());
Console.WriteLine ("Computer: {0} of {1}", val2, card2.getSuit());
// compare card values, display winner:
determineWinner(card1, card2);
So here are my questions:
Can I use loops in Main() and still consider it modular?
Is the card-drawing process written well/contained properly?
Is it considered bad practice to print messages in a method (i.e.: determineWinner())?
I've only been programming for two semesters and I'd like to form good habits at this stage. Any input/advice would be much appreciated.
Edit:
catchDuplicate() is now a boolean method and the call looks like this:
sameCard = catchDuplicate(card1, card2);
thanks to #Douglas.
Can I use loops in Main() and still consider it modular?
Yes, you can. However, more often than not, Main in OOP-programs contains only a handful of method-calls that initiate the core functionality, which is then stored in other classes.
Is the card-drawing process written well/contained properly?
Partially. If I understand your code correctly (you only show Main), you undertake some actions that, when done in the wrong order or with the wrong values, may not end up well. Think of it this way: if you sell your class library (not the whole product, but only your classes), what would be the clearest way to use your library for an uninitiated user?
I.e., consider a class Deck that contains a deck of cards. On creation it creates all cards and shuffles it. Give it a method Shuffle to shuffle the deck when the user of your class needs to shuffle and add methods like DrawCard for handling dealing cards.
Further: you have methods that are not contained within a class of their own yet have functionality that would be better of in a class. I.e., determineFace is better suited to be a method on class Card (assuming card2 is of type Card).
Is it considered bad practice to print messages in a method (i.e.: determineWinner())?
Yes and no. If you only want messages to be visible during testing, use Debug.WriteLine. In a production build, these will be no-ops. However, when you write messages in a production version, make sure that this is clear from the name of the method. I.e., WriteWinnerToConsole or something.
It's more common to not do this because: what format would you print the information? What text should come with it? How do you handle localization? However, when you write a program, obviously it must contain methods that write stuff to the screen (or form, or web page). These are usually contained in specific classes for that purpose. Here, that could be the class CardGameX for instance.
General thoughts
Think about the principle "one method/function should have only one task and one task only and it should not have side effects (like calculating square and printing, then printing is the side effect).".
The principle for classes is, very high-level: a class contains methods that logically belong together and operate on the same set of properties/fields. An example of the opposite: Shuffle should not be a method in class Card. However, it would belong logically in the class Deck.
If the main problem of your homework is create a modular application, you must encapsulate all logic in specialized classes.
Each class must do only one job.
Function that play with the card must be in a card class.
Function that draw cards, should be another class.
I think it is the goal of your homework, good luck!
Take all advices on "best practices" with a grain of salt. Always think for yourself.
That said:
Can I use loops in Main() and still consider it modular?
The two concepts are independent. If your Main() only does high-level logic (i.e. calls other methods) then it does not matter if it does so in a loop, after all the algorithm requires a loop. (you wouldn't add a loop unnecessarily, no?)
As a rule of thumb, if possible/practical, make your program self-documenting. Make it "readable" so, if a new person (or even you, a few months from now) looks at it they can understand it at any level.
Is the card-drawing process written well/contained properly?
No. First of all, a card should never be selected twice. For a more "modular" approach I would have something like this:
while ( Deck.NumCards >= 2 )
{
Card card1 = Deck.GetACard();
Card card2 = Deck.GetACard();
PrintSomeStuffAboutACard( GetWinner( card1, card2 ) );
}
Is it considered bad practice to print messages in a method (ie: determineWinner())?
Is the purpose of determineWinner to print a message? If the answer is "No" then it is not a matter of "bad practice", you function is plain wrong.
That said, there is such a thing as a "debug" build and a "release" build. To aid you in debugging the application and figuring out what works and what doesn't it is a good idea to add logging messages.
Make sure they are relevant and that they are not executed in the "release" build.
Q: Can I use loops in Main() and still consider it modular?
A: Yes, you can use loops, that doesn't really have an impact on modularity.
Q: Is the card-drawing process written well/contained properly?
A: If you want to be more modular, turn DrawCard into a function/method. Maybe just write DrawCards instead of DrawCard, but then there's an optimization-versus-modularity question there.
Q: Is it considered bad practice to print messages in a method (ie: determineWinner())?
A: I wouldn't say printing messages in a method is bad practice, it just depends on context. Ideally, the game itself doesn't handle anything but game logic. The program can have some kind of game object and it can read state from the game object. This way, you could technically change the game from being text-based to being graphical. I mean, that's ideal for modularity, but it may not be practical given a deadline. You always have to decide when you have to sacrifice a best practice because there isn't enough time. Sadly, this is all too often a common occurrence.
Separate game logic from the presentation of it. With a simple game like this, it's an unnecessary dependency.

C# On extending a large class in favor of readability

I have a large abstract class that handles weapons in my game. Combat cycles through a list of basic functions:
OnBeforeSwing
OnSwing
OnHit || OnMiss
What I have in mind is moving all combat damage-related calculations to another folder that handles just that. Combat damage-related calculations.
I was wondering if it would be correct to do so by making the OnHit method an extension one, or what would be the best approach to accomplish this.
Also. Periodically there are portions of the OnHit code that are modified, the hit damage formula is large because it takes into account a lot of conditions like resistances, transformation spells, item bonuses, special properties and other, similar, game elements.
This ends with a 500 line OnHit function, which kind of horrifies me. Even with region directives it's pretty hard to go through it without getting lost in the maze or even distracting yourself.
If I were to extend weapons with this function instead of just having the OnHit function, I could try to separate the different portions of the attack into other functions.
Then again, maybe I could to that by calling something like CombatSystem.HandleWeaponHit from the OnHit in the weapon class, and not use extension methods. It might be more appropriate.
Basically my question is if leaving it like this is really the best solution, or if I could (should?) move this part of the code into an extension method or a separate helper class that handles the damage model, and whether I should try and split the function into smaller "task" functions to improve readability.
I'm going to go out on a limb and suggest that your engine may not be abstracted enough. Mind you, I'm suggesting this without knowing anything else about your system aside from what you've told me in the OP.
In similar systems that I've designed, there were Actions and Effects. These were base classes. Each specific action (a machine gun attack, a specific spell, and so on) was a class derived from Action. Actions had an list of one or more specific effects that could be applied to Targets. This was achieved using Dependency Injection.
The combat engine didn't do all the math itself. Essentially, it asked the Target to calculate its defense rating, then cycled through all the active Actions and asked them to determine if any of its Effects applied to the Target. If they applied, it asked the Action to apply its relevant Effects to the Target.
Thus, the combat engine is small, and each Effect is very small, and easy to maintain.
If your system is one huge monolithic structure, you might consider a similar architecture.
OnHit should be an event handler, for starters. Any object that is hit should raise a Hit event, and then you can have one or more event handlers associated with that event.
If you cannot split up your current OnHit function into multiple event handlers, you can split it up into a single event handler but refactor it into multiple smaller methods that each perform a specific test or a specific calculation. It will make your code much more readable and maintainable.
IMHO Mike Hofer gives the leads.
The real point is not whether it's a matter of an extension method or not. The real point is that speaking of a single (extension or regular) method is unconceivable for such a complicated bunch of calculations.
Before thinking about the best implementation, you obviously need to rethink the whole thing to identify the best possible dispatch of responsibilities on objects. Each piece of elemental calculation must be done by the object it applies to. Always keep in mind the GRASP design patterns, especially Information Expert, Low Coupling and High Cohesion.
In general, each method in your project should always be a few lines of code long, no more. For each piece of calculation, think of which are all the classes on which this calculation is applicable. Then make this calculation a method of the common base class of them.
If there is no common base class, create a new interface, and make all these classes implement this interface. The interface might have methods or not : it can be used as a simple marker to identify the mentioned classes and make them have something in common.
Then you can build an elemental extension method like in this fake example :
public interface IExploding { int ExplosionRadius { get; } }
public class Grenade : IExploding { public int ExplosionRadius { get { return 30; } } ... }
public class StinkBomb : IExploding { public int ExplosionRadius { get { return 10; } } ... }
public static class Extensions
{
public static int Damages(this IExploding explosingObject)
{
return explosingObject.ExplosionRadius*100;
}
}
This sample is totally cheesy but simply aims to give leads to re-engineer your system in a more abstracted and maintenable way.
Hope this will help you !

Problems designing Bejeweled game

I am trying to do the design of a Bejeweled game. I have basically 3 classes. The Game class, which is what is going to be used by the player, a Board class, that represents the board, and a SwitchController class that is responsible for checking if the wanted switch on the board is valid, making the switch, counting the number of possible switches available (so I can know when the game is over, etc).
My current design is something like the following:
Game:
isGameOver()
isSwitchValid(coord1, coord2)
makeSwitch(coord1, coord2)
getPieceAt(coord)
getBoardLength()
IBoard:
getPieceAt(coord)
setPieceAt(coord, piece)
getLength()
My idea would then to have a ISwitchController:
ISwitchController:
isSwitchValid(coord1, coord2)
makeSwitch(coord1, coord2)
getAllValidSwitches()
Here is a little diagram of how the classes are to be organized:
I would have 2 different concrete classes of IBoard available for use (and for each one of them, I'd have to have an ISwitchController implementation).
The problem:
My program is to have 2 IBoard implementations:
The first, ArrayBoard, will have all the pieces of the board stored in a 2D Array. There is nothing special about it. I will define an ArrayBoardSwitchController for managing this class.
The second, ListBoard, will have for each color of pieces, a List/Set with all the coordinates of the pieces of that color. I will define a ListBoardSwitchController for managing this class.
The main issue here is that the implementation of SwitchController will be totally different on ArrayBoard and on ListBoard. For example, while for implementing getAllValidSwitches() ArrayBoardSwitchController only needs the getPieceAt() method, that would not be a good idea to do with ListBoardSwitchController(in that class I use internally lists because it's easier to check if the move is valid that way).
From what I can see, there are 2 different possible solutions:
I could either merge together the
ISwitchController and IBoard
interfaces. That way I'd only have
two classes, Game and Board (while
basically Game would just be a
controller for the Board, as it
would be the Board that had all the
game logic). It wouldn't be that nice
because the classes wouldn't be
as cohese as they could be if I had
3 distinct classes.
Let the interfaces as they are and put
all the methods I need to work with public
in the concrete classes. For example, if I need
a getYellowPiecesList() method, I'd put it public
on ListBoard so ListBoardSwitchController could
use it. ListBoardSwitchController would only
know about it because it knows it only works
against ListBoards.
What's your opinion on the matter? The focus here is not so much on how to design the Bejeweled game, but how to solve this problem, that is recurrent when you try to implement algorithms: on one hand you want to have a clear and good OOP design, and in the other sometimes that gets in the way of having a sound and effective algorithm implementation.
The main issue here is that the implementation of SwitchController will be totally different on ArrayBoard and on ListBoard.
If this is the case, then it sounds like you haven't designed the IBoard interface well enough so that classes can use an implementation of IBoard without knowing the implementation details. If the user of an IBoard needs to know what implementation is being used, then it almost defeats the purpose of having an interface!
I would strongly suggest re-visiting the methods you are exposing on IBoard to see if there is a way you can expose something like "get the piece at this coordinate" in a more generic way. Make sure that any methods a controller needs to invoke on a IBoard instance are only the methods in the IBoard interface.
For example, while for implementing getAllValidSwitches() ArrayBoardSwitchController only needs the getPieceAt() method, that would not be a good idea to do with ListBoardSwitchController(in that class I use internally lists because it's easier to check if the move is valid that way).
If an operation such as "get piece at this coordinate" is instrumental to the IBoard interface, then the implementations must be faithful to their contract and implement it correctly. It sounds as if your ListBoard is not faithfully meeting the contract set out in IBoard.
3: Let ArrayBoardSwitchController and ListBoardSwitchController be inner classes of ArrayBoard and ListBoard. The implementation of the controller is tied to the implementation of your board, thus it makes sense to keep them together. Because the controller will be an inner class you can use the implementation details from the board. Then to make it work extend the IBoard interface to return a ISwitchController.
Note that this is only slightly different from option 1. (The ISwitchController can now be used indirectly from a IBoard, merging them gives direct access to ISwitchController)
What is the purpose of ListBoard as an object decoupled from ArrayBoard? If I were going to bother with the list of gems at all, I would keep it in an object which also held an array of what was in each position, so that swapping the position of two gems could be done quickly and efficiently. Not that I'm clear on why you need the position list anyhow?
If a 6507 running at 1.19Mhz with 128 bytes of RAM and 20% CPU availability can handle Columns, finding all 3-in-a-row combinations on a 6x20 in less than 100ms, I would think more modern machines could scan for moves acceptably fast without using a list of what gems are where. I'd suggest padding your board array so you don't have to worry about edge cases, and for each gem check 16 combinations of various cells within 3 squares of it(*) to see if they both match it. Some moves may be double-reported (e.g. this algorithm may detect that moving a gem left will create a 3-in-a-row, and also detect that moving the gem to the left of the first one right will create a 3-in-a-row) but that shouldn't be a problem.
(*) If a gem can move left, then it must match either the two gems to the left of the destination, or the two gems above the destination, or the two gems below, or one above and one below. Likewise for the other directions.

Thread Safe Class Library Design

I'm working on a class library and have opted for a route with my design to make implementation and thread safety slightly easier, however I'm wondering if there might be a better approach.
A brief background is that I have a multi-threaded heuristic algorithm within a class library, that once set-up with a scenario should attempt to solve it. However I obviously want it to be thread safe and if someone makes a change to anything while it is solving for that to causes crashes or errors.
The current approach I've got is if I have a class A, then I create a number InternalA instances for each A instance. The InternalA has many of the important properties from the A class, but is internal an inaccessible outside the library.
The downside of this, is that if I wish to extend the decision making logic (or actually let someone do this outside the library) then it means I need to change the code within the InternalA (or provide some sort of delegate function).
Does this sound like the right approach?
It's hard to really say from just that - but I can say that if you can make everything immutable, your life will be a lot easier. Look at how functional languages approach immutable data structures and collections. The less shared mutable data you have, the simple threading will be.
Why Not?
Create generic class, that accepts 2 members class (eg. Lock/Unlock) - so you could provide
Threadsafe impl (implmenetation can use Monitor.Enter/Exit inside)
System-wide safe impl (using Mutex)
Unsafe, but fast (using empty impl).
another way i have had some success with is by using interfaces to achieve functional separation. the cost of this approach is that you end up with some fields 'repeated' because each interface requires total separation from the others fields.
In my case I had 2 threads that need to pass over a set of data that potentially is large and needs as little garbage collection as possible. Ie I only want to pass change information from the first stage to the second. And then have the first process the next work unit.
this was achieved by the use of change buffers to pass changes from one interface to the next.
this allows one thread to work away at one interface, make all its changes and then publish a struct containing the changes that the other interface (thread) needs to apply prior to its work.
by doing this You have a double buffer ... (thread 1 produces a change report whilst thread 2 consumes the last report). If you add more interfaces (and threads) it appears like there are pulses of work moving through the threads.
This was based on my research and I have no doubt that there are better methods available now.
My aim when coming up with this however was to avoid the need for locks in the vast majority of code by designing out race conditions. the other major consideration is performance in garbage collection - which may not be an issue for you.
this way is all good until you need complex interactions between threads ... then you find that you start forcing the layout of your buffer structures for reuse to get around inheritance which in turn has an upkeep overhead.
A little more information on the problem to help...
The heuristic I'm using is to solve TSP like problems. What happens right at the start of each
calculation is that all the aspects that form the problem (sales man/places to visit) are cloned
so they aren't affected across threads.
This means each thread can change data (such as stock left on a sales man etc) as there are a number
of values that change during the calculation as things progress. What I'd quite like to do is allow
the checked such as HasSufficientStock() for a simple example to be override by a developer using the library.
Unforutantely at present however to add further protection across threads and makings some simplier/lightweight
classes I convert them to these internal classes, and these are the things that are actually used and cloned.
For example
class A
{
public double Stock { get; }
// Processing and cloning actually works using these InternalA's
internal InternalA ConvertToInternal() {}
}
internal class InternalA : ICloneable
{
public double Stock { get; set; }
public bool HasSufficientStock() {}
}

Categories