110,533
社区成员
发帖
与我相关
我的任务
分享
public class Bottle : Element, IVisible
{
const int SIZE_FACTOR = 10;
#region Variables
int content = 0;
int capacity = 0;
Size size = Size.Empty;
Rectangle bounds = Rectangle.Empty;
Bitmap canvas;
Graphics painter;
bool dirty = true;
#endregion
#region Properties
public int FreeSpace
{
get { return capacity - content; }
}
public int Content
{
get { return content; }
}
public int Capacity
{
get { return capacity; }
}
public bool IsEmpty
{
get { return content == 0; }
}
public bool IsFull
{
get { return content == capacity; }
}
#endregion
#region Initiators
public Bottle(int capacity)
: this(capacity, 0)
{
}
public Bottle(int capacity, int content)
{
if (capacity > 0)
{
this.capacity = capacity;
if (content > -1 && content <= capacity)
this.content = content;
size.Width = 30;
size.Height = SIZE_FACTOR * capacity;
bounds.Size = size;
canvas = new Bitmap(size.Width, size.Height);
painter = Graphics.FromImage(canvas);
}
}
#endregion
#region Methods
public void DropIn()
{
DropIn(capacity);
}
public void DropIn(int amount)
{
if (amount > 0)
{
content += amount;
if (content > capacity)
content = capacity;
dirty = true;
}
}
public void DropOut()
{
DropOut(capacity);
}
public void DropOut(int amount)
{
if (amount > 0 && amount < content)
{
content -= amount;
}
else
{
content = 0;
}
dirty = true;
}
#endregion
#region IVisible
public Rectangle Bounds
{
get { return bounds; }
}
public int X
{
get { return bounds.X; }
set { bounds.X = value; }
}
public int Y
{
get { return bounds.Y; }
set { bounds.Y = value; }
}
public Bitmap Draw()
{
if (dirty)
{
painter.Clear(Color.Transparent);
// simple look bottle
int contentHeight = (int)((float)bounds.Height * ((float)content / (float)capacity));
if (contentHeight > 0)
{
using (Brush b = new LinearGradientBrush(
new Rectangle(
0,
bounds.Height - contentHeight - 1,
bounds.Width,
contentHeight
),
Color.LightBlue,
Color.DarkBlue,
90))
{
Rectangle contentRect = new Rectangle(
0,
bounds.Height - contentHeight,
bounds.Width,
contentHeight
);
painter.FillRectangle(b, contentRect);
}
}
painter.DrawRectangle(
Pens.Silver,
0,
0,
bounds.Width - 1,
bounds.Height - 1
);
string s = string.Format("{0}/{1}", content, capacity);
painter.DrawString(
s,
SystemFonts.DefaultFont,
Brushes.Black,
2,
1
);
painter.DrawString(
s,
SystemFonts.DefaultFont,
Brushes.Black,
1,
2
);
painter.DrawString(
s,
SystemFonts.DefaultFont,
Brushes.Black,
2,
3
);
painter.DrawString(
s,
SystemFonts.DefaultFont,
Brushes.Black,
3,
2
);
painter.DrawString(
s,
SystemFonts.DefaultFont,
Brushes.White,
2,
2
);
dirty = false;
}
return canvas;
}
#endregion
#region Elemenet
public override Type Type
{
get { return typeof(Bottle); }
}
#endregion
}
public class World
{
const int PADDING = 20;
#region Variables
List<Bottle> bottles = new List<Bottle>();
Rectangle bounds = Rectangle.Empty;
#endregion
#region Properties
public List<Bottle> Bottles
{
get { return bottles; }
}
public Rectangle Bounds
{
get { return bounds; }
set
{
bounds = value;
arrangeBottles();
}
}
#endregion
#region Initiators
public World()
{
}
public World(Rectangle bounds)
{
this.bounds = bounds;
}
#endregion
#region world methods
public Bottle CreateBottle(int capacity)
{
return CreateBottle(capacity, 0);
}
public Bottle CreateBottle(int capacity, int content)
{
Bottle b = new Bottle(capacity, content);
bottles.Add(b);
arrangeBottles();
return b;
}
public void DestroyBottle()
{
bottles.Clear();
}
public void DestroyBottle(Bottle b)
{
bottles.Remove(b);
}
public void DestroyBottle(int capacity)
{
List<Bottle> tmp = new List<Bottle>();
foreach (Bottle b in bottles)
{
if (b.Capacity != capacity)
tmp.Add(b);
}
bottles.Clear();
bottles.AddRange(tmp);
}
#endregion
#region paint helpers
Size getTotalSize()
{
Size sz = Size.Empty;
foreach (Bottle b in bottles)
{
sz.Width += PADDING + b.Bounds.Width;
if (sz.Height < b.Bounds.Height)
sz.Height = b.Bounds.Height;
}
return sz;
}
void arrangeBottles()
{
Size sz = getTotalSize();
Point offset = new Point(
(bounds.Width - sz.Width) / 2,
(bounds.Height - sz.Height) / 2 + sz.Height
);
foreach (Bottle b in bottles)
{
b.X = offset.X;
b.Y = offset.Y - b.Bounds.Height;
offset.X += PADDING + b.Bounds.Width;
}
}
#endregion
}
public class Game
{
string name = string.Empty;
int bottleCount = 0;
bool initiated = false;
int targetBottle = -1;
int targetAmount = -1;
World world;
Random rand = new Random();
public string Name
{
get { return name; }
}
public int Target
{
get { return targetBottle; }
}
public int Amount
{
get { return targetAmount; }
}
public World World
{
get { return world; }
}
public Game()
{
world = new World();
}
/// <summary>
/// Difficaulty of game.
/// </summary>
/// <param name="difficaulty">Difficaulty from 1 to 3.</param>
public void AutoGenerate(int difficaulty)
{
if (difficaulty < 1)
return;
world.DestroyBottle();
int bottleCount = rand.Next(3, 5); //3 + difficaulty);
targetBottle = rand.Next(0, bottleCount - 1);
int maxAmount = 10;
for (int i = 0; i < bottleCount; i++)
{
int cap = 0;
do
cap = rand.Next(3, maxAmount + difficaulty);
while (capacityInside(cap));
world.CreateBottle(cap);
}
targetAmount = rand.Next(1, world.Bottles[targetBottle].Capacity);
initiated = true;
}
bool capacityInside(int cap)
{
foreach (Bottle b in world.Bottles)
if (b.Capacity == cap)
return true;
return false;
}
public bool CheckSuccess()
{
if (targetBottle > -1)
if (initiated && world.Bottles.Count > targetBottle)
return world.Bottles[targetBottle].Content == targetAmount;
return false;
}
}