#include <stdio.h>

class Graphics
{
public:
	void DrawEllipse(int x1,int y1,int x2,int y2)
	{
		printf("DrawEllipse %d,%d,%d,%d\n",x1,y1,x2,y2);
	}
	
	void DrawRectangle(int x1,int y1,int x2,int y2)
	{
		printf("DrawRectangle %d,%d,%d,%d\n",x1,y1,x2,y2);
	}
	
	void DrawLine(int x1,int y1,int x2,int y2)
	{
		printf("DrawLine %d,%d,%d,%d\n",x1,y1,x2,y2);
	}
};

class PersonBuilder
{
public:
	PersonBuilder(Graphics _g) : g(_g){}
	
	virtual void BuildHead()=0;
	virtual void BuildBody()=0;
	virtual void BuildArmLeft()=0;
	virtual void BuildArmRight()=0;
	virtual void BuildLegLeft()=0;
	virtual void BuildLegRight()=0;
protected:
	Graphics g;
};

class PersonThinBuilder : public PersonBuilder
{
public:
	PersonThinBuilder(Graphics g) : PersonBuilder(g){}
	
	virtual void BuildHead()
	{
		g.DrawEllipse(50,20,30,30);
	}
	
	virtual void BuildBody()
	{
		g.DrawRectangle(60,50,10,50);
	}
	
	virtual void BuildArmLeft()
	{
		g.DrawLine(60,50,40,100);
	}
	
	virtual void BuildArmRight()
	{
		g.DrawLine(70,50,90,100);
	}
	
	virtual void BuildLegLeft()
	{
		g.DrawLine(60,100,45,150);
	}
	
	virtual void BuildLegRight()
	{
		g.DrawLine(70,100,85,150);
	}
};

class PersonFatBuilder : public PersonBuilder
{
public:
	PersonFatBuilder(Graphics g) : PersonBuilder(g){}
	
	virtual void BuildHead()
	{
		g.DrawEllipse(50,20,30,30);
	}
	
	virtual void BuildBody()
	{
		g.DrawEllipse(60,50,10,50);
	}
	
	virtual void BuildArmLeft()
	{
		g.DrawLine(60,50,40,100);
	}
	
	virtual void BuildArmRight()
	{
		g.DrawLine(70,50,90,100);
	}
	
	virtual void BuildLegLeft()
	{
		g.DrawLine(60,100,45,150);
	}
	
	virtual void BuildLegRight()
	{
		g.DrawLine(70,100,85,150);
	}
};

class PersonDirector
{
public:
	PersonDirector(PersonBuilder* _pb) : pb(_pb){}
	
	void CreatePerson()
	{
		pb->BuildHead();
		pb->BuildBody();
		pb->BuildArmLeft();
		pb->BuildArmRight();
		pb->BuildLegLeft();
		pb->BuildLegRight();
	}
protected:
	PersonBuilder* pb;
};

int main()
{
	Graphics gThin,gFat;
	
	PersonThinBuilder* ptb = new PersonThinBuilder(gThin);
	PersonDirector* pdThin = new PersonDirector(ptb);
	pdThin->CreatePerson();
	
	PersonFatBuilder* pfb = new PersonFatBuilder(gFat);
	PersonDirector* pdFat = new PersonDirector(pfb);
	pdFat->CreatePerson();
	
	delete ptb;
	delete pdThin;
	delete pfb;
	delete pdFat;
	return 0;
}