Say you need to create a special string that does shows floating point numbers.
Lets put another constraint , say you need to show upto K decimal places.
e.g u need an output like this
123.45 <--- 2 decimal places
say double d = 123.456
then u can create a string which shows upto 2 decimal places like this.
ostringstream o;
o.setf(ios::fixed);
o.precision(2);
o << d;
cout << o.str();
Saturday, June 16, 2007
Thursday, June 14, 2007
Const in C++
The const keyword in C++ is a very useful keyword . Apart from declaring constants it is useful in declaring few important things . Lets talk about two important const advantages
Pointer to a const basically says that the object being pointed to by the pointer should remain const and the pointer should not try to change the contents of that object . But this does not mean that that value of the object will not get changed m it just says the given pointer is not going to change the value of the object.
e.g String(const char * = ""){
.....
}
a simple rule of thumb is that if the function is not going to modify the object it should accept a const object
const reference:
void do_something(const Thing &);
This is analogous to pointers , the only advantage is that by declaring a reference const you prevent unnamed temporaries . Basically its the same concept which says if your not gonna change it then pass it as a const .
cannot use do_something(get_something()) // un named temporary not allowed
Things get_something();
Thing t(get_something());
void do_something(Thing&);
Const member functions:
const member function are member function in which the argument list is followed by the const keyword. In a const instance of an object only const member functions can be invoked.
From non const member functions unnamed temporaries can be invoked.
- pointer to a const
- const reference
Pointer to a const basically says that the object being pointed to by the pointer should remain const and the pointer should not try to change the contents of that object . But this does not mean that that value of the object will not get changed m it just says the given pointer is not going to change the value of the object.
e.g String(const char * = ""){
.....
}
a simple rule of thumb is that if the function is not going to modify the object it should accept a const object
const reference:
void do_something(const Thing &);
This is analogous to pointers , the only advantage is that by declaring a reference const you prevent unnamed temporaries . Basically its the same concept which says if your not gonna change it then pass it as a const .
cannot use do_something(get_something()) // un named temporary not allowed
Things get_something();
Thing t(get_something());
void do_something(Thing&);
Const member functions:
const member function are member function in which the argument list is followed by the const keyword. In a const instance of an object only const member functions can be invoked.
From non const member functions unnamed temporaries can be invoked.
Implementing operator as member or nonmember functions
The answer to implementing an operator as a member or a non member lies in the following simple points
- if any operand of an operator is susceptible to implicit type conversion , implement it as a member function
- if the result of an operation does not effect the two operands or an operand implement it as a non-member function.
Sunday, June 10, 2007
Tutorial: Writing a Tetris Clone using XNA
One of the Hello World programs in game programming is Tetris . I am making the assumption that you the reader have played tetris and know the rules of this simple game knows C# and under stands Object Oriented Concepts . Tetris is a very simple game , simple graphics simple collision detection and animation if you want to call the rotation of blocks as animation . So lets not any more time and lets get started with the code and step by step explanation of how to create a Tetris Using XNA .
Step 1:
Step 1 is figuring out all the the blocks that are used in the Tetris game . If you think about the game it consists of the following blocks
Step 2:
In step 2 ,we will try to see as to how we can map these blocks to their corresponding images and as to how we can rotate the blocks and their corresponding images .Since we saw that each block is made up of 4 squares , we can label the squares as 1 , 2 ,3 ,4 correspondingly . Out of these 4 squares , 1 square we will mark as the pivot around which the block can rotate .
See the image below for a clear understanding of this:
If you look at the blocks they have different names , like L , J , S which basically identify their shape . Each square in a block is numbered and one of the square is circled . The circled square is the pivot for the given block . If you look carefully at block S , that block on rotation looks like the block mentioned directly below it .
Step 3
Now that we understand the basics of the representation and requirements we can get down to some coding , i ll try to avoid the XNA related code till the end . I will try to explain how this simple representation of blocks can be represented using code.
Since we have a number of blocks and each block can rotate and move left , right , down. Also each block has a direction and a current position . So basically every object in this simple game is block and since all these blocks have few things in common , we can take that common functionality and create a simple abstract class called Block . We can then have each one of the blocks extends from this base class called Block . Since the next block that falls from the top should be randomized , we can create BlockFactory that generates these blocks for us . This factory can create an instance of each type of block and cache it . So that we can reuse the block instances . Now that i have explained how Block , BlockFactory fit together lets look at the code for Block :
Step 4:
Lets start with the Square class . A block uses 4 squares . The code for the Square class is pretty simple and looks like this :
The square class is pretty simple . Next there is an interface called Direction .
which looks like this
I have 4 classes implementing this interface . The classes being East , West , South and North . Lets look at the code for the East class .
Directions is not a true factory , but just holds static references to different
types of directions . The movement class is also similar in nature to the direction
class . The movement class is an abstract class and there are classes like Left ,
Right , Down that inherit from Movement . Again Movements is similar in nature to
Directions .
To be continued ....
Step 1:
Step 1 is figuring out all the the blocks that are used in the Tetris game . If you think about the game it consists of the following blocks
- a line
- a square shaped block
- a L shaped block
- a J shaped block
- a S shaped block
- a T shaped block
- a Z shaped block
Step 2:
In step 2 ,we will try to see as to how we can map these blocks to their corresponding images and as to how we can rotate the blocks and their corresponding images .Since we saw that each block is made up of 4 squares , we can label the squares as 1 , 2 ,3 ,4 correspondingly . Out of these 4 squares , 1 square we will mark as the pivot around which the block can rotate .
See the image below for a clear understanding of this:
If you look at the blocks they have different names , like L , J , S which basically identify their shape . Each square in a block is numbered and one of the square is circled . The circled square is the pivot for the given block . If you look carefully at block S , that block on rotation looks like the block mentioned directly below it .
Step 3
Now that we understand the basics of the representation and requirements we can get down to some coding , i ll try to avoid the XNA related code till the end . I will try to explain how this simple representation of blocks can be represented using code.
Since we have a number of blocks and each block can rotate and move left , right , down. Also each block has a direction and a current position . So basically every object in this simple game is block and since all these blocks have few things in common , we can take that common functionality and create a simple abstract class called Block . We can then have each one of the blocks extends from this base class called Block . Since the next block that falls from the top should be randomized , we can create BlockFactory that generates these blocks for us . This factory can create an instance of each type of block and cache it . So that we can reuse the block instances . Now that i have explained how Block , BlockFactory fit together lets look at the code for Block :
Step 3 was big , indeed it was a mini Leap . But it was needed . In Step i will be talking about the classes that are used by above code .
public abstract class Block
{
// the background image used by the game
protected Texture2D backgroundTexture;
// the current position of the block
protected Vector2 position;
// the 4 squares used by each block
protected Square square1;
protected Square square2;
protected Square square3;
protected Square square4;
// before we rotate the block and calculate the new position for the squares
// we'll use the following variables to store the old positions
protected Vector2 _oldSquare1Position;
protected Vector2 _oldSquare2Position;
protected Vector2 _oldSquare3Position;
protected Vector2 _oldSquare4Position;
// the game field where the actual game is being played
// i ll talk about this later
protected GameField gameField;
// the direction of the block
private Direction direction;
// the movement of the block
private Movements.Movements movements;
// this constructor for the block , this is where the block gets created
// it is given an initial position and a direction , based on this starting
// position the 4 squares get initialized
public Block(GameField gameField, Texture2D backgroundTexture, Vector2 origin , Direction direction)
{
this.backgroundTexture = backgroundTexture;
this.position = origin;
this.direction = direction;
this.gameField = gameField;
square1 = new Square(this.backgroundTexture, position);
square2 = new Square(this.backgroundTexture, position);
square3 = new Square(this.backgroundTexture, position);
square4 = new Square(this.backgroundTexture, position);
movements = new Movements.Movements(this,gameField);
// ignore this for while i ll talk about this
setupBlock();
}
// the code that will respond when a block of a given shape is rotatated to
// the North ,
public abstract void RotateTo(North north);
// similarly it also works for East , West , South
// the core rotating logic is here , first of all we save the positions of
// the 4 squares , then based on the current direction we try to rotate
// the current block , this gives us a new set of positions for the 4 squares
// and a new direction for the block , then we make a final check if we can
// possible rotate if not we revert back to the saved positions .
public void Rotate()
{
savePositions();
this.direction = direction.Rotate(this);
if (!canRotate())
revertPositions();
}
// Similar to rotation we first of all save all the positions of the 4
// squares , based on the current movement we check if we can move to the
// left the given number of units , if the block can move we move else
// we revert back to the saved positions .
public virtual void MoveLeft(int units)
{
savePositions();
if (movements.LEFT.CanMove(units))
{
square1.MoveLeft(units);
square2.MoveLeft(units);
square3.MoveLeft(units);
square4.MoveLeft(units);
}
else
revertPositions();
}
// similar logic applies for Right and Down
// the draw method for the block draws the block , by drawing all the 4
// squares , ignore the SpriteBatch i ll talk about that later
public virtual void Draw(SpriteBatch batch)
{
// draw the given square at the given position
batch.Draw(square1.Texture, square1.Position, Color.White);
batch.Draw(square2.Texture, square2.Position, Color.White);
batch.Draw(square3.Texture, square3.Position, Color.White);
batch.Draw(square4.Texture, square4.Position, Color.White);
}
protected void savePositions()
{
_oldSquare1Position = square1.Position;
_oldSquare2Position = square2.Position;
_oldSquare3Position = square3.Position;
_oldSquare4Position = square4.Position;
}
protected bool canRotate()
{
return canRotate(square1) &&
canRotate(square2) &&
canRotate(square3) &&
canRotate(square4);
}
protected void revertPositions()
{
square1.Position = _oldSquare1Position;
square2.Position = _oldSquare2Position;
square3.Position = _oldSquare3Position;
square4.Position = _oldSquare4Position;
}
// ask the gameField if the given square can rotate
private bool canRotate(Square square)
{
return gameField.CanRotate(square);
}
}
Step 4:
Lets start with the Square class . A block uses 4 squares . The code for the Square class is pretty simple and looks like this :
public class Square
{
.....
// move the position of the square to the left by given units
public void MoveLeft(int units)
{
position.X = position.X - units;
}
...
// move the position down by given unite
public void MoveDown(int units)
{
position.Y = position.Y + units;
}
...
The square class is pretty simple . Next there is an interface called Direction .
which looks like this
public interface Direction
{
Direction Rotate(Block block);
}
I have 4 classes implementing this interface . The classes being East , West , South and North . Lets look at the code for the East class .
// East implements the Direction class
public class East : Direction
{
// the rotate method tells the block to rotate itself in the east
// direction . Remember the abstract method in Block that rotate in
// different direction , this is where they are used . Why i did this
// well depending upon the shape of the block and using this type of
// reverse delegation helps in keeping the code managable
public Direction Rotate(Block block)
{
block.RotateTo(this);
// since the next direction in clockwise manner is South return that .
return Directions.SOUTH;
}
}
Directions is not a true factory , but just holds static references to different
types of directions . The movement class is also similar in nature to the direction
class . The movement class is an abstract class and there are classes like Left ,
Right , Down that inherit from Movement . Again Movements is similar in nature to
Directions .
To be continued ....
Subscribe to:
Posts (Atom)
Labels
. linux
(1)
algorithm
(15)
analytics
(1)
bash
(2)
bigoh
(1)
bruteforce
(1)
c#
(1)
c++
(40)
collections
(1)
commands
(2)
const
(1)
cosine similarity
(1)
creating projects
(1)
daemon
(1)
device_drivers
(1)
eclipse
(6)
eclipse-plugin-development
(9)
equals
(1)
formatting
(1)
freebsd
(1)
game programming
(1)
hashcode
(1)
heap
(1)
heaps
(1)
immutable-objects
(1)
java
(19)
JDT
(1)
kernel
(1)
linux
(4)
little sugar
(23)
logging
(1)
machine learning
(1)
marker-resolution
(1)
markers
(1)
mergesort
(1)
mixins
(1)
numbers
(1)
opengl
(2)
patterns
(2)
priority-queue
(1)
programming
(51)
ps
(1)
ranking
(1)
refactoring
(3)
references
(1)
security
(1)
set
(1)
shell
(1)
similarity
(1)
statistics
(1)
stl
(1)
tetris
(1)
threads
(1)
trees
(2)
unicode
(1)
unix
(2)
views
(2)
windows programming
(2)
XNA
(1)