Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
As part of the same preparation I really enjoyed to program a classic:
Which are the 92 solutions to the 8 queen problem?
First, the usage intentions and conditions of satisfaction:
[TestMethod]
public void validSolutions()
{
List<ChessBoard> boards = ChessBoard.AllQueens();
foreach (ChessBoard b in boards)
{
IList all=b.Pieces;
Assert.IsTrue(all.Count == 8);
for (int k = 0; k < 8; k++)
{
IList l = b.Rank[k];
Assert.IsTrue(l.Count == 1);
}
foreach (char c in "abcdefgh")
{
IList l = b.File[c];
Assert.IsTrue(l.Count == 1);
}
}
}
[TestMethod]
public void allSolutions()
{
List<ChessBoard> boards = ChessBoard.AllQueens();
Assert.AreEqual(92, boards.Count);
}
The AllQueens method:
public static List<ChessBoard> AllQueens()
{
ResultKeeper keeper = new ResultKeeper();
ChessBoard board = new ChessBoard();
board.OnNewSolution += new ChessBoard.OnNewSolutionHandler(keeper.OnNewSolution);
board.GetQueens();
return keeper.Results;
}
And the ancillary ResultKeeper class:
class ResultKeeper
{
List<ChessBoard> results;
public ResultKeeper()
{
results = new List<ChessBoard>();
}
public void OnNewSolution(int count, ChessBoard board)
{
results.Add(board);
}
public List<ChessBoard> Results
{
get
{
return results;
}
}
}
And finally, the ChessBoard class:
public class ChessBoard
{
private char[,] board;
private int hit_count;
public ChessBoard()
{
board = new char[8, 8];
reset();
}
private ChessBoard(char[,] b)
{
board = b;
}
public delegate void OnNewSolutionHandler(int count,ChessBoard board);
public event OnNewSolutionHandler OnNewSolution;
public IList Pieces
{
get
{
ArrayList result = new ArrayList();
for (int k = 0; k < 8; ++k)
for(int j=0;j<8;++j)
if (board[k,j] == 'X')
result.Add(board[k,j]);
return result;
}
}
public FileLine File { get { return new FileLine(board); } }
public RankLine Rank { get { return new RankLine(board); } }
public char[,] InternalState
{
get { return board; }
}
public static List<ChessBoard> AllQueens()
{
ResultKeeper keeper = new ResultKeeper();
ChessBoard b = new ChessBoard();
b.OnNewSolution += new ChessBoard.OnNewSolutionHandler(keeper.OnNewSolution);
b.GetQueens();
return keeper.Results;
}
public void GetQueens()
{
find_safe_positions();
}
void reset()
{
for (int k = 0; k < 8; ++k)
for (int j = 0; j < 8; ++j)
board[k, j] = '-';
}
private void find_safe_positions()
{
int rank = 0;
find_safe_position(rank);
}
private bool find_safe_position(int rank)
{
for (int file = 0; file < 8; ++file)
{
if (is_safe(rank, file))
{
board[rank, file] = 'X';
if (rank == 7)
{
NewSolutionFound();
board[rank, file] = '-';
continue;
}
if (find_safe_position(rank + 1))
return true;
else
board[rank, file] = '-';
}
}
return false;
}
bool is_safe(int rank, int file)
{
bool safe = empty_rank(rank) && empty_file(file) && empty_cross(rank, file);
return safe;
}
bool empty_rank(int rank)
{
for (int k = 0; k < 8; ++k)
if (board[rank, k] == 'X')
return false;
return true;
}
bool empty_file(int file)
{
for (int k = 0; k < 8; ++k)
if (board[k, file] == 'X')
return false;
return true;
}
bool empty_cross(int rank, int file)
{
for (int k = rank, j = file; k >= 0 && j >= 0; --k, --j)
if (board[k, j] == 'X')
return false;
for (int k = rank, j = file; k < 8 && j < 8; ++k, ++j)
if (board[k, j] == 'X')
return false;
for (int k = rank, j = file; k < 8 && j >= 0; ++k, --j)
if (board[k, j] == 'X')
return false;
for (int k = rank, j = file; k >= 0 && j < 8; --k, ++j)
if (board[k, j] == 'X')
return false;
return true;
}
void NewSolutionFound()
{
ChessBoard b = new ChessBoard(board.Clone() as char[,]);
++hit_count;
if (OnNewSolution != null)
OnNewSolution(hit_count, b);
}
public class FileLine
{
private char[,] board;
internal FileLine(char[,] b) { board = b; }
public IList this[char c]
{
get
{
ArrayList result = new ArrayList();
int j = (int)c - 97;
for (int k = 0; k < 8; ++k)
if (board[k, j] == 'X')
result.Add(board[k, j]);
return result;
}
}
}
public class RankLine
{
private char[,] board;
internal RankLine(char[,] b) { board = b; }
public IList this[int n]
{
get
{
ArrayList result = new ArrayList();
for (int k = 0; k < 8; ++k)
if (board[n, k] == 'X')
result.Add(board[n, k]);
return result;
}
}
}
}
Comments
- Anonymous
June 19, 2009
PingBack from http://debtsolutionsnow.info/story.php?id=12323