-
Notifications
You must be signed in to change notification settings - Fork 119
Лабораториска вежба 2
Game of Life, или уште позната како Life, е автомат на клетки пронајден од Британскиот математичар John Horton Conway во 1970.
За играње на играта не се потребни играчи, односно еволуцијата во следната состојба на играта се одредува од нејзината почетна состоба, без притоа да е потребно било каква интеракција од играчот. Единствена интеракција во играта е да се создаде почетна конфигурација и да се гледа како истата еволуира.
Светот на Game of Life е бесконечен дво-димензионален ортогонален грид од клекти во квадратна форма, при што секоја клетка може да биде во две можни состојби, жива или мртва. Секоја клетка е во интеракција со нејзините осум соседи, кои се распоредени хоризонтално, вертикално или дијагонално соседно. Во секој момент во времето, односно при секоја еволуција на светот се случуваат следните транзиции:
- Секоја жива клетка со помалку од два живи соседи умира од ненаселеност.
- Секоја жива клетка со два или три живи соседи преживеува до следната генерација.
- Секоја жива клетка со повеќе од три живи соседи умира од пренаселеност.
- Секоја мртва клетка со точно три живи соседи оживува преку репродукција.
Иницијалната состојба на светот ја претставува почетната еволуција. Секоја наредна генерација се добива со еволуција на претходната и притоа раѓањето и умирањето на клетките се одвива во ист момент. Правилата на играта се применуваат за постојано еволуриање во нова генерација.
Играта ќе ја имплементираме на целосно објектно-ориентиран начин. За таа цел на почеток ќе ги идентификуваме класите кои треба да ги имплементираме. Вообичаено класите ја претставуваат статичката структура (податоците) во една објектно-ориентирана програма.
- Креирајте нова конзолна апликација
Lab2GameOfLife
. - Од погоре во текстот може да се заклучи дека основна податочна единка во нашата апликација е клетката. Во вашиот проект додајте нова класа и именувајте ја
Cell
. - Секоја клетка може да биде во две состојби (мртва или жива). Додајте својство кое ќе ја репрезентира состојбата на клетката.
public bool IsAlive { get; set; }
- Исто така додадете го следното својство кое ќе означува дали треба да оживее клетката во следната еволуција.
public bool ShouldLive { get; set; }
- Имплементирајте
default
конструктор кој ќе ги инцијализира двете својства наfalse
. - Препокриете (
override
) го методотToString()
така што ако клетката е жива да враќа" X "
, а ако не" _ "
. - Следната класа која треба да се имплментира е класата која ќе ја претставува дво-димензионалната матрица (грид) со клетки. Додајте нова класа и именувајте ја
Grid
. - Во класта додадете својства за бројот на редови и колони за матрицата на гридот.
public int Rows { get; set; }
public int Columns { get; set; }
- Додајте својство дво-димензионално поле (матрица) во која ќе се чуваат клетките.
public Cell[][] Cells { get; set; }
- Имплементирајте конструктор кој ќе прима два аргументи (бројот на редови и бројот на колони) и ќе ја иницијализира матрицата со објекти од класата
Cell
.
public Grid(int rows, int columns)
{
// kod za postavuvanje na svojstvata Rows i Columns
// ... ovde vasiot kod ...
// kod za inicijalizacija na matricata
Cells = new Cell[rows][];
for (int i = 0; i < Rows; i++)
{
Cells[i] = new Cell[Columns];
for (int j = 0; j < Columns; j++)
{
// ovde kod za instanciranje na objekt od klasata Cell
// i postavuvanje na toj objekt na soodvetniot element vo matricata
// ... vasiot kod ovde...
}
}
}
- Имплементирајте го методот
ToggleCell
за оживување/убивање на клетка на позицијаx, y
public void ToggleCell(int x, int y, bool isAlive)
{
// vasiot kod ovde
}
- Во следниот метод
Evolve
ќе ги имплементираме правилата на еволуција во играта.
public void Evolve()
{
/*
Algoritam za implementiranje na pravilata na igrata
1. Za sekoja kletka vo matricata so kletki treba da se izbrojat brojot na
zhivi sosedi vo 8-te nasoki (gore levo, gore sredina, gore desno, levo,
desno, dolu levo, dolu sredina i dolu desno).
2. Spored slednite pravila na igrata za evolucija treba da se implementiraat
slednite uslovi (postavuvanje na svojstvoto ShouldLive):
- sekoja zhiva kletka so pomalku od dva zhivi sosedi umira od osamenost
- sekoja zhiva kletka so dva ili tri zhivi sosedi prezhivuva do slednata
generacija
- sekoja zhiva kletka so povekje od tri sosedi umira od prenaselenost
- sekoja mrtva kletka so tochno tri sosedi ozivuva preku reprodukcija
3. Otkako kje gi evoluirame site kletki, treba da ja promenime nivnata
sostojba (svojstvoto IsAlive) vo zavisnost od toa dali treba da zhivee
(svojstvoto ShouldLive). Treba da se izminat povtorno site kletki i
svojstvoto IsAlive da dobie vrednost na svojstvoto ShouldLive.
*/
}
- Следна класа која треба да се имплементира е класата која ќе ја претставува самата игра. Додајте нова класа и именувајте ја
Game
. Направете ја оваа класа апстрактна.
abstract class Game
{
}
- Во класта додадете својства за гридот на клетките во играта, моменталната генерација и максималниот број на генерации што може да еволуираат клетките.
protected Grid grid;
public int CurrentGeneration { get; set; }
public int MaxGenerations { get; set; }
- Имплементирајте конструктор кој ќе прима аргумент максимален број на генерации и ќе го поставува ова својство, а својството моментна генерација ќе го поставува на 0.
public Game(int maxGenerations)
{
// vasiot kod ovde
}
- Имплементирајте метод
Evolve
кој не прима аргументи и само го повикува соодветниот метод од класатаGrid
и ја зголемува тековната генерација за 1.
public void Evolve()
{
// vasiot kod ovde
}
- Имплементирајте виртуелен метод
virtual
кој ќе ја печати состојбата на играта на конзола.
virtual public void Show()
{
Console.Clear();
// vasiot kod ovde
// prikazot od pechatenjeto treba da e sleden:
// 'Current generation: <CurrentGeneration>'
// ' _ _ _ X _ _ _
// ' _ _ _ X _ _ _
// itn
}
- Додајте две класи
StillLifeGame
иOscilatorGame
кои наследуваат од класатаGame
и го содржат следниот код:
/// <summary>
/// Implementacija na igrata so pochetna sostojba so statichki raspored na zhivi kletki koi ne se menuvaat pri evolucija.
/// </summary>
class StillLifeGame : Game
{
public enum GameType
{
Block,
Beehive,
Loaf,
Boat
}
public GameType Type { get; set; }
public StillLifeGame(GameType gameType, int maxGenerations) : base(maxGenerations)
{
Type = gameType;
if (Type == GameType.Block)
{
grid = new Grid(4, 4);
grid.ToggleCell(1, 1, true);
grid.ToggleCell(1, 2, true);
grid.ToggleCell(2, 1, true);
grid.ToggleCell(2, 2, true);
}
if (Type == GameType.Beehive)
{
grid = new Grid(5, 6);
grid.ToggleCell(1, 2, true);
grid.ToggleCell(1, 3, true);
grid.ToggleCell(2, 1, true);
grid.ToggleCell(2, 4, true);
grid.ToggleCell(3, 2, true);
grid.ToggleCell(3, 3, true);
}
}
override public void Show()
{
Console.Title = String.Format("Still Game of Life: {0}", Type);
base.Show();
}
}
/// <summary>
/// Implementacija na igrata so pochetna sostojba so raspored na zhivi kletki koi osciliraat pri evolucija.
/// </summary>
class OscilatorGame : Game
{
public enum GameType
{
Blinker,
Toad,
Beacon,
Pulsar
}
public GameType Type { get; set; }
public OscilatorGame(GameType gameType, int maxGenerations) : base(maxGenerations)
{
Type = gameType;
if (gameType == GameType.Blinker)
{
grid = new Grid(5, 5);
grid.ToggleCell(2, 1, true);
grid.ToggleCell(2, 2, true);
grid.ToggleCell(2, 3, true);
}
if (gameType == GameType.Toad)
{
grid = new Grid(6, 6);
grid.ToggleCell(2, 1, true);
grid.ToggleCell(3, 1, true);
grid.ToggleCell(4, 2, true);
grid.ToggleCell(1, 3, true);
grid.ToggleCell(2, 4, true);
grid.ToggleCell(3, 4, true);
}
if (gameType == GameType.Beacon)
{
grid = new Grid(6, 6);
grid.ToggleCell(1, 1, true);
grid.ToggleCell(1, 2, true);
grid.ToggleCell(2, 1, true);
grid.ToggleCell(2, 2, true);
grid.ToggleCell(3, 3, true);
grid.ToggleCell(3, 4, true);
grid.ToggleCell(4, 3, true);
grid.ToggleCell(4, 4, true);
}
if (gameType == GameType.Pulsar)
{
grid = new Grid(17, 17);
for (int i = 0; i < 17; i++)
{
for (int j = 0; j < 17; j++)
{
if (i == 2 || i == 7 || i == 9 || i == 14)
{
if (j == 4 || j == 5 || j == 6 || j == 10 || j == 11 || j == 12)
{
grid.ToggleCell(i, j, true);
}
}
if ((i >= 4 && i <= 6) || (i >= 10 && i <= 12))
{
if (j == 2 || j == 7 || j == 9 || j == 14)
{
grid.ToggleCell(i, j, true);
}
}
}
}
}
}
override public void Show()
{
Console.Title = String.Format("Oscilator Game of Life: {0}", Type);
base.Show();
}
}
- Додајте го следниот код во класата
Program
static readonly int MAX_GENERATIONS = 10;
static void Main(string[] args)
{
// Instanciranje na objekt od igrata
Game game = new OscilatorGame(OscilatorGame.GameType.Beacon, MAX_GENERATIONS);
while (game.CurrentGeneration <= game.MaxGenerations)
{
game.Show();
game.Evolve();
Thread.Sleep(1000);
}
Console.WriteLine("Evaluation ended!\nPress any key to exit...");
Console.ReadKey();
}
-
Изврешете ја програмата.
-
Додајте ваша имплементација на класа која наследува од
Game
и имплементирајте некоја почетна генерација и извршете ја програмата со објект од оваа класа.