MazeGame — различия между версиями
Admin (обсуждение | вклад) (→Диаграмма классов) |
Admin (обсуждение | вклад) (→Код) |
||
(не показаны 3 промежуточные версии этого же участника) | |||
Строка 20: | Строка 20: | ||
Наконец, класс MazeGame создает и возвращает лабиринт вызовом функции CreateMaze(). | Наконец, класс MazeGame создает и возвращает лабиринт вызовом функции CreateMaze(). | ||
− | Функция CreateMaze() различается для четырех рассматриваемых далее паттернов: | + | Функция CreateMaze() различается для четырех рассматриваемых далее паттернов: Абстрактная фабрика, Строитель, Фабричный метод, Прототип. |
+ | |||
+ | ===Пример простого лабиринта=== | ||
+ | [[Изображение:Labyrinth2.png]] | ||
===Диаграмма классов=== | ===Диаграмма классов=== | ||
Строка 26: | Строка 29: | ||
===Код=== | ===Код=== | ||
− | + | Данный код является отправной точкой для применения паттернов. | |
<source lang="Csharp"> | <source lang="Csharp"> | ||
using System; | using System; | ||
Строка 37: | Строка 40: | ||
public enum Direction { North, South, East, West }; | public enum Direction { North, South, East, West }; | ||
− | public | + | public abstract class MapSite |
{ | { | ||
− | void Enter(); | + | public abstract void Enter(); |
+ | public object Clone() | ||
+ | { | ||
+ | return this.MemberwiseClone(); | ||
+ | } | ||
} | } | ||
Строка 45: | Строка 52: | ||
{ | { | ||
private MapSite[] sides = new MapSite[4]; | private MapSite[] sides = new MapSite[4]; | ||
− | |||
− | |||
− | |||
public Room(int no) | public Room(int no) | ||
{ | { | ||
RoomNumber = no; | RoomNumber = no; | ||
} | } | ||
− | + | public MapSite GetSide(Direction d) | |
− | |||
{ | { | ||
return sides[(int)d]; | return sides[(int)d]; | ||
} | } | ||
− | + | public void SetSide(Direction d, MapSite m) | |
− | |||
{ | { | ||
sides[(int)d] = m; | sides[(int)d] = m; | ||
} | } | ||
− | + | public override void Enter() | |
− | public void Enter() | ||
{ | { | ||
Console.WriteLine("Room.Enter"); | Console.WriteLine("Room.Enter"); | ||
} | } | ||
− | + | public int RoomNumber {get; set; } | |
− | |||
− | |||
− | |||
− | |||
} | } | ||
public class Wall : MapSite | public class Wall : MapSite | ||
{ | { | ||
− | + | public override void Enter() | |
{ | { | ||
Console.WriteLine("Wall.Enter"); | Console.WriteLine("Wall.Enter"); | ||
} | } | ||
− | + | }; | |
− | |||
− | |||
− | |||
− | |||
− | } | ||
public class Door : MapSite | public class Door : MapSite | ||
{ | { | ||
private Room r1, r2; | private Room r1, r2; | ||
− | + | private bool isOpened = true; | |
− | |||
public Door(Room r1 = null, Room r2 = null) | public Door(Room r1 = null, Room r2 = null) | ||
{ | { | ||
Строка 97: | Строка 88: | ||
this.r2 = r2; | this.r2 = r2; | ||
} | } | ||
− | |||
public void Initialize(Room r1 = null, Room r2 = null) | public void Initialize(Room r1 = null, Room r2 = null) | ||
{ | { | ||
Строка 103: | Строка 93: | ||
this.r2 = r2; | this.r2 = r2; | ||
} | } | ||
− | + | public override void Enter() | |
− | public void Enter() | ||
{ | { | ||
if (isOpened) | if (isOpened) | ||
Строка 110: | Строка 99: | ||
else Console.WriteLine("Door is Closed"); | else Console.WriteLine("Door is Closed"); | ||
} | } | ||
− | + | public Room OtherSideFrom(Room r) | |
− | |||
{ | { | ||
if (r == r1) | if (r == r1) | ||
return r2; | return r2; | ||
else return r1; | else return r1; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
} | } | ||
Строка 127: | Строка 110: | ||
{ | { | ||
private List<Room> rlist = new List<Room>(); | private List<Room> rlist = new List<Room>(); | ||
− | + | public void AddRoom(Room r) | |
− | |||
{ | { | ||
rlist.Add(r); | rlist.Add(r); | ||
} | } | ||
− | + | public Room RoomNo(int n) | |
− | |||
{ | { | ||
if (n > rlist.Count) | if (n > rlist.Count) | ||
Строка 139: | Строка 120: | ||
return rlist[n-1]; | return rlist[n-1]; | ||
} | } | ||
− | } | + | } |
public class MazeGame | public class MazeGame | ||
Строка 145: | Строка 126: | ||
public Maze CreateMaze() | public Maze CreateMaze() | ||
{ | { | ||
− | + | Maze aMaze = new Maze(); | |
− | + | Room r1 = new Room(1); | |
− | + | Room r2 = new Room(2); | |
− | + | Door d = new Door(r1,r2); | |
− | |||
− | |||
− | + | aMaze.AddRoom(r1); | |
− | + | aMaze.AddRoom(r2); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | r1.SetSide(Direction.North, new Wall()); | |
+ | r1.SetSide(Direction.East, d); | ||
+ | r1.SetSide(Direction.South, new Wall()); | ||
+ | r1.SetSide(Direction.West, new Wall()); | ||
+ | r2.SetSide(Direction.North, new Wall()); | ||
+ | r2.SetSide(Direction.East, new Wall()); | ||
+ | r2.SetSide(Direction.South, new Wall()); | ||
+ | r2.SetSide(Direction.West, d); | ||
+ | |||
+ | return aMaze; | ||
} | } | ||
} | } | ||
− | |||
class ProgramBase | class ProgramBase |
Текущая версия на 12:47, 31 августа 2014
Общее описание
MazeGame - программа, строящая лабиринт для компьютерной игры.
Лабиринт - это множество комнат. Любая комната знает о своих соседях. Соседями могут быть другие комнаты, стены и двери.
Классы Room, Door и Wall являются потомками интерфейса MapSite - компонента лабиринта. В нем - только одна операция - Enter() - войти. Кроме того, он реализует интерфейс клонирования, что понадобится нам в одном из примеров.
У каждой комнаты - 4 стороны, задаваемые направлениями
enum Direction { North, South, East, West };
Каждая комната Room имеет номер и ссылки на другие объекты MapSite по всем четыре направлениям.
Каждая стена Wall характеризуется двумя комнатами, находящимися по разные стороны от двери, а также флагом, открыта ли дверь, определяющим. можно ли в нее войти. Входя в дверь, мы входим в соседнюю комнату.
Класс лабиринта Maze может добавлять новые комнаты к внутреннему списку и имеет функцию RoomNo определения комнаты по ее номеру.
Наконец, класс MazeGame создает и возвращает лабиринт вызовом функции CreateMaze().
Функция CreateMaze() различается для четырех рассматриваемых далее паттернов: Абстрактная фабрика, Строитель, Фабричный метод, Прототип.
Пример простого лабиринта
Диаграмма классов
Код
Данный код является отправной точкой для применения паттернов.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MazeCommon
{
public enum Direction { North, South, East, West };
public abstract class MapSite
{
public abstract void Enter();
public object Clone()
{
return this.MemberwiseClone();
}
}
public class Room: MapSite
{
private MapSite[] sides = new MapSite[4];
public Room(int no)
{
RoomNumber = no;
}
public MapSite GetSide(Direction d)
{
return sides[(int)d];
}
public void SetSide(Direction d, MapSite m)
{
sides[(int)d] = m;
}
public override void Enter()
{
Console.WriteLine("Room.Enter");
}
public int RoomNumber {get; set; }
}
public class Wall : MapSite
{
public override void Enter()
{
Console.WriteLine("Wall.Enter");
}
};
public class Door : MapSite
{
private Room r1, r2;
private bool isOpened = true;
public Door(Room r1 = null, Room r2 = null)
{
this.r1 = r1;
this.r2 = r2;
}
public void Initialize(Room r1 = null, Room r2 = null)
{
this.r1 = r1;
this.r2 = r2;
}
public override void Enter()
{
if (isOpened)
Console.WriteLine("Door.Enter");
else Console.WriteLine("Door is Closed");
}
public Room OtherSideFrom(Room r)
{
if (r == r1)
return r2;
else return r1;
}
}
public class Maze
{
private List<Room> rlist = new List<Room>();
public void AddRoom(Room r)
{
rlist.Add(r);
}
public Room RoomNo(int n)
{
if (n > rlist.Count)
return null;
return rlist[n-1];
}
}
public class MazeGame
{
public Maze CreateMaze()
{
Maze aMaze = new Maze();
Room r1 = new Room(1);
Room r2 = new Room(2);
Door d = new Door(r1,r2);
aMaze.AddRoom(r1);
aMaze.AddRoom(r2);
r1.SetSide(Direction.North, new Wall());
r1.SetSide(Direction.East, d);
r1.SetSide(Direction.South, new Wall());
r1.SetSide(Direction.West, new Wall());
r2.SetSide(Direction.North, new Wall());
r2.SetSide(Direction.East, new Wall());
r2.SetSide(Direction.South, new Wall());
r2.SetSide(Direction.West, d);
return aMaze;
}
}
class ProgramBase
{
static void Main(string[] args)
{
Console.WriteLine("Base Program");
var game = new MazeGame();
Maze m = game.CreateMaze();
}
}
}