Head First C#
頭とからだで覚えるC#の基本
(オライリージャパン)
Andrew Stellman (著), Jennifer Green (著)
佐藤 嘉一 (監修), 木下 哲也 (翻訳)
開発環境
- Microsoft Windows 8.1 Pro (VMware Fusion 6, OS X Mavericks - Apple) (OS)
- C# (プログラミング言語)
- Microsoft Visual Studio Express 2013 for Windows Desktop (統合開発環境, IDE)
Head First C#―頭とからだで覚えるC#の基本 (Andrew Stellman (著)、Jennifer Green (著)、佐藤 嘉一 (監修)、木下 哲也 (翻訳)、オライリージャパン)の6章(インタフェースと抽象クラス: クラスに約束を守らせる)、エクササイズ(p.268)を解いてみる。
エクササイズ(p.268)
コード
Form1.cs
using System; using System.Threading; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { Location currentLocation; int count; RoomWithDoor livingRoom; RoomWithHidingPlace diningRoom; RoomWithDoor kitchen; RoomWithHidingPlace corridor; Room stairs; RoomWithHidingPlace bedroom1; RoomWithHidingPlace bedroom2; RoomWithHidingPlace bathroom; OutsideWithHidingPlace garden; OutsideWithDoor frontYard; OutsideWithDoor backYard; OutsideWithHidingPlace driveway; Opponent opponent; public Form1() { InitializeComponent(); CreateObjects(); opponent = new Opponent(frontYard); ResetGame(); } private void Form1_Load(object sender, EventArgs e) { } public void CreateObjects() { livingRoom = new RoomWithDoor( "居間", "アンティークカーペット", "居間の隠れ場所", "真ちゅうのノブを持つオーク材のドア"); diningRoom = new RoomWithHidingPlace("ダイニングルーム", "ダイニングルームの隠れ場所", "クリスタルのシャンデリア"); kitchen = new RoomWithDoor("台所", ":ステンレス製の電化製品", "台所の隠れ場所", "網戸"); corridor = new RoomWithHidingPlace("2階の廊下", "犬の写真", "クローゼット"); stairs = new Room("居間と2階の廊下をつなぐ階段", "木の手すり"); bedroom1 = new RoomWithHidingPlace("主寝室", "大きなベッド", "ベッドの下"); bedroom2 = new RoomWithHidingPlace("第2寝室", "小さなベッド", "ベッドの下"); bathroom = new RoomWithHidingPlace("浴室", "洗面台とトイレ", "シャワールーム"); garden = new OutsideWithHidingPlace("庭園", false, "小屋"); frontYard = new OutsideWithDoor("前庭", false, "真ちゅうのノブを持つオーク材のドア"); backYard = new OutsideWithDoor("裏庭", true, "網戸"); driveway = new OutsideWithHidingPlace("ドライブウェイ", true, "車庫"); opponent = new Opponent(frontYard); livingRoom.exits = new Location[] { frontYard, diningRoom }; diningRoom.exits = new Location[] { livingRoom, kitchen }; kitchen.exits = new Location[] { diningRoom, backYard }; stairs.exits = new Location[] { livingRoom, corridor }; corridor.exits = new Location[] { stairs, bedroom1, bedroom2, bathroom }; bedroom1.exits = new Location[] { corridor }; bedroom2.exits = new Location[] { corridor }; bathroom.exits = new Location[] { corridor }; garden.exits = new Location[] { frontYard, backYard }; frontYard.exits = new Location[] { livingRoom, garden, driveway }; backYard.exits = new Location[] { garden, kitchen, driveway }; driveway.exits = new Location[] { frontYard, backYard }; livingRoom.DoorLocation = frontYard; kitchen.DoorLocation = backYard; frontYard.DoorLocation = livingRoom; backYard.DoorLocation = kitchen; } void MoveToANewLocation(Location loc) { ++count; currentLocation = loc; RedrawForm(); } private void goHere_Click(object sender, EventArgs e) { MoveToANewLocation(currentLocation.exits[exits.SelectedIndex]); } public void goThroughTheDoor_Click(object sender, EventArgs e) { IHasExteriorDoor door = currentLocation as IHasExteriorDoor; MoveToANewLocation(door.DoorLocation); } private void button1_Click(object sender, EventArgs e) { ++count; if (opponent.Check(currentLocation)) { MessageBox.Show("私は" + count + "回で見つけられた!"); description.Text = currentLocation.Name + "に隠れてました。"; ResetGame(); } else { RedrawForm(); } } private void button2_Click(object sender, EventArgs e) { button2.Visible = false; for (int i = 0; i < 10; ++i) { opponent.Move(); description.Text = (i + 1) + "..."; Application.DoEvents(); Thread.Sleep(200); } description.Text = "もういいかい?いくよ"; Application.DoEvents(); Thread.Sleep(500); goHere.Visible = true; exits.Visible = true; MoveToANewLocation(livingRoom); } private void ResetGame() { count = 0; opponent = new Opponent(frontYard); goHere.Visible = false; exits.Visible = false; goThroughTheDoor.Visible = false; button1.Visible = false; button2.Visible = true; } private void RedrawForm() { exits.Items.Clear(); for (int i = 0; i < currentLocation.exits.Length; ++i) { exits.Items.Add(currentLocation.exits[i].Name); } exits.SelectedIndex = 0; description.Text = currentLocation.Description; if (currentLocation is IHidingPlace) { IHidingPlace hide = currentLocation as IHidingPlace; button1.Text = hide.HidingPlaceName + "をチェックせよ"; button1.Visible = true; } else { button1.Visible = false; } if (currentLocation is IHasExteriorDoor) { goThroughTheDoor.Visible = true; } else { goThroughTheDoor.Visible = false; } } } public interface IHasExteriorDoor { string DoorDescription { get; } Location DoorLocation { get; set; } } public interface IHidingPlace { string HidingPlaceName { get; } } public abstract class Location { private string name; public Location[] exits; public Location(string name) { this.name = name; } public string Name { get { return name; } } public virtual string Description { get { string description = "あなたは今" + name + "に立っています。次の場所への出口があります。"; for (int i = 0; i < exits.Length; ++i) { description += " " + exits[i].Name; if (i != exits.Length - 1) { description += ", "; } } description += "。"; return description; } } } public class Room : Location { private string decoration; public Room(string name, string decoration) : base(name) { this.decoration = decoration; } public string Decoration { get { return this.decoration; } } public override string Description { get { return base.Description + decoration + "が見えます。"; } } } public class Outside : Location { private bool hot; public Outside(string name, bool hot) : base(name) { this.hot = hot; } public bool Hot { get { return this.hot; } } public override string Description { get { if (hot) { return base.Description + "ここはとても暑い。"; } return base.Description; } } } public class OutsideWithHidingPlace : Outside, IHidingPlace { private string hidingPlaceName; public OutsideWithHidingPlace(string name, bool hot, string hidingPlaceName) : base(name, hot) { this.hidingPlaceName = hidingPlaceName; } public string HidingPlaceName { get { return hidingPlaceName; } } } public class RoomWithHidingPlace : Room, IHidingPlace { private string hidingPlaceName; public RoomWithHidingPlace(string name, string decoration, string hidingPlaceName) : base(name, decoration) { this.hidingPlaceName = hidingPlaceName; } public string HidingPlaceName { get { return hidingPlaceName; } } } public class OutsideWithDoor : Outside, IHasExteriorDoor { private Location doorLocation; private string doorDescription; public OutsideWithDoor(string name, bool hot, string doorDescription) : base(name, hot) { this.doorDescription = doorDescription; } public string DoorDescription { get { return doorDescription; } } public Location DoorLocation { get { return this.doorLocation; } set { this.doorLocation = value; } } } public class RoomWithDoor : RoomWithHidingPlace, IHasExteriorDoor { private Location doorLocation; private string doorDescription; public RoomWithDoor(string name, string decoration, string hidingPlaceName, string doorDescription) : base(name, decoration, hidingPlaceName) { this.doorDescription = doorDescription; } public string DoorDescription { get { return doorDescription; } } public Location DoorLocation { get { return this.doorLocation; } set { this.doorLocation = value; } } } public class Opponent { private Location myLocation; Random random; public Opponent(Location myLocation) { this.myLocation = myLocation; random = new Random(); } public void Move() { if (myLocation is IHasExteriorDoor) { IHasExteriorDoor door = myLocation as IHasExteriorDoor; if (random.Next(2) == 1) { myLocation = door.DoorLocation; } } while (true) { myLocation = myLocation.exits[random.Next(myLocation.exits.Length)]; if (myLocation is IHidingPlace) { break; } } } public bool Check(Location location) { if (myLocation == location) { return true; } return false; } } }
0 コメント:
コメントを投稿