#專案:農夫渡河 2017/10/21 廖惠平
##Out Lines - 快速複習 - 讀寫檔案 - 專案:農夫渡河
#快速複習
##快速複習 - 集合型別 - 迴圈 - 流程控制 - 實作練習
#讀寫檔案
##讀寫檔案 - 檔案格式 - 讀檔 - 寫檔
##檔案格式 - 不同格式、不同規則 - 副檔名 - 爽就好
##讀檔 - 回傳string: System.IO.File.ReadAllText(@"檔案路徑和名稱"); - 回傳string[]: System.IO.File.ReadAllLines(@"檔案路徑和名稱"); - 一次一行:使用StreamReader - 使用StreamReader後記得Close - 注意路徑與檔案是否存在

讀檔


//ReadAllText
string text = System.IO.File.ReadAllText(@"C:\Users\Test\Sample.txt");
Console.Write(text);

//ReadAllLines
string[] lines = System.IO.File.ReadAllLines(@"C:\Users\Test\Sample.txt");
foreach (string line in lines)
{
	Console.WriteLine(line);
}
					

讀檔:StreamReader


System.IO.StreamReader file =   
    new System.IO.StreamReader(@"C:\Users\Test\Sample.txt");  
while((line = file.ReadLine()) != null)  
{  
    System.Console.WriteLine (line);
}  

file.Close(); 
					
##寫檔 - System.IO.File.WriteAllLines(@"檔案路徑和名稱", 字串陣列); - System.IO.File.WriteAllText(@"檔案路徑和名稱", 字串); - 一次一行:使用StreamWriter - 注意覆蓋檔案的問題

寫檔


//WriteAllLines
string[] lines = { "First line", "Second line", "Third line"};
System.IO.File.WriteAllLines(@"C:\Users\Test\Sample2.txt", lines);

//WriteAllText
string text = "OwO";
System.IO.File.WriteAllText(@"C:\Users\Test\Sample3.txt", text);
					

寫檔:StreamWriter


string[] lines = {"First line", "Second line", "Third line"};

using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\Test\Sample4.txt"))
{
	foreach (string line in lines)
	{
		file.WriteLine(line);
	}
}

//接在原檔內容下面的寫檔
using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\Test\Sample5.txt", true))
{
	file.WriteLine("OwO");
}
					
#專案:農夫渡河
##農夫渡河 - 角色:農夫、狼、羊、菜 - 目標:農夫要帶著所有動物及菜渡河 - 船一次只能載兩個人,只有農夫會划船 - 農夫不在時,狼會吃羊、羊會吃菜
##農夫渡河 - 顯示目前正在左岸、右岸、船上的角色及船停靠的位置 - 給使用者輸入要帶的角色或開船 - 如果狼吃羊或羊吃菜則遊戲結束(失敗) - 船上沒有農夫無法開船 - 成功將所有人渡到對岸後則遊戲結束(勝利) - 防呆
##程式規劃 - 如何代表角色? - 如何表示左岸、右岸及船上? - 如何判斷遊戲結束? - 如何判斷是否能開船? - 流程?

如何代表角色?

  • 使用數字
  • 使用列舉

public enum Character
{
	Farmer = 1,
	Wolf = 2,
	Sheep = 3,
	Vegetable = 4
}
					

如何表示左岸、右岸及船上?

  • 使用List
  • List有Add、Remove、Count及Contains可以利用

List<Character> leftSide = new List<Character>();
List<Character> rightSide = new List<Character>();
List<Character> onBoat = new List<Character>();
					

如何判斷遊戲結束

  • 檢查農夫、狼、羊和菜的位置
  • 使用if判斷搭配Contains()

//檢查
if(leftSide.Contains(角色) && leftSide.Contains(不能在一起的角色))
{
	//遊戲結束
}
					

如何判斷是否能開船?

  • 檢查農夫是否在船上
  • 檢查船上角色數量

if(!onBoat.Contains(Farmer) || onBoat.Count > 2)
{
	//不可以開船
}
					

流程?


宣告&初始化變數
while(!遊戲結束)
{
	顯示目前狀態
	使用者輸入
	防呆
	移動
	檢查移動結果
	清空畫面
}
顯示遊戲結果
					

宣告&初始化變數


List<Character> leftSide = new List<Character>()
{
	Farmer, Wolf, Sheep, Vegetable
};
List<Character> rightSide = new List<Character>();
List<Character> onBoat = new List<Character>();
bool isGameOver = false;
bool isWin;
bool isBoatLeft = true;

int userInput;
					

顯示目前狀態


Console.Write("河岸左側:");
foreach(var character in leftSide)
{
	Console.Write("{0} ", character);
}
Console.Write("\n河岸右側:");
foreach(var character in rightSide)
{
	Console.Write("{0} ", character);
}
Console.Write("\n船上:");
foreach(var character in onBoat)
{
	Console.Write("{0} ", character);
}

if(isBoatLeft)
{
	Console.WriteLine("船目前停在:左岸");
}
else
{
	Console.WriteLine("船目前停在:右岸");
}
					

使用者輸入


Console.WriteLine("\n請輸入要移動的對象:");
Console.WriteLine("1. Farmer\n2. Wolf\n3. Sheep\n4. Vegetable.\n5. 開船");
int.TryParse(Console.ReadLine(), userInput);
					

防呆


while(userInput<1 || userInput>4)
{
	Console.Write("錯誤,請重新輸入:");
	int.TryParse(Console.ReadLine(), userInput);
}
					

移動


//開船
if(userInput == 5)
{
	//農夫在船上才能開船
	if(onBoat.Contains(Farmer))
	{
		isBoatLeft = !isBoatLeft;
	}
	else
	{
		Console.WriteLine("農夫不在船上,無法開船!");
	}
}
					

移動


//移動角色
else
{
	//角色在船上 => 移下船
	if(onBoat.Contains(userInput))
	{
		onBoat.Remove(userInput);
		if(isBoatLeft)
		{
			leftSide.Add(userInput);
		}
		else
		{
			rightSide.Add(userInput);
		}
	}
	//船和角色都在左邊 => 上船
	else if(isBoatLeft && leftSide.Contains(userInput))
	{
		leftSide.Remove(userInput);
		onBoat.Add(userInput);
	}
	//船和角色都在右邊 => 上船
	else if(!isBoatLeft && rightSide.Contains(userInput))
	{
		rightSide.Remove(userInput);
		onBoat.Add(userInput);
	}
	//船在對面,不能上船
	else
	{
		Console.WriteLine("船在對面,不能上船哦!");
	}
}
					

檢查移動結果


//開船就檢查兩岸
if(userInput == 5)
{
	//狼吃羊
	if(leftSide.Contains(Wolf) && leftSide.Contains(Sheep))
	{
		isGameOver = true;
		isWin = false;
		Console.WriteLine("糟糕,同在左岸的狼把羊吃掉了!");
	}
	if(rightSide.Contains(Wolf) && rightSide.Contains(Sheep))
	{
		isGameOver = true;
		isWin = false;
		Console.WriteLine("糟糕,同在右岸的狼把羊吃掉了!");
	}

	//羊吃菜
	if(leftSide.Contains(Sheep) && leftSide.Contains(Vegetable))
	{
		isGameOver = true;
		isWin = false;
		Console.WriteLine("糟糕,同在左岸的羊把菜吃掉了!");
	}
	if(rightSide.Contains(Sheep) && rightSide.Contains(Vegetable))
	{
		isGameOver = true;
		isWin = false;
		Console.WriteLine("糟糕,同在右岸的羊把菜吃掉了!");
	}
}
					

檢查移動結果



//檢查是否全到對岸
if(rightSide.Count == 4)
{
	isGameOver = true;
	isWin = true;
}
					

顯示遊戲結果


if(isWin)
{
	Console.WriteLine("You Win!");
}
else
{
	Console.WriteLine("You Lose!");
}
					
##進階功能 - 減少重複的程式碼 - 儲存遊戲進度 - 紀錄步數 - 步數排行榜 - 還原操作 - 程式尋找最佳解