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 コメント:
コメントを投稿