Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace ConsoleApplication {
- internal class Program {
- private static readonly Stack<Point> OccupyHistory = new Stack<Point>();
- public static void Main(string[] args) {
- var chessTable = new ChessTable();
- var combinationsCount = GetCombinationsCount(chessTable, 8);
- Console.WriteLine("Combinations count: " + combinationsCount);
- }
- private static int GetCombinationsCount(ChessTable table, int figures) {
- var count = 0;
- for (var i = 0; i < ChessTable.Rows; i++) {
- count += StartPlacingAt(table, new Point(0, i), 1, figures);
- table.Clear();
- }
- return count;
- }
- private static int StartPlacingAt(ChessTable table, Point point, int current, int max) {
- if (current == max)
- return 1;
- FigureOccupyTablePoint(table, point);
- var count = 0;
- for (var j = 0; j < ChessTable.Rows; j++) {
- var cell = table[current, j];
- if (cell.IsOccupied || cell.Attacked > 0)
- continue;
- count += StartPlacingAt(table, new Point(current, j), current + 1, max);
- }
- RollbackOccupyPoint(table);
- return count;
- }
- private static void FigureOccupyTablePoint(ChessTable table, Point point) {
- OccupyHistory.Push(point);
- table[point].IsOccupied = true;
- SetAttacked(table, point, true);
- }
- private static void RollbackOccupyPoint(ChessTable table) {
- var point = OccupyHistory.Pop();
- table[point].IsOccupied = false;
- SetAttacked(table, point, false);
- }
- private static void SetAttacked(ChessTable table, Point point, bool isAttacked) {
- AttackCast(table, point, isAttacked, p => p + Point.Up);
- AttackCast(table, point, isAttacked, p => p + Point.Down);
- AttackCast(table, point, isAttacked, p => p + Point.Right);
- AttackCast(table, point, isAttacked, p => p + Point.Left);
- AttackCast(table, point, isAttacked, p => p + Point.Up + Point.Left);
- AttackCast(table, point, isAttacked, p => p + Point.Down + Point.Left);
- AttackCast(table, point, isAttacked, p => p + Point.Up + Point.Right);
- AttackCast(table, point, isAttacked, p => p + Point.Down + Point.Right);
- }
- private static void AttackCast(ChessTable table, Point start, bool isAttack, Func<Point, Point> move) {
- while (true) {
- start = move(start);
- if (!table.PointInRange(start))
- return;
- table[start].Attacked += isAttack ? 1 : -1;
- }
- }
- public class ChessTable {
- public const int Rows = 8;
- private readonly Cell[,] _table = new Cell[Rows, Rows];
- public ChessTable() {
- Clear();
- }
- public Cell this[int i, int j] => _table[i, j];
- public Cell this[Point point] => _table[point.X, point.Y];
- public bool PointInRange(Point point)
- => point.X > -1 && point.X < Rows && point.Y > -1 && point.Y < Rows;
- public void Clear() {
- for (var i = 0; i < Rows; i++)
- for (var j = 0; j < Rows; j++)
- _table[i, j] = new Cell();
- }
- public class Cell {
- public int Attacked;
- public bool IsOccupied;
- }
- public override string ToString() {
- var builder = new StringBuilder();
- for (var i = 0; i < ChessTable.Rows; i++) {
- for (var j = 0; j < ChessTable.Rows; j++) {
- var cell = _table[i, j];
- if (cell.IsOccupied)
- builder.Append("@");
- else if (cell.Attacked > 0)
- builder.Append("X");
- else
- builder.Append("O");
- }
- builder.Append("\r");
- }
- return builder.ToString();
- }
- }
- public struct Point {
- public static readonly Point Up = new Point(0, 1);
- public static readonly Point Down = new Point(0, -1);
- public static readonly Point Right = new Point(1, 0);
- public static readonly Point Left = new Point(-1, 0);
- public static readonly Point Zero = new Point(0, 0);
- public int X;
- public int Y;
- public Point(int x, int y) {
- X = x;
- Y = y;
- }
- public static Point operator +(Point a, Point b) {
- return new Point(a.X + b.X, a.Y + b.Y);
- }
- public static Point operator -(Point a, Point b) {
- return new Point(a.X - b.X, a.Y - b.Y);
- }
- public override string ToString() => "X: " + X + " Y: " + Y;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement