Philosophical Design Questions for OOP-Tetris [closed] - oop

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
You are writing a Tetris program in Java. How would you set up your class design with regards to the following aspects?
Piece class: Have one Piece class, with an internal array which determines the shape of the piece, versus having seven Piece classes, one for each of the pieces. They are all subclasses of one generic Piece class.
Piece class representation: Have an array of 4 instances of Block, representing one square of a piece, and each Block contains its location on the Board (in graphical coordinates) vs. having a 4x4 array where null means there is no block there, and location is determined by the shape of the array.
Location: Each Block in the Piece array or on the Board array stores its location vs. the Piece and the Board know the locations of the Blocks that comprise them.
Generating a Piece: Have a static method of the Piece class getRandomPiece, or have a PieceFactory which you make one instance of that has the genRandomPiece method on the instance.
Manipulating the current piece: Use the Proxy pattern, so that everything that needs access to it just uses the proxy, or have a getCurrentPiece method on the Board class and call that any time you want to do something with the current piece.
This is not homework. I'm just at odds with what the intro CS course teaches at my college and I want to see what people in general believe. What would be thought of as "good" OOP design? Ignore the fact that it's for an intro course - how would you do it?

Firstly, I wouldn't subclass the Piece class because it's unnecessary. The Piece class should be capable of describing any shape without using inheritance. IMHO, this isn't what inheritance was made for and it just complicates things.
Secondly, I wouldn't store the x/y coordinates in the Block objects because it allows two blocks to exist in the same place. The Piece classes would keep a grid (i.e. 2D array) holding the block objects. The x/y coordinates would be the indexes of the 2D array.
As for the static method vs factory object for getting a random piece, I'd go with the factory object for the simple fact that the factory object can be mocked for testing.
I would treat the board as one large Piece object. The Board class would keep the large Piece object as a member variable, and might keep other Piece objects such as the current piece being played, and the next piece to be played. This is done using composition to avoid inheritance.

All these classes and stuff... it might be making the problem way too abstract for what it really is. Many different ways to represent tetris pieces (stackoverflow.com/questions/233850/…) and many different ways to manipulate them. If it's for an intro course I wouldn't worry about OOP. Just my opinion, not a real answer to your question.
Having said that, one could suffice with simply a Board and Piece class.
Board class: Encapsulates a simple 2d array of rectangles. Properties like currentpiece, nextpiece. Routines like draw(), fullrows(), drop(), etc.. which manipulate the current piece and the filled in board squares.
Piece class: Encapsulates an array of unsigned 16 bit numbers encoding the pieces in their various rotations. You would track color, current location, and rotation. Perhaps one routine, rotate() would be necessary.
The rest, would be, depending on the environment, handling keyboard events etc...
I've found that placing too much emphasis on design tends to make people forget that what they really need to do is to get something running. I'm not saying don't design, I'm saying that more often than not, there is more value in getting something going, giving you traction and motivation to keep going.
I would say, to the class, you have X hours to make a design for a tetris game. Then they would need to turn in that design. Then I would say, you have X days, to get something running based on the design you turned in or even not based on the design.

One Piece interface, with seven classes that implement that interface for the individual pieces (which would also enable the OOP course to discuss interfaces) (EDIT: One Piece class. See comments)
I would have a BlockGrid class that can be used for any map of blocks - both the board, and the individual pieces. BlockGrid should have methods to detect intersections - for example, boolean intersects(Block block2, Point location) - as well as to rotate a grid (interesting discussion point for the course: If the Board doesn't need to rotate, should a rotate() method be in BlockGrid?). For a Piece, BlockGrid would represent be a 4x4 grid.
I would create a PieceFactory with a method getRandomShape() to get an instance of one of the seven shapes
For manipulating the piece, I'd get into a Model-View-Controller architecture. The Model is the Piece. The Controller is perhaps a PieceController, and would also allow or disallow legal/illegal moves. The thing that would show the Piece on the screen is a PieceView (hrm, or is it a BlockGridView that can show Piece.getBlockGrid()? Another discussion point!)
There are multiple legitimate ways to architect this. It would benefit the course to have discussions on the pro's and con's of different OOP principles applied to the problem. In fact, it might be interesting to compare and contrast this with a non-OOP implementation that just uses arrays to represent the board and pieces.
EDIT: Claudiu helped me realize that the BlockGrid would sufficiently differentiate pieces, so there is no need for a Piece interface with multiple subclasses; rather, an instance of a Piece class could differ from other instances based on its BlockGrid.

Piece class: I think that a single class for all the pieces is sufficient. The class functions shoudl be general enough to work for any piece, so there is no need to subclass.
Piece Class Representation: I believe that a 4x4 array is probably a better way as you will then find it much easier to rotate the piece.
Location: Location should definitely be stored by the board, not the piece as otherwise you would have to go through the entire set of blocks to ensure that no two blocks are in the same position.
Generating a Piece: Honestly for this one I do not feel that it will make too much of a difference. Having said that, I would prefer a static function as there is really not so much to this function that it warrants its own class.
Manipulating the Current Piece: I would just implement a getCurrent function as I feel that there is no need to overcomplicate the problem by adding in an extra class to serve as a proxy.
This is how I would do it, but there are many different ways, and at the end of the day, the thing to focus on is simply getting the program running.

Related

An object for every sprite? (Games, OOP)

Currently I am trying my best programming a little video game in the style of the old Zelda games. However, I am having some trouble with the whole OOP style of thinking. To be more specific, I don't really know how to "design" the screens.
Let's say I have a class for my sprites and loaded a Wall-sprite to have a border for a certain area, should I make an extra "wall"-class, or is the wall being a "sprite" already enough? I thought it might be senseless to define an extra class since it would not have any different variables than the actual sprite class (as my wall IS only a sprite) so I didn't consider it to be a useful idea.
I am asking this because I have a little problem with the collision detection as well: What I currently do is loading a sprite for an object only once and rendering it multiple times at several locations. But the problem is that this causes the collision only to be detected at the last position the sprite was rendered at.
It gives me more problems when I render 2 cave-entrances somewhere but my game only checks for the 2nd entrance if I "entered" it.
So I thought making an extra "entrance"-class and creating 2 completely different objects of it that are treated separately might help, but should I then also create 30 objects for my wall-sprites?
Hmmm, there is really two questions, well three, but the OOP-thinking is too non-specific for a good question. So let's see if we can answer it by answering your valid ones.
Good OO Design is centered around "Patterns" (Common solutions to a variety of Problems) in the case of your sprite re-use in OO this would be known as a "Fly-weight" Pattern. Three important structural elements in good OO and understanding them is key to "getting it". They are:
Interfaces - They are free (relatively) of operational code, and provide only method and constructor signatures(generally) to allow for clean separation of coding concerns.
Classes - Only the reusable parts(ideally) of an object they are "the Mold or Pattern" that objects are instantiated (or patterned) from.
Objects - Instances (this chair or that chair as opposed, to Chair as an ideal) of the same form of Class (the ideal Chair). Objects (ideally) should keep as instance values only that which differentiates it from other instances of the same ideal.
However, because your original sprite is not an object you are having this collision problem, because it actually is the same instance rendered again and again, the graphics pipeline does not keep all of its previous locations as separate things it actual just stores pixels(usually), once they've been translated.
In this case if each instance is an object, each instance would have its location as a local instance variable(s), while its graphical representation and collision detection method would be common to all instances of the class.
Don't think of it as having 30 whole copies in memory at once, you only have thirty copies of the instance variables. This is true if you use OO or not; in a procedural solution to get proper collision detection you would have to maintain an array of all of the places you rendered that sprite and iterate through each time, further your code would be less cleanly separated and you would have to iterate through the array for every sprite interaction as well as for updating moving sprites. With OO you could handle this with one class method call that recurses it children.
A good class structure for this simple example might be:
An Abstract Sprite Class (abstract because you will never use a non-specific Sprite) containing only code common to all sprites
A Concrete Wall Sprite Class that extends Sprite, only the code for non-moving wall sprites.
A Concrete Trigger Sprite Class (whose graphic might be clear or null) for behaviors that need to be triggered in "open spaces"
A Concrete Agent Sprite Class for moving sprites (might implement a movable interface meaning all derivatives of the class have a move() method.
A Concrete Character class that extends agent for a movable sprite that is driven by user commands.
It may seem confusing at first, but it's actually cleaner, simpler, and more maintainable doing it the OO way.
:)

Best OOP way to represent chess pieces

Consider a Chess application that has a Board containing an array of chess Pieces. Which of the following is the best object-oriented way of designing the Piece object, taking into account the advantages/disadvantages of each choice:
One class for all pieces, with a piece_type attribute that enumerates the types of chess pieces,
A Piece interface that all pieces inherit from, which would have the overhead of creating 6 other classes each corresponding to a unique chess piece.
The first option has the advantage of being lightweight and uses the fact that there is a lot of similar code involved with each chess piece, but is less "OOP". The second option defines an object for each chess piece, but would probably have to contain a lot of copied code and additional source files.
Considering the above, which method would be the most "OOP" design for a chess Piece?
Definitely the second one. The reason is that different chess pieces aren't just different types, they have completely different behavior.
So breaking it down into different classes allows you to specify correct movement (no two units move alike) and attack (e.g. pawn attacks diagonally) behavior for each piece nicely with polymorphism without having giant switch/case clauses in single class.
As for copied code, that is definitely bad; if you find yourself in the need to copy code, it is best to move that particular code to separate class, however I'm not sure what would be needed to copy here - each piece is different.
And as for additional source files, that is something you should almost never worry about. If you are getting lost in all the files it is best to organize it differently, e.g. putting all chess piece classes in their own folder.
Update (from comment):
The game should decide that the piece moves, but the piece decides how. So for example if you wanted to be provide feedback for the user, the user would click on a unit, and the game would ask the unit where it can move (because only the unit knows where it can move), and once the user would confirm the target, the game would tell the unit to move to the (valid!) target. So the game provides interaction between the pieces and user, but the pieces provide behavior particular to each piece.
Indeed great answer, however, I would omit any "Definitely" from an answer, especially to OO related subjects...I assume that each time you address such a problem you'll reach a different design concept.
IMO, there are several options, and any mix and match may work and be reasonably implemented. For instance, defining class "Movement" to stereotype the different moves a Piece can make. Different pieces can actually utilize same movement in certain game play.
Interface vs. Base class definition, again, depending on whether you see any attributes to the classes or not. I see several (Type, assigned movement, Active/Inactive etc.) - and that actually shouts "Base Class"...
For the actual game play, is there a "Player" class that actually instantiate "Moves"? just something to think about.

Non-object-oriented game tutorials

I've been tasked with writing an essay extolling the virtues of object oriented programming and creating an accompanying game to demonstrate them.
My initial idea is to find a tutorial for a simple game written in a programming language which does not follow the OOP paradigm (or written in an OOP language but not in an OOP way) and recreate it in an OOP way using either C# or Java (haven't yet decided). This would then allow me to make concrete comparisons between the two.
The game doesn't have to be anything complex; Tetris, Pong, etc. that sort of thing. The problem I've had so far is finding a suitable tutorial, any suggestions?
Let's say that you found source code for a game not in OOP. There are some OOP virtues that you can point out in your essay:
Organization.
Since a game has many tasks, it is a good idea to assign a responsibility to one class. This means write one class that keeps score, one class that does file access (reading and writing game state, for example), classes to represent your characters, etc. Otherwise, you will have one huge text file with thousands of lines of code. It would be a nightmare to even look at it, let alone find what you need and fix it.
Encapsulation.
This is grouping together properties and functions for better organization. We used to have a different array to store each property - (example) one array for aircraft names, one array for firepower, another array for top speed, etc. That sucks because you need to make sure that the same index across all those arrays actually describes the correct aircraft. It's better to create an Aircraft object and give it those property names. You'll then have one array that holds aircraft - no need to keep track of too many arrays.
Reusability.
As you write more games (and even other apps), you will come across the need to reuse classes. For example, you would use the same Card class in your Solitaire game as any card game you'll write in the future.
Polymorphism/Inheritance.
Say that you want to display each character - both heroes and villains in some sort of a grid. You will want both Hero and Villain to inherit Character. Character will have common properties and even a[n abstract] Display() function. You would then write the custom Display() function for Character and Villain (that access class-specific data for drawing). You then create an array of Character objects, and you may store either a Villain or Hero in each slot. When the game goes through that list to display, each item.Display() call will automatically pick the correct Display() function based on the Character's actual type. Try to do this without OOP and you'll end up with a long if-else (and probably even nested) statement and all drawing routines in one place.
That's just from the type of my head from experience in general programming that you can definitely apply in game programming. There are probably more OOP aspects than mentioned, so you may want to research. Best of everything for your essay!
You can try grabbing a (simple) TI-Basic game from TICalc, Omnimaga, or most other calculator programming websites and try to understand its code.
Try a BASIC game from this site:
http://www.atariarchives.org/basicgames/

Trying to follow MVC - Seeking advice on a good design

I just resumed work on an old project and have been thinking about rewriting some parts of it.
My question relates to how to structure my program. I have been trying to follow the MVC paradigm. I'll start by explaining where things stand: the program manipulates 4 types of images: Bias, Darks, Flat Fields and Lights. I have a class called Image that can represent all of these. The Bias and Dark are subtracted from the Light and then the Light is divided by the Flat Field. Initially, I was going to use 2 classes for this, one called CalibrationImage and the other just Light. But the difference was only of one method which would be the dividing function I mentioned above. Otherwise, they are the same. So I decided against having two classes for this purpose.
The 2nd major class in the program concerns handling multiple Image objects -- this class is known as ImageStacker. As of right now, it holds Image objects in a mutable array. It can do various operations on this array, like stack all the images, calibrate them etc.
This class also acts as the datasource for the NSTableView object in the main window. I'm not thinking that instead of having a single mutable array, I should have 4 arrays each holding its designated for a type of image (like, an array for Lights, another for Darks etc.). Once the program begins its actual work, it will Darks, Flat Fields and Bias frames. It will then calibrate each object held in the Lights array and then stack them. I feel like this provides the program with logical progression. Its also a bit easy to visualize.
Is this a good program design? Does it follow MVC? As I see it, my view is NSTableView, controller is NSApplication and Model is ImageStacker. But then, Image feels like its not part of the MVC but I cant see how to write the program without it.
My 2-cents: MVC is a presentation design pattern. I will typically write my MVC apps with separate business and data layers apart from MVC portion. It is ok that Image is not apart of the MVC pattern, it would probably better fit into a group of classes that you would define as your business layer. There are a lot of good books, blogs and articles out there that talk about programming design patters so I will not reiterate what they have already done. Simply asking this question is a good start. I would suggest you follow through by looking at content that is already available.

The core of object oriented programming [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
I am trying to understand the core of object oriented programming for php or actionscript proect. As far as I understand, we will have a Main class that control different elements of the project. For example, photoslider class, music control class..etc. I created instance of those classes inside my Main class and use their method or property to control those objects.
I have studied many OOP articles but most of them only talks about inheritance, encapsulation...etc I am not sure if I am right about this and I would appreciate if someone can explain more about it. Thanks!
Same question , i was asking when i were just starting my career but i understood Object Orientation as i progress in my career.
but for very basic startng point in oop.
1- think about object just try to relate your daily household things like ( your laptop, your ipad, your Mobile, your pet)
Step 2-
Try to relate objects like ( Your TV an your remote ) this gives you the basic idea how object should relate to each other.
Step 3-
Try to visulize how things compose to create a full feature like your Body compose of (Heart, Lungs and many other organs)
Step 4-
Try to think about object lifetime ( Like as a example a car enigne is less useful outside Car , so if car is a object than this object must contain a engine and when actual car object destroys engine is also destroyed)
Step 5-
Try to learn about a polymorphism ( Like a ScrewDriver can take may shapes according to your need then map to your objects if your using c# than try to leran about ToString() method overriding)
Step 6 -
Try to create a real life boundry to your real life object ( Like your House ; You secure your house by various means )
this is the initial learning .. read as much as text as you find and try to learn by your own examples
in the last ; oop is an art first , try to visulize it.
my main suggestion is to look at the objects as "smart serfs": each one of these will have memory (the data members) and logic (the member functions).
In my experience, the biggest strength of OOP is the control that you have on the evolution of your design: if your software is remotely useful, it will change, and OOP gives you tools to make the change sustainable. In particular:
a class should change for only one reason, so it must be solve only one problem (SINGLE RESPONSABILITY PRINCIPLE)
changing the behaviour of a class should be made by extending it, not by modifying it (OPEN CLOSED PRINCIPLE)
Focus on interfaces, not on inheritance
Tell, don't ask! Give orders to your objects, do not use them as "data stores"
There are other principles, but I think that these are the ones that must be really understood to succeed in OOP.
I'm not sure I ever understood OOP until I started programming in Ruby but I think I have a reasonable grasp of it now.
It was once explained to me as the components of a car and that helped a lot...
There's such a thing as a Car (the class).
my_car and girlfriends_car are both instances of Car.
my_car has these things that exist called Tyres.
my_car has four instances of Tyres - tyre1, tyre2, tyre3, tyre4
So I have two classes - Car, Tyre
and I have multiple instances of each class.
The Car class has an attribute called Car.colour.
my_car.colour is blue
girlfriends_car is pink
The sticking point for me was understanding the difference between class methods and instance methods.
Instance Methods
An instance method is something like my_car.paint_green. It wouldn't make any sense to call Car.paint_green. Paint what car green? Nope. It has to be girlfriend_car.wrap_around_tree because an instance method has to apply to an instance of that Class.
Class Methods
Say I wanted to build a car? my_new_car = Car.build
I call a Class method because it wouldn't make any sense to call it on an instance? my_car.build? my_car is already built.
Conclusion
If you're struggling to understand OOP then you should make sure that you understand the difference between the Class itself and instances of that Class. Furthermore, you should try to undesrstand the difference between class methods and instance methods. I'd recommend learning some Ruby or Python just so you can get a fuller understanding of OOP withouth the added complicaitons of writing OOP in a non-OOP language.
Great things happen with a true OOP language. In Ruby, EVERYTHING is a class. Even nothing (Nil) is a class. Strings are classes. Numbers are classes and every class is descended from the Object class so you can do neat things like inherit the instance_methods method from Object so String.instance_methods tells you all the instance methods for a string.
Hope that helps!
Kevin.
It seems like you're asking about the procedures or "how-tos" of OOP, not the concepts.
For the how-tos, you're mostly correct: I'm not specifically familiar with PHP or ActionScript, but for those of us in .NET, your program will have some entry point which will take control, and then it will call vairous objects, functions, methods, or whatever- often passing control to other pieces of code- to perform whatever you've decided.
In psuedo-code, it might look something like:
EntryPoint
Initialize (instanciate) a Person
Validate the Person's current properties
Perform some kind of update and/or calculation
provide result to user
Exit
If what you're looking for is the "why" then you're already looking in the right places. The very definitions of the terms Encapsulation, Inheritance, etc. will shed light on why we do OOP.
It's mostly about grouping code that belongs to certain areas together. In non-OOP languages you often have the problem that you can't tell which function is used for what/modifies which structures or functions tend to do too many loosely related things. One work around is to introduce a strict naming scheme (e.g. start every function name with the structure name it's associated with). With OOP, every function is tied to a data structure (the object) and thus makes it easier to organize your code. If you code gets larger/the number of tasks bigger inheritance starts to make a difference.
Good example is a structure representing a shape and a function that returns its center. In non-OOP, that function must distinguish between each structure. That's a problem if you add a new shape. You have to teach your function how to calculate the center for that shape. Now imagine you also had functions to return the circumfence and area and ... Inheritance solves that problem.
Note that you can do OOP programming in non-OOP languages (see for example glib/gtk+ in C) but a "real" OOP language makes it easier and often less error-prone to code in OOP-style. On the other hand, you can mis-use almost every OOP language to write purely imperative code :-) And no language prevents one from writing stupid and inefficient code, but that's another story.
Not sure what sort of answer you're looking for, but I think 10s of 1000s of newly graduated comp sci students will agree: no amount of books and theory is a substitute for practice. In other words, I can explain encapsulation, polymorphism, inheritance at length, but it won't help teach you how to use OO effectively.
No one can tell you how to program. Over time, you'll discover that, no matter how many different projects your working on, you're solving essentially the same problems over and over again. You'll probably ask yourself regularly:
How to represent an object or a process in a meaningful way to the client?
How do I reuse functionality without copy-pasting code?
What actually goes in a class / how fine-grained should classes be?
How do support variations in functionality in a class of objects based on specialization or type?
How do support variations in functionality without rewriting existing code?
How do I structure large applications to make them easy to maintain?
How do I make my code easy to test?
What I'm doing seems really convoluted / hacky, is there an easier way?
Will someone else be able to maintain the code when I'm finished?
Will I be able to maintain the code in 6 months or a year from now?
etc.
There are lots of books on the subject, and they can give you a good head start if you need a little advice. But trust me, time and practice are all you need, and it won't be too long -- maybe 6 or 9 months on a real project -- when OO idioms will be second nature.