Liskov Substitution Principle example - solid-principles

LSP is the hardest in SOLID for me to understand correctly.
LSP states that objects in a program should be replaceable with instances of their subtypes without altering the correctness of the program.
So if we have this typical rectangle - square example:
rect = new Rectangle();
rect.width = 10;
rect.height = 20;
and then we try to test it:
assert 10 == rect.width
assert 20 == rect.height
Everything is ok, but when we try to say that square is rectangle as well we use:
rect = new Square();
Square actually has both height and width the same, which will make tests fail.
So how do we resolve this problem? We segragate classes for Square and Rectangle to avoid LSP problem in this case?

In this particular example, the solution is to not let Square derive from Rectangle, because although we usually say inheritance is an 'is a' relationship, you should see it as an 'behaves like' relationship. So although mathematically, a Square is a Rectangle, a Square does certainly not behave like a Rectangle (as you prove in the code above).
Instead, let them both derive from the same base class:
public abstract class Shape { }
public class Square : Shape {
public int Size;
}
public class Rectangle : Scape {
public int Height;
public int Weight;
}

Related

Pattern creation of collectibles - LibGdx

I am working on a LibGdx running game.I have collectibles/coins in the game.
I have created a coin array,and spawned it throughout the game.
To improve the play,I want to make patterns of coins.Like 2 coins or 3 coins together , coins in vertical or diagonal arrangements etc.
I tried to implement this,but found it a difficult task as a fresher.
Please suggest me some code to implement patterns like triangle with an array of objects.
Like this:triangle with 3 coins in equal distance:
My coin array and method are included here:
I am adding new coins on the basis of last coin passes a particular distance on the screen.
Array<Coin> coins = new Array<Coin>();
private void createCoin() {
coinObj = objectFactory.createCoin(CoinEnum.random());
coinObj.isCollided = false;
coins.add(coinObj);
}
private void spawnCoin() {
if (coins.size == 0) {
createCoin();
} else {
Coin c = coins.peek();
if (c.getY() > (Constants.WORLD_HEIGHT / 8))
createCoin();
}
// remove out of screen coins
if (coins.size > 0) {
Coin cc = coins.first();
if (cc.getY() > Constants.WORLD_HEIGHT) {
coins.removeValue(cc, true);
}
}
}
Also hope someone can tell me the mistakes in my approach if any!
Thanks in advance!
First of all, try to model the CoinPattern:
- What is a CoinPattern?
It is just a pattern, describing an arrangement of multiple coins.
- What do I need to describe it?
As it is just a pattern, you don't need no Coins yet.
In my opinion, a list of Points (or Vector2) should be enough.
Each of these Points could describe the relative Position of the Object (in your case Coin) inside the Pattern.
Now you could create constants for your Patterns. The triangle could look something like this:
public static final PATTERN_TRIANGLE = new Vector2[] {
new Vector2(0,0),
new Vector2(1,0),
new Vector2(0,1),
};
Then you could create a method spawnPattern(Vector2[] pattern, int x, int y). This method should then create a Coin for every Vector2 in the pattern.
The position of each Coin could be calculated like this:
int posX = x + pattern[i].x;
int posY = y + pattern[i].y;
Note, that using this methode, the positions of the Coins are relative to the lower, left corner of the Pattern position.

Does a programming language with the following features exist?

Is there a language which will support the following concept or is there a pattern to achieve something similar with existing one?
Concept
I want to define a Rectangle with the following properties: Length, Height, Area, Perimeter; where Area = Length * Height and Perimeter = (2 * Length) + (2 * Height).
Given the statement above, if I want to create a Rectangle by giving it a Length and a Height, it should of course automatically fill out the rest of the properties.
However, it should go further and automatically allow you to create a Rectangle with any two properties (say Height and Perimeter) because that is also mathematically enough to create the same Rectangle.
Example
To help explain the idea, take this example:
//Declaration
Rectangle
{
Height, Length, Area, Perimeter;
Area = Height * Length;
Perimeter = (2 * Length) + (2 * Height);
}
//Usage
main()
{
var rectangleA = new Rectangle(Height, Length);
var rectangleB = new Rectangle(Height, Area);
Assert(rectangleA == rectangleB);
}
Notice how I didn't need to define constructors for Rectangle. Notice I did not need specify the specific logic needed if a Rectangle was created using Height and Area.
Edit: Should be rectangle and not a square for a proper example.
What you are looking for is a language with an integrated computer algebra system. It has to be able to resolve equations with respect to different variables.
While it would be possible to implement something like this, I doubt that it would make sense because in many cases there will be either no solution or multiple solutions.
Even your simple example will not work if only area and perimeter are given because there will usually be two solutions. (I assume that your class actually represents a rectangle and not a square, otherwise you should not have separate variables for length and height.)
Example:
Input: area = 2, perimeter = 6
Solution 1: length = 2, height = 1
Solution 2: length = 1, height = 2
Another remark not really related to your question: Your class obviously contains redundant member variables. This is a bad thing for various reasons, the most important being the possibility of inconsistencies. Unless you have very strict performance constraints, you should store only two of them, say length and width, and provide methods to calculate the others when needed.
Of course such a language exists. Many do, as you've now pointed out in your own comment to this answer.
In the example below I'll be using the Powerloom representation system, implemented in a language called STELLA.
You can play with it from within a Common Lisp environment.
Once you have everything installed you can load the language by running:
(cl:load "load-powerloom.lisp")
(in-package "STELLA")
(in-dialect "KIF")
That's about all you need to start building awesome geometrical objects.
Within STELLA you may define a concept with the primitive defconcept:
(defconcept Rectangle (?r)
:documentation "Curious geometrical objects that live on a plane.")
And define its properties with deffunction:
(deffunction rect-height ((?t Rectangle)) :-> (?n INTEGER))
(deffunction rect-length ((?t Rectangle)) :-> (?n INTEGER))
(deffunction area ((?t Rectangle)) :-> (?n INTEGER))
(deffunction perimeter ((?t Rectangle)) :-> (?n INTEGER))
To make the relations between area, perimeter and the sides of your rectangle, you'll have to make some assertions. That's what you'll have assert for.
(assert (forall (?t Rectangle)
(= (area ?t) (* (rect-height ?t) (rect-length ?t)))))
(assert (forall (?t Rectangle)
(= (perimeter ?t) (+ (* 2 (rect-height ?t))
(* 2 (rect-length ?t))))))
You are telling STELLA that for all rectangles, the area is the product of height and length, and that for all rectangles, the perimeter is twice the height plus twice the length.
Now you can instantiate your objects, and it doesn't matter what properties you give it, as long as they make sense.
(definstance rect1 :Rectangle true :rect-height 10 :rect-length 10)
(definstance rect2 :Rectangle true :area 40 :rect-height 20)
Here you instantiate rect1 with height and length as parameters, and rect2 with area and height.
But its always good to check that the language is doing what you expect:
STELLA> (retrieve all ?x (= (area rect1) ?x))
There is 1 solution:
#1: ?X=100
STELLA> (retrieve all ?x (= (rect-length rect2) ?x))
There is 1 solution:
#1: ?X=2
If you ever get tired of rectangles and decide to build a beautiful square, why not derive a concept?
(defconcept Square ((?r Rectangle))
:documentation "Weird rectangles that fascinated the Greeks"
:<=> (= (rect-height ?r) (rect-length ?r)))
Simply tell STELLA that squares are rectangles where height and length are equal.
Now try it out:
STELLA> (definstance nice-rectangle :Rectangle true :rect-length 10 :area 100)
|i|NICE-RECTANGLE
STELLA> (ask (Square nice-rectangle))
TRUE
I'm not an expert at all, but I find the language fascinating. It's sad that there is so little information about it on the internet. Even the manual is incomplete.
For more information I'd suggest starting with these slides.
The famous book SICP teaches how to build a nondeterministic evaluator for such a language here.
And finally, a wonderful write up describing motivations and applications behind these ideas can be seen here.
In C#, you can use properties, which have implicit getters and setters. That way you can write something like:
public class Square {
public int Length {
get { return length; }
set { length = value; }
}
public int Area {
get { return length * length; }
set { length = Math.Sqrt(value); }
}
public int Perimeter {
get { return length * 4; }
set { length = value / 4; }
}
private int length;
}
Now you can write:
Square square = new Square();
square.Length = 2;
Console.WriteLine(square.Length); // "2"
Console.WriteLine(square.Area); // "4"
Console.WriteLine(square.Perimeter); // "8"
square.Area = 9;
Console.WriteLine(square.Length); // "3"
Console.WriteLine(square.Area); // "9"
Console.WriteLine(square.Perimeter); // "12"
Edit:
C# also allows you name properties at your choosing when instantiating an object:
Square square1 = new Square { Perimeter = 12 };
Square square2 = new Square { Length = 4 };
I don't think something like this does exist in the form of a programming language.
Ontology
However the first approach I can think about is defining an Ontology, I mean a set of rules about
Entities: Rectangle, Square, Dog, Car, etc...
Attributes: Area, Height, Number of Wheels, etc...
Relations between (1) and (2): Rectangle's Area is Height * Width, ...
Now given a list of attributes and the required output Entity
I have height and width and I need a Rectangle
the system could search for a path through the rules graph to produce the required outcome based on the provided inputs.
Real world example
Wolfram Alpha probably follows the technique described above

How to tween alpha of a BitmapFontCache in libgdx?

I am animating some text in my libgdx application and would like a label text to fade-in and move (e.g. similar to this jsfiddle).
I can move, and change alpha of other objects (e.g. Sprites) and can move BitmapFontCaches. However I can't get alpha of the BitmapFontChage to change.
Declaration:
message = new BitmapFontCache(messageFont, true);
message.setWrappedText("some text", 10.0f, 10.0f, 10.0f);
message.setAlphas(0.0f);
In my screen class, I override the render method, and call .draw() on a renderer class, which is (among other things) essentially just a message.draw(batch); call.
#Override
public void render(float delta) {
...
try{
batch.begin();
feedbackRenderer.draw(batch);
tweenManager.update(delta);}
finally{
batch.end();
}
}
Then as a part of a timeline I call these two Tweens. (yes, they are wrapped in .push( ) and I do start my tweenManager:)
Tween.to(message, BitmapFontCacheAccessor.POSITION_X, animationDuration)
.target(35.0f)
Tween.to(message, BitmapFontCacheAccessor.ALPHA, animationDuration)
.target(1.0f)
The BitmapFontCacheAccessor tries to setAlphas() of the BitmapFontCache as such:
public class BitmapFontCacheAccessor implements TweenAccessor<BitmapFontCache> {
public static final int POSITION_X = 1;
public static final int ALPHA = 2;
#Override
public void setValues(BitmapFontCache target, int tweenType, float[] newValues) {
switch (tweenType) {
case POSITION_X:
float y = target.getY();
target.setPosition(newValues[0], y);
break;
case ALPHA:
target.setAlphas(newValues[0]);
break;}
}...
It moves the label (==> .setPosition(x, y) works!), but does not even touch the alpha. This exact same approach works for Sprites, which fade in nicely.
Is there perhaps some catch when tweening alpha for the BitmapFontCache? Is it possible?
Many thanks!
After a good hour of debugging I have found the reason for this funny behavior.
Libgdx's BitmapFontCache does not have a getAlphas() method
Therefore, to get the alpha channel I used getColor().a
However, these two are not always synced. The behavior is quite random, I myself am not quite sure when it syncs and when it doesn't (f.ex. in the question above, the fade-outs would work, but fade-ins wouldn't)
The solution is to change and declare BOTH alpha channels.
Definition of BitmapFontCache:
message = new BitmapFontCache(messageFont, true);
message.setColor(1,1,1,0);
message.setAlphas(0);
and inside TweenAccessor:
case ALPHA:
//first alpha channel
target.setAlphas(newValues[0]);
//second alpha channel
Color c = target.getColor();
c.a = newValues[0];
target.setColor(c);
break;
To you, hopeless SO wanderer, I address this answer so that you can spend some of the finite number of minutes of your life better than I did.

Camera movement in AS3

OK so i have a character that moves with the mouse. I need it to stay in the center of the screen(kind of like a platformer game). I can't figure out how to access the camera and move it. (Note: I have tried Vcam and moving all of the other objects but Vcam makes the file slow or something [or so i have heard] and moving the other objects in kind of like cheating [and for my needs is insufficient]) I don't have any code because i don't know where to start. Maybe someone can point me into the right direction.
Thanks,
Thor
One way is to store everyhting in one DisplayObject and then move that single object based on the camera movement. Instead of moving the camera, move the main container the opposite direction of the camera. I'm not sure why you seem to suggest a strategy like this is "cheating" as it is a perfectly suitable way to doing this.
This is my previous answer on a similar question found here.
What I do here is:
Create a Map class with a property camera which is another custom class MapCamera.
The MapCamera has five properties:
_x
_y
map - a reference to the instance of Map owning this MapCamera
offsetX
offsetY
The offset values represent the x and y spacing from the left and top edges of the screen, which should be set to half of the stage width and height so that the camera will centre on the stage correctly.
The _x and _y properties are private, and have getters and setters.
The getters are pretty basic:
public function get x():Number{ return _x; }
public function get y():Number{ return _y; }
The setters are where the viewport will be altered, like so:
public function set x(n:Number):void
{
_x = n;
map.x = -(_x + offsetX);
}
public function set y(n:Number):void
{
_y = n;
map.y = -(_y + offsetY);
}
From here, you add your children into the Map container and then can simply go:
map.camera.x = player.x;
map.camera.y = player.y;
Which will cause the player to always be in the centre of the screen.
Your camera is only a vector that modifies position of all renderable objects.
myMovieClip.x = movingClipPosition.x + camera.x
So if the camera.x is moved to the right, this will make the object move the left, giving the impression of a "camera".

AS3: Viewports without an end

I'm making a space navigation game. So it starts with the user on the spaceship and then when he press the up key the ship goes forward, the 'map' is always different, I have 5 variations of stars and 2 variations of planets, so they basically 'spawn' randomly while the user navigates. I can make the key detection, the movie clips generator code, but I don't know how do I make the navigation code, I mean how do I make the viewport move when the user press the key, ... I've saw a code that I didn't understand too well that the guy basically created a giant movie clip that moves according to the key that was pressed. That won't work in my case because I want it to generate everything randomly and when the user press the down arrow, I want it to go back, with the same 'map' that he was before. Please help me out guys I'm totally confused with all this viewport thing. And also, I want the game to run fast, I'm kind of new to the Action Script, and I don't know if it gets heavy if you are rendering objects that are not being displayed, if so will a simple 'obj.visible = false' works? Thanks in advance.
What I do here is:
Create a Map class with a property camera which is another custom class MapCamera.
The MapCamera has five properties:
_x
_y
map - a reference to the instance of Map owning this MapCamera
offsetX
offsetY
The offset values represent the x and y spacing from the left and top edges of the screen, which should be set to half of the stage width and height so that the camera will centre on the stage correctly.
The _x and _y properties are private, and have getters and setters.
The getters are pretty basic:
public function get x():Number{ return _x; }
public function get y():Number{ return _y; }
The setters are where the viewport will be altered, like so:
public function set x(n:Number):void
{
_x = n;
map.x = -(_x + offsetX);
}
public function set y(n:Number):void
{
_y = n;
map.y = -(_y + offsetY);
}
From here, you add your children into the Map container and then can simply go:
map.camera.x = player.x;
map.camera.y = player.y;
Which will cause the player to always be in the centre of the screen.