2015年4月16日 星期四

[2015][Quiz]MidExam - 40173027H


第一題程式有三個部分
Program為程式進入點
WareJug為視窗主程式
Water為類別 設定容量.裝倒水功能

Program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace JugPuzzle
{
    static class Program
    {
        /// 
        /// 應用程式的主要進入點。
        /// 
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new JugPuzzle());
        }
    }
}

WareJug
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace JugPuzzle
{
    public partial class FormJugPuzzle : Form
    {
        Water game = new Water();

        public FormJugPuzzle()
        {
            InitializeComponent();
        }

        private void btnSolve_Click(object sender, EventArgs e)
        {
            game.maxAVolume = int.Parse(txtBoxAMaxVolume.Text);
            game.maxBVolume = int.Parse(txtBoxBMaxVolume.Text);
            game.goalVolume = int.Parse(txtBoxGoalVolume.Text);
            game.message = txtBoxMessage;
            game.Solve();

        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            txtBoxMessage.Clear();
        }
    }
}


Water
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace JugPuzzle
{
    class Water
    {
        public int maxAVolume = 5;
        public int maxBVolume = 3;
        public int goalVolume = 2;
        public int currentAVolume = 0;
        public int currentBVolume = 0;
        public TextBox message;

        public int GCD()
        {
            int copyAVolume = maxAVolume;
            int copyBVolume = maxBVolume;
            int temp = 0;

            while(copyAVolume!=0)
            {
                if (copyAVolume < copyBVolume)
                {
                    temp = copyAVolume;
                    copyAVolume = copyBVolume;
                    copyBVolume = temp;
                }
                copyAVolume -= copyBVolume;
            }
            return copyBVolume;
        }
        
        public bool IsRight()
        {
            if (maxAVolume > 0 && maxBVolume > 0 && goalVolume > 0 && (maxAVolume + maxBVolume >= goalVolume) && (goalVolume % GCD() == 0))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public void Print()
        {
            message.AppendText("(A,B) = (" + currentAVolume + "," + currentBVolume + ")\n");
            message.AppendText("========================================\n");
        }

        public void DiscardAVolume()
        {
            currentAVolume = 0;
            message.AppendText("將A容器的水倒光!\n");
            Print();
        }

        public void FillAVolume()
        {
            currentAVolume = maxAVolume;
            message.AppendText("將A容器裝滿水!\n");
            Print();
        }

        public void FillBVolume()
        {
            currentBVolume = maxBVolume;
            message.AppendText("將B容器裝滿水!\n");
            Print();
        }

        public void PourBIntoA()
        {
            if(currentAVolume + currentBVolume <= maxAVolume)
            {
                currentAVolume = currentAVolume + currentBVolume;
                currentBVolume = 0;
                message.AppendText("將B容器的水倒入A容器!\n");
                Print();
            }
            else
            {
                currentBVolume = (currentAVolume + currentBVolume - maxAVolume);
                currentAVolume = maxAVolume;
                message.AppendText("將B容器的水倒入A容器  直到A容器滿為止!\n");
                Print();
            }
        }

        public void Solve()
        {
            message.AppendText("開始進行分水遊戲!\n");
            message.AppendText("========================================\n");
            if (!IsRight())
            {
                message.AppendText("輸入錯誤或是目標水量無法達成!\n");
                message.AppendText("========================================\n");
                return;
            }
            currentAVolume = 0;
            currentBVolume = 0;
            Print();

            if(maxAVolume == goalVolume)
            {
                FillAVolume();
                message.AppendText("將A容器放在磅秤上  即為所求!\n");
                message.AppendText("========================================\n");
            }
            else if(maxAVolume + maxBVolume == goalVolume)
            {
                FillAVolume();
                FillBVolume();
                message.AppendText("將A.B容器一起放在磅秤上  即為所求!\n");
                message.AppendText("========================================\n");
            }
            else
            {
                while(true)
                {
                    if(currentBVolume == goalVolume)
                    {
                        message.AppendText("將B容器放在磅秤上  即為所求!\n");
                        message.AppendText("========================================\n");
                        break;
                    }
                    else if(currentAVolume + currentBVolume == goalVolume)
                    {
                        message.AppendText("將A.B容器一起放在磅秤上  即為所求!\n");
                        message.AppendText("========================================\n");
                        break;
                    }
                    else
                    {
                        FillBVolume();
                        if(currentBVolume == goalVolume)
                        {
                            message.AppendText("將B容器放在磅秤上  即為所求!\n");
                            message.AppendText("========================================\n");
                            break;
                        }
                        else if(currentAVolume + currentBVolume == goalVolume)
                        {
                            message.AppendText("將A.B容器一起放在磅秤上  即為所求!\n");
                            message.AppendText("========================================\n");
                            break;
                        }
                        else
                        {
                            PourBIntoA();
                            while(currentBVolume != 0)
                            {
                                DiscardAVolume();
                                if(currentBVolume == goalVolume)
                                {
                                    message.AppendText("將B容器放在磅秤上  即為所求!\n");
                                    message.AppendText("========================================\n");
                                    return;
                                }
                                else 
                                {
                                    PourBIntoA();
                                }
                            }
                            if(currentBVolume == goalVolume)
                            {
                                message.AppendText("將B容器放在磅秤上  即為所求!\n");
                                message.AppendText("========================================\n");
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
}





第二題程式有三個部分
Program為程式進入點
Form1為視窗主程式
MyDateTime為類別 設定年.月.日及各種功能

Program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Calendar
{
    static class Program
    {
        /// 
        /// 應用程式的主要進入點。
        /// 
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

Form1
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Calendar
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnFunction_Click(object sender, EventArgs e)
        {
            MyDateTime test = new MyDateTime();
            test.Year = int.Parse(txtBoxYear.Text);
            test.Month = (cmbBoxmonth.SelectedIndex + 1);
            test.Day = (cmbBoxDay.SelectedIndex + 1);
            if(radBtnIsLeap.Checked)
            {
                if (!test.IsValid())
                {
                    txtBoxMessage.Text = "日期輸入錯誤或是不合法!\n";
                }
                else if (test.IsLeap())
                {
                    txtBoxMessage.Text = test.Year.ToString() + "年是閏年!\n";
                }
                else
                {
                    txtBoxMessage.Text = test.Year.ToString() + "年是平年!\n";
                }
            }

            if (radBtnDateCheck.Checked)
            {
                txtBoxMessage.Text = test.Print();
                if (test.IsValid())
                {
                    txtBoxMessage.Text += "是合法的!\n";
                }
                else
                {
                    txtBoxMessage.Text += "是不合法的!\n";
                }
            }

            if (radBtnDateToWeekDay.Checked)
            {
                if (!test.IsValid())
                {
                    txtBoxMessage.Text = "日期輸入錯誤或是不合法!\n";
                }
                else
                {
                    txtBoxMessage.Text = test.Print();
                    switch (test.WeekDay())
                    {
                        case 1:
                            txtBoxMessage.Text += "是星期一!\n";
                            break;
                        case 2:
                            txtBoxMessage.Text += "是星期二!\n";
                            break;
                        case 3:
                            txtBoxMessage.Text += "是星期三!\n";
                            break;
                        case 4:
                            txtBoxMessage.Text += "是星期四!\n";
                            break;
                        case 5:
                            txtBoxMessage.Text += "是星期五!\n";
                            break;
                        case 6:
                            txtBoxMessage.Text += "是星期六!\n";
                            break;
                        default:
                            txtBoxMessage.Text += "是星期日!\n";
                            break;
                    }
                }
            }

            if (radBtnCalendar.Checked)
            {
                txtBoxMessage.Text = "\tSun\tMon\tTue\tWed\tThr\tFri\tSat\r\n";
                test.Day = 1;
                for (int i = 1; i <= (test.WeekDay() + 1); i++)
                {
                    txtBoxMessage.Text += "\t";
                }
                int monthFirstWeekDay = test.WeekDay();
                for (int j = 1; j <= test.DaysOfMonth(); j++)
                {
                    txtBoxMessage.Text += j.ToString() + "\t";
                    monthFirstWeekDay++;
                    if ((monthFirstWeekDay) % 7 == 0)
                    {
                        txtBoxMessage.Text += "\r\n";
                        txtBoxMessage.Text += "\t";
                    }
                }
            }

            else
            {
                txtBoxMessage.Text = "請選擇一種功能!!\n";
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            txtBoxMessage.Clear();
        }
    }
}

MyDateTime
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Calendar
{
    class MyDateTime
    {
        private int _year;
        private int _month;
        private int _day;

        public int Year
        {
            get { return _year; }
            set { _year = value; }
        }
        public int Month
        {
            get { return _month; }
            set { _month = value; }
        }
        public int Day
        {
            get { return _day; }
            set { _day = value; }
        }

        public MyDateTime ()
        {
            _year = 0;
            _month = 0;
            _day = 0;
        }
        public MyDateTime(int year, int month, int day)
        {
            _year = year;
            _month = month;
            _day = day;
        }

        public bool IsLeap()
        {
            if(_year % 400 == 0 || (_year % 4 == 0 && _year % 100 != 0))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public int DaysOfMonth()
        {
            switch (_month)
            {
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    return 31;
                case 4:
                case 6:
                case 9:
                case 11:
                    return 30;
                default:
                    if(IsLeap())
                    {
                        return 29;
                    }
                    else
                    {
                        return 28;
                    }
            }
        }
        public bool IsValid()
        {
            if(_year > 0 && _month > 0 && _day > 0)
            {
                if(_day <= DaysOfMonth())
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
        public int WeekDay()
        {
            int Y = _year;
            if(_month == 1 || _month == 2)
            {
                Y-=1;
            }
            int d = _day;
            int m = ((_month + 9) % 12) + 1;
            int y = Y % 100;
            int c = Y / 100;
            int w = (d + System.Convert.ToInt32(Math.Floor(2.6 * m - 0.2)) + y + y / 4 + c / 4 - 2 * c) % 7;
            if(w < 0)
            {
                w += 7;
            }
            return w;
        }
        public string Print()
        {
            return Year.ToString() + "/" + Month.ToString() + "/" + Day.ToString();
        }
    }

}

5 則留言:

  1. FullAVolume(),FullBVolume()兩個方法內的差異不大,所以改寫成一個方法去處理會更好喔!
    然後方法名稱的第一個字改成Fill應該比較好.
    Gcd()這個方法的名稱建議全部都用大寫,因為GCD(Greatest common divisor)已經是縮寫囉

    回覆刪除
    回覆
    1. 謝謝提醒 會再做修改!

      刪除
    2. 現在水量的輸出部分有使用方法簡化程式
      Full已改成Fill 但是對兩個整合的部分有些問題 雖然同樣是裝滿水
      可是兩個是不同的動作 (在倒水過程中可能擇一 或同時使用) 不知道該如何設計比較好

      (第二題已上傳!)

      刪除
    3. 一個比較簡單的想法,寫一個Fill()作為裝滿水的動作,
      void Fill(int source, int container)
      source: 給水的一方
      container: 接受水的一方
      至於原本FillAVolume裡面的message,你可以選擇把它當作Fill的第三個參數,或者另外處理也可

      刪除