2014年6月16日月曜日

開発環境

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

コメントを投稿