Jump to content

N Adet Vezir Satranç Tahtasına Nasıl Yerleştirilir


wmismail

Recommended Posts

Biliyorum çok klasik bir soru bu... Seneler önce, üniversitedeyken 8 vezirin bir satranç tahtasına kaç farklı şekilde yerleştirilebileceğini bulan bir program yazmamış istenmişti bizden. Ben de o dönemler http://en.wikipedia.org/wiki/Pascal_%28programming_language%29 diline hakimdim tamamen ve diğer dilleri yeni yeni öğrenmeye başlamıştım. Sanırım çok acil olarak ta yetiştirilmesi gereken bir ödevimizdi bu. Ben de internettten arayıp hazı yapılmış bir tane varsa onu alıp, kodlarında bir takım değişiklikler yaptıktan sonra vermeyi düşünmüştüm.

Internette Pascal ile yazılmış satranç programları aramaya başladım böylece; ve şu an kimin yazdığını hatırlamıyorum ama gayet güzel bir program buldum. Program yalnızca 8 vezirle yetinmiyor dışarıdan parametre olarak girilen bir N sayısı için NxN lik bir satranç tahtası üzerinde N adet vezirin birbirlerini görmeden kaç farklı şekilde yerleşrilebileceğini buluyordu. İstediğimi bulmuştum sonunda hatta daha da fazlasını!

Önce programı 8x8 lik bir satranç tahtası üzerinde 8 adet vezirin kaç farklı şekillde yerleştirilebileceğini bulabilecek duruma getirdim yani sınırlandırdım programı. Sonra değişken isimleri üzerinde bir takım değişiklikler yaparak ödevimi teslim ettim :dribble: Güldüğüme bakmayın yanlış hatırlamıyorsam kalmıştım o dersten <_<

C# dilini öğrendikten sonra bu programı C# ile yeniden yazmaya karar verdim ve aşağıdaki programı yazdım:

nqueen.jpg

Ekran görüntüsünden de anlaşılacağı üzere program verilen bir N sayısı için, kullanıcıya NxN' lik satranç tahtası üzerinde N adet vezirin kaç faklı şekilde yerleşebileceğini görsel olarak gösteriyor ve bulunan toplam çözüm sayısını buluyor.

Programımızdaki temel sınıfımız aşağıda görülmektedir.

public class BaseClass

{

private int nSolution;

private int nBoardSize;

int[,] ChessBoard;

private SolutionList Solutions = new SolutionList();

public event SolutionFoundEventHandler OnSolutionFound;

public event SolutionProgressEventHandler OnSearhingSolutions;

public int SolutionCount

{

set

{

nSolution = value;

}

get

{

return nSolution;

}

}

public int BoardSize

{

set

{

nBoardSize = value;

}

get

{

return nBoardSize;

}

}

public void FindSolutions()

{

this.SolutionCount = 0;

this.ChessBoard = new int[this.nBoardSize + 1, this.nBoardSize + 1];

Place(0, 0);

this.SolutionFound(this, new SolutionFoundEventArgs(this));

}

private void AddToSolutions(int solutionNumber, int row, int col)

{

Solution sol = new Solution(solutionNumber, row, col);

this.Solutions.Add(solutionNumber, sol);

}

public SolutionCollection GetSolutions(int index)

{

return Solutions[index];

}

private void Initialize(int col)

{

for (int i = 0; i < this.nBoardSize; i++)

{

for (int j = col; j < this.nBoardSize; j++)

{

this.ChessBoard[i, j] = 0;

}

}

}

private void Display()

{

int i, j, s;

this.SolutionCount += 1;

s = this.SolutionCount;

for (i = 0; i < this.nBoardSize; i++)

{

for (j = 0; j < this.nBoardSize; j++)

{

if (this.ChessBoard[i, j] == 1)

this.AddToSolutions(s-1, i, j);

}

}

}

private bool CanPlace(int row, int col)

{

int i, j;

bool NoConflict;

NoConflict = true;

for (j = 0; j < col; j++)

{

if (this.ChessBoard[row, j] == 1)

NoConflict = false;

}

i = row - 1;

j = col - 1;

while ((i >= 0) && (j >= 0) && (NoConflict))

{

if (this.ChessBoard[i, j] == 1)

NoConflict = false;

i = i - 1;

j = j - 1;

}

i = row + 1;

j = col - 1;

while ((i < this.nBoardSize) && (j >= 0) && (NoConflict))

{

if (this.ChessBoard[i, j] == 1)

NoConflict = false;

i = i + 1;

j = j - 1;

}

return NoConflict;

}

private void Place(int row, int col)

{

if (col == this.nBoardSize)

Display();

else

{

do

{

Initialize(col);

if (Can_Place(row, col))

{

this.ChessBoard[row, col] = 1;

Place(0, col + 1);

}

row++;

} while ((row < this.nBoardSize));

}

}

protected virtual void SolutionFound(Object obj,

SolutionFoundEventArgs solArgs)

{

if (this.OnSolutionFound != null)

this.OnSolutionFound(obj, solArgs);

}

protected virtual void SearchingSolutions(Object obj,

SolutionSearchProgressEventArgs prgArgs)

{

if (this.OnSearhingSolutions != null)

this.OnSearhingSolutions(obj, prgArgs);

}

}Temel sınıfımızla ilgili detaylara geçmeden önce Solution, SolutionCollection ve SolutionList sınıflarına kısaca değinmemiz gerekiyor. Bu sınıflar hakkında detaylı bilgiyi programın kaynak kodunu inceleyerek görebilirsiniz.

Solution sınfı ICollection arayüzünden türetilmiştir ve verilen bir N sayısına karşılık bulunan bir çözümdeki bir veziri temsil eder. İçerisinde vezirin satranç tahtası üzerindeki koordinatlarını ve kaçıncı çözüme ait olduğunu belirten tanımlamalar yer alır.

SolutionCollection sınfı da ICollection arayüzünden türetilmiştir ve verilen bir N sayısına karşılık bulunan bir çözümde yer alan bütün vezirleri temsil etmektedir. Tanımdan da anlaşılacağı üzere bu kolleksiyon içerisinde Solution türünden nesneleri barındırmaktadır.

SolutionList sınıfı da aynen Solution ve SolutionCollection sınıflarında olduğu gibi ICollection arayüzünden türetilmiştir. Bu sınıf verilen N sayısı için bulunun toplam çözümleri SolutionCollection bazında temsil eder. Başka bir değişle bulunan tüm çözümlerdeki vezirlerin konum bilgileri Solution ve SolutionCollection sınıfları yardımıyla bu kolleksiyon içerisinde saklanmaktadır. Bu sınıf içerisinde SolutionCollection türünden nesneler barındırmaktadır.

Şimdi temel sınıfımızın detaylarına kısaca değinelim:

Temel sınıfımızda iki adet temsilci (delegate) yer almaktadır. Bunlardan ilki SolutionFoundEventHandler, diğeri ise SolutionProgressEventHandler temsilcisidir. SolutionFoundEventHandler temsilcisi verilen bir N sayısı için bütün çözümlerin bulunması olayını temsil etmektedir. SolutionProgressEventHandler temsilcisi ise verilen bir N sayısı için bulunan çözümlerin bulunma aşamalarını gösteren olayları temsil eder.

Temel sınıfımıza ait iki adet Property bulunmaktadır. Bunlar SolutionCount ve BoardSize ' dır. SolutionCount, bir kenarı BoardSize ile belirtilen BoardSizexBoardSize ebatlarında bir satranç tahtası üzerine BoardSize adet vezirin kaç farklı şekilde yerleştirilebileceğini göstermektedir.

Temel sınıfımızın public olan yalnızca iki adet metodu bulunmaktadır. Bunlardan ilki temel sınıfımızın bir örneğine ait çözüm sayısının bulunmasını sağlayan FindSolutions() metodudur. GetSolutions() metodunun geri dönüş değeri SolutionList türündendir ve FindSolutions metodu ile çözümleri bulunmuş temel sınıfımızın bir örneğine ait çözümlerin listesini içermektedir.

Temel sınıfımıza ait en önemli metotlarımız ise CanPlace() ve Place() metotlarıdır. CanPlace metodu verilen satır ve sütun koordinatı için bir vezirin satranç tahtasına yerleşip yerleşemeyeceğini bulur. Bu işlemi yaparken de temel sınıfımıza ait ChessBoard matrisimizi yatay, dikey ve çapraz kontrol ederek izlenen yol üzerinde daha önce Place() metodu ile yerleştirilmiş bir vezirin olup olmadığını kontrol eder.

Temel sınıfımızın şüphesiz en önemli metodu Place() metodudur. Bu metot verilen koordinatlar için veziri recursive olarak satranç tahtasına yerleştir. Satranç tahtası üzerindeki tüm sütün ve satırlar tamamlandığında bir çözüm bulunmul olur ve bulunan çözümler Display() metodu ile bulunan çözümlere eklenir.

Programımınız şimdilik yalnızca vezirler için çalışır durumda ama daha sonraki versiyonlarında tüm satranç taşlarının kullanımına olanak veren bir yapıyla yeniden karşınızda olacak..

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...