Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace OOP_HW08
{
public partial class Form1 : Form
{
List ShapeList = new List();
private Label[] lbl_ArrayFeature;
private TextBox[] txt_ArrayFeature;
//Status check
bool isLeagle = true;
bool isClean = false;
bool calculated = false;
//I/P check
private int _checkInt = 0;
private double _checkDouble = 0;
//Error O/P
private string _error = "";
// Methods (Front Panel I/O)
bool[,] VisibleTable = { { true, false },
{ true, false },
{ true, true },
{ true, true } };
string[,] FeatureText = { { "半徑", "" },
{ "邊長", "" },
{ "半徑", "高度" },
{ "邊長", "高度" } };
public Form1()
{
InitializeComponent();
lbl_ArrayFeature = new Label[] { lbl_Radius, lbl_Height };
txt_ArrayFeature = new TextBox[] { txt_Radius, txt_Height };
}
private void btn_AddShape3D_Click(object sender, EventArgs e)
{
CheckInPut_Add();
if (!isLeagle)
{
isLeagle = true;
return;
}
Initialize();
//Create obj. by selection
switch (cmb_Shape.SelectedIndex)
{
case 0: //Ball
Ball ball = new Ball(cmb_Material.SelectedIndex, double.Parse(txt_Radius.Text));
ShapeList.Add(ball);
break;
case 1: //Cube
Cube cube = new Cube(cmb_Material.SelectedIndex, double.Parse(txt_Radius.Text));
ShapeList.Add(cube);
break;
case 2: //Cylinder
Cylinder cylinder = new Cylinder(cmb_Material.SelectedIndex, double.Parse(txt_Radius.Text), double.Parse(txt_Height.Text));
ShapeList.Add(cylinder);
break;
case 3: //Pyramid
Pyramid pyramid = new Pyramid(cmb_Material.SelectedIndex, double.Parse(txt_Radius.Text), double.Parse(txt_Height.Text));
ShapeList.Add(pyramid);
break;
default:
MessageBox.Show("請選擇形狀!");
return;
}
ShapeList[ShapeList.Count - 1].Order = ShapeList.Count -1; //Refresh the order
txt_Result.AppendText(ShapeList[ShapeList.Count - 1].Order + "\t" + ShapeList[ShapeList.Count - 1].ShowNameAndDensity() + "\n"); //Refresh the result
UpdateShapesAmount();
}
private void CheckInPut_Add()
{
//I/P check
bool isMatNull = (cmb_Material.SelectedItem == null);
bool isShapeNull = (cmb_Shape.SelectedItem == null);
bool isRadiDouble = (double.TryParse(txt_Radius.Text, out _checkDouble));
bool isHeightDouble = (double.TryParse(txt_Height.Text, out _checkDouble));
bool isBallSelected = (cmb_Shape.SelectedIndex == 0);
bool isCylinderSelected = (cmb_Shape.SelectedIndex == 2);
//Check I/P
if (isMatNull)
{
_error += "材質";
}
if (isShapeNull)
{
_error += " 形狀";
}
if (!isRadiDouble)
{
_error += " 半徑/邊長";
}
else {
bool isRadiNegative = (double.Parse(txt_Radius.Text) < 0);
if (isRadiNegative)
{
_error += " 半徑/邊長";
}
}
if (isBallSelected || isCylinderSelected)
{
if (!isHeightDouble)
{
_error += " 高度";
}
else
{
bool isHeightNegative = (double.Parse(txt_Height.Text) < 0);
if (isHeightNegative)
{
_error += " 高度";
}
}
}
//Situation: Incomplete I/P
if (_error.Length != 0)
{
isLeagle = false;
ShowError(_error);
_error = "";
}
}
private void Initialize()
{
if (!isClean)
{
ShowList("Clean");
ShapeList.Clear();
Ball.Amount = 0;
Cube.Amount = 0;
Cylinder.Amount = 0;
Pyramid.Amount = 0;
calculated = false;
isClean = true;
}
}
//Change the I/P by selection
private void cmb_Shape_SelectedIndexChanged(object sender, EventArgs e)
{
ChangeVisible();
}
private void ChangeVisible()
{
int Index = cmb_Shape.SelectedIndex;
for (int i = 0; i < lbl_ArrayFeature.Length; i++)
{
lbl_ArrayFeature[i].Visible = VisibleTable[Index, i];
txt_ArrayFeature[i].Visible = VisibleTable[Index, i];
lbl_ArrayFeature[i].Text = FeatureText[Index, i];
}
}
//Calculate
private void btn_cal_Click(object sender, EventArgs e)
{
if (!calculated)
{
Sort();
//RefreshOrder();
ShowList("Calculate");
//Initialization
isClean = false;
calculated = true;
}
}
private void btn_DeleteShape_Click(object sender, EventArgs e)
{
CheckInPut_Delete();
if (!isLeagle)
{
isLeagle = true;
return;
}
//Situation: Check passed, start deletion
Delete();
//Garbage collection
GC.Collect();
GC.WaitForPendingFinalizers();
//Update the result
RefreshOrder();
UpdateShapesAmount();
ShowList("Delete");
//Initialization
calculated = false;
}
private void CheckInPut_Delete()
{
//I/P check
bool isDelNumInt = (int.TryParse(txt_DeleteNum.Text, out _checkInt));
//Check I/P
if (!isDelNumInt)
{
_error += "刪除編號";
}
else {
bool isDelNumOutOfRange = (int.Parse(txt_DeleteNum.Text) >= ShapeList.Count);
bool isDelNumNegative = (int.Parse(txt_DeleteNum.Text) < 0);
if (isDelNumOutOfRange || isDelNumNegative)
{
_error += "刪除編號";
}
}
if (_error.Length != 0)
{
isLeagle = false;
ShowError(_error);
_error = "";
}
}
private void Delete() {
int order = int.Parse(txt_DeleteNum.Text);
int count = 0;
foreach (var shape in ShapeList)
{
//Check the order
bool sameOrder = (shape.Order == order);
//Order check
if (sameOrder)
{
//Forced deletion
ShapeList[count] = null;
ShapeList.RemoveAt(count);
break;
}
count++;
}
}
private void cmb_sort_SelectedIndexChanged(object sender, EventArgs e)
{
calculated = false;
}
private void RefreshOrder()
{
int count = 0;
ShapeList.Sort(SortByOrder);
foreach (var shape in ShapeList)
{
shape.Order = count;
count++;
}
}
private void UpdateShapesAmount()
{
txt_BallAmount.Text = Ball.Amount.ToString();
txt_CubeAmount.Text = Cube.Amount.ToString();
txt_CylinderAmount.Text = Cylinder.Amount.ToString();
txt_PyramidAmount.Text = Pyramid.Amount.ToString();
txt_amount.Text = ShapeList.Count.ToString();
}
//Show error message
private void ShowError(string Error) {
MessageBox.Show(Error + " 之輸入資料有誤!");
}
//Show data
private void ShowList(string Case) {
string paraline = "編號" + "\t" + "種類" + "\t" + "徑/長" + "\t" + "高度" + "\t" + "密度" + "\t";
string newline = "\n" + "==============================================================" + "\n";
switch (Case)
{
case "Clean":
txt_Result.Text = (paraline + newline);
break;
case "Calculate":
txt_Result.AppendText(newline + "==========================" + cmb_Sort.Text + "==========================" + "\n");
txt_Result.AppendText(paraline + "體積" + "\t" + "質量" + "\t" + "滾動" + newline);
foreach (var shape in ShapeList)
{
IRollable rollable = shape as IRollable;
//Null check
bool isRollNull = (rollable == null);
//Check null
if (!isRollNull)
txt_Result.AppendText(shape.Order + "\t" + shape.ShowAllData() + "\t" + rollable.RollDist() + "\n");
else
txt_Result.AppendText(shape.Order + "\t" + shape.ShowAllData());
}
break;
case "Delete":
txt_Result.AppendText(newline + "==========================" + "資料已更新" + "==========================" + "\n");
txt_Result.AppendText(paraline + newline);
foreach (var shape in ShapeList)
{
txt_Result.AppendText(shape.Order + "\t" + shape.ShowNameAndDensity() + "\n");
}
break;
default:
break;
}
}
private void Sort()
{
switch (cmb_Sort.SelectedIndex)
{
case 0: //"依加入順序"
ShapeList.Sort(SortByOrder);
break;
case 1: //"依形狀類別"
ShapeList.Sort(SortByType);
break;
case 2: //"依材質類別"
ShapeList.Sort(SortByMaterial);
break;
case 3: //"依體積大小"
ShapeList.Sort(SortByVolume);
break;
case 4: //"依質量大小"
ShapeList.Sort(SortByWeight);
break;
case 5: //"依滾動距離"
ShapeList.Sort(SortByRollDist);
break;
default:
return;
}
}
//Sort method
private int SortByOrder(Shape3D shape1,Shape3D shape2)
{
//Order check
bool isShape1Bigger = (shape1.Order > shape2.Order);
bool isSame = (shape1.Order == shape2.Order);
//Check the order
if (isShape1Bigger)
{
return 1;
}
else if (isSame)
{
return 0;
}
else
{
return -1;
}
}
private int SortByType(Shape3D shape1, Shape3D shape2)
{
//Type check
bool isShape1Bigger = (shape1.ShapeType > shape2.ShapeType);
bool isSame = (shape1.ShapeType == shape2.ShapeType);
//Check type
if (isShape1Bigger)
{
return 1;
}
else if (isSame)
{
return 0;
}
else
{
return -1;
}
}
private int SortByMaterial(Shape3D shape1, Shape3D shape2)
{
//Density check
bool isShape1Bigger = (shape1.Density > shape2.Density);
bool isSame = (shape1.Density == shape2.Density);
//Check density
if (isShape1Bigger)
{
return 1;
}
else if (isSame)
{
return 0;
}
else
{
return -1;
}
}
private int SortByVolume(Shape3D shape1, Shape3D shape2)
{
//Volume check
bool isShape1Bigger = (shape1.volume > shape2.volume);
bool isSame = (shape1.volume == shape2.volume);
//Check volume
if (isShape1Bigger)
{
return 1;
}
else if (isSame)
{
return 0;
}
else
{
return -1;
}
}
private int SortByWeight(Shape3D shape1, Shape3D shape2)
{
//Weight check
bool isShape1Bigger = (shape1.Weight() > shape2.Weight());
bool isSame = (shape1.Weight() == shape2.Weight());
//Check weight
if (isShape1Bigger)
{
return 1;
}
else if (isSame)
{
return 0;
}
else
{
return -1;
}
}
private int SortByRollDist(Shape3D shape1, Shape3D shape2)
{
double RollDist1 = 0;
double RollDist2 = 0;
IRollable RollTemp1 = shape1 as IRollable;
IRollable RollTemp2 = shape2 as IRollable;
//Null check
bool isTemp1Null = (RollTemp1 == null);
bool isTemp2Null = (RollTemp2 == null);
//Check null, distance
if (!isTemp1Null)
{
RollDist1 = RollTemp1.RollDist();
}
if (!isTemp2Null)
{
RollDist2 = RollTemp2.RollDist();
}
//Distance check
bool isDist1Bigger = (RollDist1 > RollDist2);
bool isSame = (RollDist1 == RollDist2);
if (isDist1Bigger)
{
return 1;
}
else if (isSame)
{
return 0;
}
else
{
return -1;
}
}
}
}
Shape3D.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OOP_HW08
{
abstract class Shape3D
{
//Field
protected double density;
protected int order;
protected Shape3DTypes.Types shapeType;
//Constructors
public Shape3D()
{
density = 0;
}
public Shape3D(int d)
{
density = Material.mDensity[d];
}
//Property
public int Order
{
get { return order; }
set { order = value; }
}
public int ShapeType
{
get { return (int)shapeType; }
}
public double Density
{
get { return density; }
}
public double volume
{
get { return Volume(); }
}
protected abstract double Volume();
public double Weight()
{
return density * Volume();
}
protected abstract string ShapeName();
public string ShowNameAndDensity()
{
string str = "";
str += ShapeName();
str += "\t";
str += density.ToString("F");
return str;
}
public string ShowAllData()
{
string str = "";
str += ShowNameAndDensity();
str += "\t";
str += Volume().ToString("F");
str += "\t";
str += Weight().ToString("F");
str += "\n";
return str;
}
}
static class Shape3DTypes
{
public enum Types { Unknown = 0, Ball, Cube, Cylinder, Pyramid };
}
static class Material
{
public static double[] mDensity = { 2.7, 7.87, 11.3 };
}
}
IRollable.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OOP_HW08
{
interface IRollable
{
double RollDist();
}
}
Ball.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OOP_HW08
{
class Ball : Shape3D, IRollable
{
private double radius;
private static int amount = 0;
public Ball(int density, double radius)
: base(density)
{
this.radius = radius;
shapeType = Shape3DTypes.Types.Ball;
amount++;
}
~Ball()
{
amount--;
}
public static int Amount
{
get { return amount; }
}
protected override double Volume()
{
return 4.0 / 3 * Math.PI * radius * radius * radius;
}
protected override string ShapeName()
{
string str = "";
str += "Ball";
str += "\t";
str += radius.ToString("F");
str += "\t";
return str;
}
public double RollDist()
{
return radius * radius;
}
}
}
Cube.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OOP_HW08
{
class Cube : Shape3D
{
private double length;
private static int amount = 0;
public Cube(int density, double length)
: base(density)
{
this.length = length;
shapeType = Shape3DTypes.Types.Cube;
amount++;
}
~Cube()
{
amount--;
}
public static int Amount
{
get { return amount; }
}
protected override double Volume()
{
return length * length * length;
}
protected override string ShapeName()
{
string str = "";
str += "Cube";
str += "\t";
str += length.ToString("F");
str += "\t";
return str;
}
}
}
Cylinder.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OOP_HW08
{
class Cylinder : Shape3D, IRollable
{
private double radius, height;
private static int amount = 0;
public Cylinder(int density, double radius, double height)
: base(density)
{
this.radius = radius;
this.height = height;
shapeType = Shape3DTypes.Types.Cylinder;
amount++;
}
~Cylinder()
{
amount--;
}
public static int Amount
{
get { return amount; }
}
protected override double Volume()
{
return radius * radius * Math.PI * height;
}
protected override string ShapeName()
{
string str = "";
str += "Cylinder";
str += "\t";
str += radius.ToString("F");
str += "\t";
str += height.ToString("F");
return str;
}
public double RollDist()
{
return 5 * radius;
}
}
}
Pyramid,cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OOP_HW08
{
class Pyramid : Shape3D
{
private double side, height;
private static int amount = 0;
public Pyramid(int density, double side, double height)
: base(density)
{
this.side = side;
this.height = height;
shapeType = Shape3DTypes.Types.Pyramid;
amount++;
}
~Pyramid()
{
amount--;
}
public static int Amount
{
get { return amount; }
}
protected override double Volume()
{
return 1.0/3 * side * side * height;
}
protected override string ShapeName()
{
string str = "";
str += "Pyramid";
str += "\t";
str += side.ToString("F");
str += "\t";
str += height.ToString("F");
return str;
}
}
}
沒有留言:
張貼留言