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.Threading.Tasks;
using System.Windows.Forms;
namespace WinJugPuzzle
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
JugPuzzle jug = new JugPuzzle();
jug.Message = txtMessage;
jug.CapacityOfJugA = Convert.ToInt16(txtCapacityOfJugA.Text);
jug.CapacityOfJugB = Convert.ToInt16(txtCapacityOfJugB.Text);
jug.Target = Convert.ToInt16(txtTarget.Text);
jug.Solve();
}
private void btnClear_Click(object sender, EventArgs e)
{
txtMessage.Clear();
}
}
}
JugPuzzle
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinJugPuzzle
{
class JugPuzzle
{
public int CapacityOfJugA;
public int CapacityOfJugB;
public int Target;
public TextBox Message;
public void Solve()
{
if (!isSolvable())
{
Message.AppendText("無解,你被唬了, Boom!\n");
return;
}
int capacityA = 0; //容器A 的水量
int capacityB = 0; //容器B 的水量
Message.AppendText("開始進行分水步驟!\n");
while (true)
{
// 條件: 容器 A 空的
// 動作: 將容器A 裝滿
if (capacityA == 0)
{
capacityA = CapacityOfJugA;
Action(capacityA, capacityB,1);
if (capacityA == Target || (capacityA + capacityB == Target))
break;
}
// 條件: 容器 A 滿的
// 動作: 將容器A的水倒進容器B
else if (capacityA == CapacityOfJugA)
{
// 條件: 容器 A 的水量少於 容器B 可以再裝的容量jugB - capacityB
// 動作: 將容器A的水全部倒進容器B
if (capacityA <= CapacityOfJugB - capacityB)
{
capacityB += capacityA;
capacityA = 0;
Action(capacityA, capacityB,2);
if (capacityB == Target)
break;
}
else
{
// 條件: 容器 A 的水量大於 容器B 可以再裝的容量(jugB - capacityB)
// 動作: 將容器A的水倒 (jugB - capacityB) 進容器B
capacityA -= (CapacityOfJugB - capacityB);
capacityB += (CapacityOfJugB - capacityB);
Action(capacityA, capacityB,3);
if (capacityA == Target)
break;
}
}
// 條件: 容器 B 滿的
// 動作: 將容器B的水倒光
else if (capacityB == CapacityOfJugB)
{
capacityB = 0;
Action(capacityA, capacityB,4);
}
// 條件: 容器 A 有水,但沒有滿
// 動作: 將容器A的水倒進容器B
else if (capacityA > 0 && capacityA < CapacityOfJugA)
{
capacityB += capacityA;
capacityA = 0;
Action(capacityA, capacityB,5);
}
}
ShowSolution(capacityA, capacityB);
}
//將步驟列印到 Textbox
void Action(int capacityA, int capacityB,int moveMethod)
{
Message.AppendText("===============================\n");
switch (moveMethod)
{
case 1:
Message.AppendText("將容器A 裝滿\n");
break;
case 2:
Message.AppendText("將容器A的水全部倒進容器B\n");
break;
case 3:
Message.AppendText("將容器A的水倒進容器B,直到B滿為止\n");
break;
case 4:
Message.AppendText("將容器B的水倒光\n");
break;
case 5:
Message.AppendText("將容器A的水倒進容器B\n");
break;
default:
break;
}
Message.AppendText("(A,B)=(" + capacityA.ToString() + ',' + capacityB.ToString() + ") \n");
}
//Show Solution
void ShowSolution(int capacityA, int capacityB)
{
Message.AppendText("**********************************\n");
Message.AppendText("**********************************\n");
if (capacityA == Target)
{
Message.AppendText("將容器A放在磅秤上,即為所求\n");
}
else if (capacityB == Target)
{
Message.AppendText("將容器B放在磅秤上,即為所求\n");
}
else
{
Message.AppendText("將容器A與B一起放在磅秤上,即為所求\n");
}
Message.AppendText("炸彈解除!\n");
}
// 檢查 Jug puzzle 是否有解
bool isSolvable()
{
if (Target % gcd(CapacityOfJugA, CapacityOfJugB) != 0)
return false;
return true;
}
//求最大公因數
int gcd(int num1, int num2)
{
int temp = num1 % num2;
while (num1 % num2 != 0)
{
temp = num1 % num2;
num1 = num2;
num2 = temp;
}
return num2;
}
}
}
沒有留言:
張貼留言