Редактирование: Информатика: Расстановка шахматных фигур

Перейти к: навигация, поиск

Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.

Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 1: Строка 1:
'''[[Абрамов Игорь]]'''
+
'''[[Белоусова Екатерина]]'''
  
'''Алгоритм''': в зависимости от выбранного режима работы, после ввода пользователем необходимой информации о размере поля а также типе расставляемых фигур, запускается основная рекурсивная функция, которая либо подсчитывает все возможные расстановки для заданного числа фигур и выводит их в файл, либо рассчитывает максимально возможное расставляемое число фигур. В первом режиме это происходит путём установки фигуры в свободную клетку и отметки клеток, которые бьются данной фигурой, затем запускается эта же функция для оставшихся клеток и т.д., пока число поставленных фигур не дойдёт до числа, заданного пользователем. Тогда эта расстановка выводится в файл и счётчик числа расстановок увеличивается на единицу. Во втором режиме как только находится расстановка для данного количества фигур, функция завершает свою работу, увеличивается счётчик количества фигур и функция вызывается уже для большего количества фигур, пока не будет найдено максимально возможное расставляемое на данной доске число фигур.
+
'''Краткое описание алгоритма''': доска представлена в виде динамического массива, заполненного 1 и 0. 1-стоит фигура, 0-пустое место. Программа при помощи рекурсии вызывает функцию, которая ставит фигуру в пустую клетку и проверяет, находится ли эта фигура под ударом других.
  
'''Инструкция''': В меню пользователю предлагается указать размеры доски, тип расставляемых фигур и режим работы программы. После этого, если был выбран режим вывода всех расстановок, необходимо ввести количество расставляемых фигур, после чего программа выведет на экран количество расстановок, а в файле "output.txt" появятся изображения всех расстановок. При выборе второго режима, на экран будет выведено максимальное число фигур заданного типа, которые можно расставить на данной доске.
+
'''Инструкция''': пользователь вводит четный размер доски М*М, затем выбирает, какую фигуру он хочет расставить на этой доске, после чего ему предлагается выбрать количество фигур(в скобках указывается максимальное количество фигур, которые можно расставить на доске М*М).Программа выводит на экран всевозможные расстановки, пронумеровывая каждую, и сохраняет их в файл.
  
Ссылка для скачивания:[http://tm.spbstu.ru/File:Chess_Abramov.rar]
+
Скачать можно  [http://tm.spbstu.ru/Файл:задача_1.zip тут].  
 
 
'''[[Андреева Полина]]'''
 
 
 
'''Краткое описание алгоритма''':если шахматную доску представить в виде одной строчки(вторую поставить следом за первой, третью за второй и тд), то получится двоичное число. Максимальное число которое может получиться если 111...111 перевести в десятичное ,это число М*М. Тогда абсолютно ВСЕ варианты расстановки фигур это двоичные записи чисел от 0 до М*М. В программе есть цикл, который рассматривает каждый вариант для числа от 0 до М*М, переводит его в двоичную форму. Программа рассматривает каждую клетку, где стоит фигура. Если эта фигура бьет других, то цикл прерывается, нам такой вариант не подходит. Если никакая фигура не бьет никакую другую, то идет подсчет количества фигур на доске. Если фигур столько, сколько нужно, то вывод на экран.
 
 
 
'''Инструкция''': На экране показано соответствие каждому номеру типа фигуры. Пользователь выбирает тип фигуры, испольуя номер. Дальше нужно ввести размер доски. Затем на экране появляется два варианта количества фигур на доске: максимальное или введенное пользователем. Пользователь выбирает вариант. Если второй, то затем надо будет ввести количество фигур.
 
[http://tm.spbstu.ru/Файл:ШахматыАП.rar Программа]
 
  
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
<syntaxhighlight lang="cpp" line start="1" enclose="div">  
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
#include <iostream>
 +
#include <stdlib.h>
 +
#include <stdio.h>
 +
#include <string>
 
#include <cstring>
 
#include <cstring>
#include <iostream>
 
#include"math.h"
 
 
#include <fstream>
 
#include <fstream>
 +
#include <locale.h>
 +
#include<iomanip>
 +
#include<math.h>
 +
 
using namespace std;
 
using namespace std;
  
int M, N;  // M-размер доски, N-коичество шахмат.
 
int    sum;//нужно в процессе для подсчета количества шахмат
 
int **ChessBoard= new int* [M];
 
  
void ChessBoards(int k) //создание доски, k-число, которое переводим в двоичную запись, чтобы отобразить на доске расстановку фигур, 1-фигура есть, 0-нет.
+
int n, figureID, figura, maxCount; /// n - размер доски, figureID - номер фигуры, figura - колическтво фигур, maxCount - максимальное возможное количество фигур
 +
int results_count = 0; /// определяем тип и задаем начальное значение results_count(номер результата)
 +
int **mass; /// определяем двумерный массив
 +
 
 +
///создаем массив размером n*n
 +
int** create_mass(int n)
 
{
 
{
     for (int i=0; i<M; i++) //создание массива
+
 
 +
    int **mass = new int* [n];
 +
     for (int a=0; a<n; ++a)
 
     {
 
     {
         ChessBoard[i] = new int[M];
+
         mass[a] = new int [n];
    }
+
        memset((char*)mass[a],0,n*sizeof(int)); ///зануление массива
    for (int x=(M-1); x>=0; x=x-1)//заполнение массива фигурами (переводя k в двоичную форму)
 
    {
 
        for (int y=(M-1); y>=0; y=y-1)
 
        {
 
            ChessBoard[x][y]=(k%2);
 
            k=k/2;
 
        }
 
 
     }
 
     }
 +
 +
        return mass;
 +
 
}
 
}
void print (char filename[] ) ///создание функции вывода массива в файл
+
 
 +
///функция вывода массива
 +
void output_mass ()
 +
{
 +
 
 +
    for (int a=0; a<n; ++a)///заполнение ячеек массива от 0 до n по горизонтали
 
     {
 
     {
        ofstream fout(filename, ios::app);
 
  
         for (int x=0; x<M; ++x)
+
         for(int b=0; b<n; ++b)///заполнение ячеек массива от 0 до n по вертикали
 
         {
 
         {
             for(int y=0; y<M; ++y)
+
             cout << mass[a][b]<<" "; ///вывод массива на экран
            {
+
        }
                fout << ChessBoard[x][y]<<" "; ///вывод массива в файл
 
            }
 
            fout <<'\n';
 
  
         }
+
         cout << '\n';
        fout <<"\n\n";
 
  
        fout.close();
 
 
     }
 
     }
  
 +
    cout << "Result #" << ++results_count <<"\n\n"; /// вывод номера результата
  
 +
}
  
bool CheckHorse(int x, int y)//проверка для коня в клетке с номером x, y
+
void zapis (char Zapis[] ) ///функции записи решений в файл
 
{
 
{
 +
    ofstream fout(Zapis, ios::app);///запись в фаил "Zapis"
  
     if (((x+1)<M) && ((y+2)<M) && (ChessBoard[x+1][y+2]==1))//если в клетке, куда может сходить конь (х+1,у+2) уже есть фигура, то этот вариант не подходит, так как один конь бьет другого.
+
     for (int x=0; x<n; ++x)///заполнение ячеек массива от 0 до n по горизонтали
 
     {
 
     {
         return false;
+
         for(int y=0; y<n; ++y)///заполнение ячеек массива от 0 до n по вертикали
 
+
        {
 +
            fout<< mass[x][y]<<" "; ///вывод решений в файл
 +
        }
 +
        fout<<'\n';
 
     }
 
     }
     else if (((x+1)<M ) && ((y-2)>=0) && (ChessBoard[x+1][y-2]==1))//то же самое и в остальных случаях проверяем бьет ли один конь другого.
+
     fout<<"\n\n";
    {
+
    fout.close();
        return false;
+
}
 +
 
 +
///проверяем наличие фигуры в строке а
 +
bool isEmptyHorisontal(int a)
 +
{
  
     }
+
     for(int i=0; i<n; ++i)///создаем цикл от 0 до n
    else if (((x-1)>=0) && ((y+2)<M) && (ChessBoard[x-1][y+2]==1))
 
 
     {
 
     {
         return false;
+
         if(mass[a][i])///в каждой ячейке массива [a][i]
 +
        {
 +
            return false;///неверно
 +
        }
 
     }
 
     }
     else if (((x-1)>=0) && ((y-2)>=0) && (ChessBoard[x-1][y-2]==1))
+
 
 +
     return true;///в остальных случаях верно
 +
 
 +
}
 +
 
 +
///проверяем наличие фигур в столбце b
 +
bool isEmptyVertical(int b)
 +
{
 +
 
 +
    for(int i=0; i<n; ++i)///создаем цикл от 0 до n
 
     {
 
     {
         return false;
+
         if(mass[i][b])///в каждой ячейке массива [i][b]
 +
        {
 +
            return false;///неверно
 +
        }
 
     }
 
     }
     else if (((x+2)<M) && ((y+1)<M) && (ChessBoard[x+2][y+1]==1))
+
 
 +
     return true;///в остальных случаях верно
 +
 
 +
}
 +
 
 +
///проверяем наличие фигур на диагоналях
 +
bool isEmptyDiagonales(int a, int b)
 +
{
 +
 
 +
    for(int i=1; a-i>=0 && b-i>=0; ++i)///диагональ влево-вверх
 
     {
 
     {
         return false;
+
         if(mass[a-i][b-i])///в каждой ячейке массива [a-i][b-i]
 +
        {
 +
            return false;///неверно
 +
        }
 
     }
 
     }
     else if (((x+2)<M ) && ((y-1)>=0) && (ChessBoard[x+2][y-1]==1))
+
 
 +
     for(int i=1; a+i<n && b+i<n; ++i)///диагональ вправо-вниз
 
     {
 
     {
         return false;
+
         if(mass[a+i][b+i])///в каждой ячейке массива [a+i][b+i]
 +
        {
 +
            return false;///неверно
 +
        }
 
     }
 
     }
     else if (((x-2)>=0 ) && ((y+1)<M) && (ChessBoard[x-2][y+1]==1))
+
 
 +
     for(int i=1; a+i<n && b-i>=0; ++i)///диагональ влево-вниз
 
     {
 
     {
         return false;
+
         if(mass[a+i][b-i])///в каждой ячейке массива [a+i][b-i]
 +
        {
 +
            return false;///неверно
 +
        }
 
     }
 
     }
     else if (((x-2)>=0 ) && ((y-1)>=0) && (ChessBoard[x-2][y-1]==1))
+
 
 +
     for(int i=1; a-i>=0 && b+i<n; ++i)///диагональ вправо-вверх
 
     {
 
     {
         return false;
+
         if(mass[a-i][b+i])///в каждой ячейке массива [a-i][b+i]
    }
+
        {
    else //в итоге, если конь, стоящий в данной клетке никого не бьет, то этот вариант подходит
+
            return false;///неверно
    {
+
        }
        return true;
 
 
     }
 
     }
 +
 +
        return true;///в остальных случаях верно
 +
 
}
 
}
  
int Horse(int k)//k-то число которое нужно будет перевести в двоичную форму, это делается в main'е
+
///проверяем наличие фигур по горизонтали, вертикали и диагоналям
//в этой функции считаем количество фигур, если он равно введенному  или максимальному,то доска подходит и выводится в файл (все это в main'е)
+
bool tryQueen(int a, int b)
 
{
 
{
     for (int x=0; x<M; x++)
+
 
    {
+
     if (!isEmptyHorisontal(a) || !isEmptyVertical(b) || !isEmptyDiagonales(a,b))///если не выполняются эти условия,
        int y;
+
                                                                                //.е. постановка фигуры не удовлетворяет расстановке
        for (y=0; y<M; y++)
+
                                                                                ///по горизонтали, или по вертикали, или по диагонали
        {
+
    return false;///неверно
            if (ChessBoard[x][y]==1)//если в данной клетке стоит конь, то нужно проверить,
+
 
            // бьет оно кого-то или нет...
+
     return true;///в остальных случаях верно
            //если в клетке нет коня, то ее проверять не нужно
+
 
            {
 
                if (CheckHorse(x,y))//...делаем это с помощью этой функции,если конь в данной клетке х;у 
 
                //никого не бьет, то прибавляем 1 к количеству шахмат на доске и считаем дальше 
 
                {
 
                    sum=sum+1;
 
                }
 
                else //а если бьет, то выходим из цикла, на данной этапе выйдем только из внуреннего
 
                {
 
                    sum=0;//количество фигур обнуляем
 
                    break;
 
                }
 
            }
 
        }
 
        if (y<M)//если из внутреннего цикла вышли раньше, значит у досчитался не до конца,
 
        //то есть он меньше своего максимального значения М
 
        {
 
           
 
            break;//тогда выходим и из внешнего цикла
 
        }
 
    }
 
     return sum; //возвращаем количество фигур
 
 
}
 
}
  
bool CheckKing(int x, int y) //все то же самое для проверки короля, стоящего в клетке х,у
+
/// функция поиска результатов решений.
 +
/// row - номер очередной строки в которую нужно поставить очередного ферзя.
 +
/// count - количество фигур, поставленое к данному моменту
 +
void setQueen(int row, int count)
 
{
 
{
  
     if (((x+1)<M) && ((y+1)<M) && (ChessBoard[x+1][y+1])==1)//если в клетке куда может сходить король
+
     for(int column=0; column<n; ++column)///двигаемся по столбцу сверху вниз
    //уже есть фигура, то клетка не подходит и т.д
 
 
     {
 
     {
        return false;
 
  
    }
+
        if(tryQueen(row, column))/// проверка, если поставить ферзя в ячейку [row][column],
    else if (((x+1)<M ) && (ChessBoard[x+1][y]==1))
+
                                ///будет ли он единственным в этих строке, столбце и диагоналях
    {
+
        {
         return false;
+
            mass[row][column]=1;
 +
 
 +
            if(count+1==figura) /// нужное количество фигур поставлено
 +
            {
 +
                output_mass(); /// вызов функции вывода массива на экран
 +
                zapis("Zapis");///записываем в файл
 +
            }
 +
 
 +
            else
 +
            {
 +
                for(int i = row + 1; i<n; i++)/// ставим следующего ферзя в одну из следующих строк
 +
                setQueen(i,count+1);///и повторяем цикл
 +
            }
 +
 
 +
            mass[row][column]=0;
 +
 
 +
         }
  
 
     }
 
     }
    else if (((x+1)<M) && ((y-1)>=0) && (ChessBoard[x+1][y-1]==1))
+
 
    {
 
        return false;
 
    }
 
    else if (((x-1)>=0) && ((y-1)>=0) && (ChessBoard[x-1][y-1]==1))
 
    {
 
        return false;
 
    }
 
    else if (((x-1)>=0) && ((y+1)<M) && (ChessBoard[x-1][y+1]==1))
 
    {
 
        return false;
 
    }
 
    else if (((x-1)>=0) &&  (ChessBoard[x-1][y]==1))
 
    {
 
        return false;
 
    }
 
    else if (((y+1)<M) && (ChessBoard[x][y+1]==1))
 
    {
 
        return false;
 
    }
 
    else if (((y-1)>=0) && (ChessBoard[x][y-1]==1))
 
    {
 
        return false;
 
    }
 
    else
 
    {
 
        return true;
 
    }
 
 
}
 
}
  
int King(int k) //так же как и для коня, проверяем каждую клетку
+
bool tryRook(int a, int b)///проверка на наличие фигур по вертикали и горизонтали
//подходит-прибавляем к количеству фигур sum единичку, нет-обнуляем сумму и выходим из цикла
+
{
 +
 
 +
    if (!isEmptyHorisontal(a) || !isEmptyVertical(b))///если не выполняются эти условия,
 +
                                                    ///т.е. постановка фигуры не удовлетворяет расстановке
 +
                                                    ///по горизонтали, или по вертикали
 +
    return false;///неверно
 +
 
 +
    return true;///в остальных случаях верно
 +
 
 +
}
 +
 
 +
/// функция поиска результатов решений.
 +
/// row - номер очередной строки в которую нужно поставить очередную ладью
 +
/// count - количество фигур, поставленое к данному моменту
 +
void setRook(int row, int count)
 
{
 
{
     for (int x=0; x<M; x++)
+
 
 +
     for(int column=0; column<n; ++column)///двигаемся по столбцу сверху вниз
 
     {
 
     {
        int y;
+
 
         for (y=0; y<M; y++)
+
         if(tryRook(row, column))/// проверка, если поставить ладью в A[row][column], будет ли она единственной в этих строке и столбце
 
         {
 
         {
             if (ChessBoard[x][y]==1)
+
 
 +
             mass[row][column]=1;
 +
 
 +
            if(count+1==figura) /// нужное количество фигур поставлено
 
             {
 
             {
                 if (CheckKing(x,y))
+
                 output_mass(); /// вызов функции вывода массива на экран
                {
+
                 zapis("Zapis");///записываем в файл
                    sum=sum+1;
 
                 }
 
                else
 
                {
 
                    sum=0;
 
                    break;
 
                }
 
 
             }
 
             }
 +
 +
            else
 +
            {
 +
                for(int i = row + 1; i<n; i++)/// ставим следующую ладью в одну из следующих строк
 +
                setRook(i,count+1);///и повторяем цикл
 +
            }
 +
 +
            mass[row][column]=0;
 +
 
         }
 
         }
        if (y<M)
+
 
        {
 
            break;
 
        }
 
 
     }
 
     }
     return sum;
+
 
 +
}
 +
 
 +
bool tryElephant(int a, int b) ///проверка на наличие фигур по диагоналям.
 +
{
 +
 
 +
    if (!isEmptyDiagonales(a,b))///если не выполняется это условие,
 +
                                ///т.е. постановка фигуры не удовлетворяет расстановке по диагоналям
 +
    return false;
 +
 
 +
     return true;
 +
 
 
}
 
}
  
int CheckQueen(int x, int y)///проверка для королевы, принцип тот же, королева стит в клеке x,y
+
/// функция поиска результатов решений.
///1 значит как true в bool (как в коне или короле), 0 - false
+
/// diagonale - номер диагонали в которую нужно поставить очередного слона
{ int returnn=1;//начала true, дальше если будет false, то return примет значение 0, а если все пдходит
+
/// count - количество фигур, поставленое к данному моменту
///то так и стается 1
+
void setElephant(int diagonale, int count)
int m;
+
{
    for (m=1; m<M; m++)
+
 
  { //проверяем для диагоналей
+
     int a, b; /// опорная точка диагонали (крайняя левая)
    ///если по диагонале клетки х,у стоит еще королва, то такой вариант не подходит, выходим из цикла
+
 
     ///разбито на 4 услвия, так как если не разбивать, то клетка в кторой стоит данная королева
+
    if (diagonale < n)///если номер диагонали меньше n
    ///тоже будет считаться и выходить из цикла
+
    {
      if (((x+m)<M)&&((y+m)<M))
+
         a = diagonale;///значению а присвоить значенье номера диагонали
      {
+
         b = 0;///значению b присвоить значение 0
          if (ChessBoard[x+m][y+m]==1)
+
    }
          {returnn=0;
 
          break;
 
          }
 
      }
 
      if (((x-m)>=0)&&((y+m)<M))
 
      {
 
          if (ChessBoard[x-m][y+m]==1)
 
          {returnn=0;
 
          break;}
 
      }
 
      if (((x+m)<M)&&((y-m)>=0))
 
      {
 
          if (ChessBoard[x+m][y-m]==1)
 
         {returnn=0;
 
          break;}
 
      }
 
      if (((x-m)>=0)&&((y-m)>=0))
 
      { if (ChessBoard[x-m][y-m]==1)
 
          {returnn=0;
 
          break;}
 
      }
 
      if (m!=x) ///тут считаем по вертикали и горизонтали, так как длаем в цикле для m, то m меняется
 
         ///и в какой-то момент может стать х, и тогда роверятьбуде клетку в которой стоит ДАННАЯ и выходить
 
        ///это не нужно так что выходим только если m не равен x
 
        {
 
            if (ChessBoard[m][y]==1) //если по горизонтали есть какая-о клетка, где стоит королева, то выходим
 
            {
 
                returnn=0;
 
                break;
 
            }
 
        }
 
        if (m!=y)//то же по вертикали
 
        {
 
          if (ChessBoard[x][m]==1)
 
            {
 
                returnn=0;
 
                break;
 
            }
 
        }
 
  }
 
  return returnn;
 
}
 
  
int Queen(int k)//тут также как и для коня и короля
+
    else///иначе
{
 
for (int x=0; x<M; x++)
 
 
     {
 
     {
         int y;
+
         a = n-1;///значению а присвоить значение n-1
        for (y=0; y<M; y++)
+
         b =(diagonale % n)+1;///значению b присвоить значение целого частного от деления номера диагонали на n прибавив к нему 1
         {
 
            if (ChessBoard[x][y]==1)//если в клетке королева, проверяем подходи ли она нам
 
            {
 
                if (CheckQueen(x,y))
 
                {
 
                    sum=sum+1;
 
                }
 
                else
 
                {
 
                    sum=0;
 
                    break;
 
                }
 
            }
 
        }
 
        if (y<M)
 
        {
 
            break;
 
        }
 
 
     }
 
     }
    return sum;
 
}
 
  
int CheckRook(int x, int y)///ладья, просто берем ту часть из проверки королевы, где проверка по горизонтали и вертикали
+
    /// перебираем все "столбцы" текущей диагонали
{ int returnn=1;
+
    for(int dcolumn=0; a-dcolumn>=0 && b+dcolumn < n; ++dcolumn)
int m;
+
    {
    for (m=0; m<M; m++)
+
 
 +
        /// рассчёт координат клетки по координатам крайней точки диагонали и "столбца" в диагонали
 +
        int x = a-dcolumn;
 +
        int y = b+dcolumn;
  
    {
+
         if(tryElephant(x, y))/// проверка, если поставить слона в A[row][column], будет ли он единственным по диагоналям
         if (m!=x)
 
 
         {
 
         {
             if (ChessBoard[m][y]==1)
+
 
 +
             mass[x][y]=1;
 +
 
 +
            if(count+1==figura) /// нужное количество фигур поставлено
 
             {
 
             {
                 returnn=0;
+
                 output_mass(); /// вызов функции вывода массива на экран
                 break;
+
                 zapis("Zapis");///запись в файл
             }
+
             }
        }
+
 
        if (m!=y)
+
            else
        {
 
          if (ChessBoard[x][m]==1)
 
 
             {
 
             {
                 returnn=0;
+
                 for(int i = diagonale + 1; i<2*n-1; i++)/// ставим следующего слона в одну из следующих диагоналей
                 break;
+
                 setElephant(i,count+1);///и повторяем цикл
 
             }
 
             }
 +
 +
            mass[x][y]=0;
 +
 
         }
 
         }
 +
 
     }
 
     }
  
 +
}
  
      return returnn;
+
/// проверка на наличие фигуры на позиции x,y
 +
bool isFigure(int x, int y)
 +
{
 +
    return 0 <= x && x < n && 0 <= y && y < n && mass[x][y];
 
}
 
}
  
int Rook(int k)//все то же самое, количество фигур на доске
+
///проверка на наличие короля в квадрате 3 на 3
 +
bool tryKing(int a, int b)
 
{
 
{
     for (int x=0; x<M; x++)
+
 
 +
     for(int i = a-1; i <= a+1; i++)///для ячеек находящихся слева и справа от поставленного короля
 
     {
 
     {
        int y;
+
         for(int j = b-1; j <= b+1; j++)///для ячеек находящихся снизу и сверху от поставленного короля
         for (y=0; y<M; y++)
 
 
         {
 
         {
             if (ChessBoard[x][y]==1)
+
             if (isFigure(i,j))///если выполняется это условие
             {
+
             return false;///неверно
                if (CheckRook(x,y)==1)
+
        }
                {
+
    }
                    sum=sum+1;
+
 
 +
    return true;///в остальных случаях верно
  
                }
+
}
                else
+
 
                {
+
///функция поиска результатов решений
                    sum=0;
+
/// count - количество фигур, поставленое к данному моменту
                    break;
+
///x,y - позиция, начиная с которой разрешено ставить фигуры (все предшествующие позиции уже точно определены)
                 }
+
void setKing(int count, int x, int y)
 +
{
 +
 
 +
    if(count==figura)///figura - количество фигур, вводимых пользователями.
 +
    {
 +
        output_mass();/// вызов функции вывода массива на экран
 +
        zapis("Zapis");///записываем в файл
 +
        return;
 +
    }
 +
 
 +
    if (x == n) /// строки закончились
 +
        return;
 +
 
 +
    /// обрабатываем текущую строку
 +
    for (int j=y; j<n; ++j)
 +
    {
 +
 
 +
        if(tryKing(x, j))
 +
        {
 +
            mass[x][j]=1;
 +
            /// смещаем разрешённую позицию на 1 вправо или в начало следующей строки
 +
            int nextX = x, nextY = j+1;
 +
 
 +
            if (nextY == n)///если столбец последний
 +
            {
 +
                nextY = 0;///идем сначала по столбцам
 +
                 nextX++;///к строке прибавляем 1
 
             }
 
             }
 +
 +
            /// ставим следующего короля
 +
            setKing(count+1,nextX,nextY);
 +
            mass[x][j]=0;
 +
 
         }
 
         }
        if (y<M)
+
 
        {
 
            break;
 
        }
 
 
     }
 
     }
  
     return sum;
+
     /// обрабатываем прямоугольник ниже текущей строки
}
+
    for(int i=x+1; i<n; ++i)
 +
    {
  
int CheckElephant(int x, int y)//для слона берем ту часть прроверки королевы, где по диагонали
+
        for (int j=0; j<n; ++j)
{ int returnn=1;
+
         {
  for (int i=1; i<M; i++)
 
  {
 
      if (((x+i)<M)&&((y+i)<M))
 
      {
 
          if (ChessBoard[x+i][y+i]==1)
 
          {returnn=0;
 
          break;
 
          }
 
      }
 
      if (((x-i)>=0)&&((y+i)<M))
 
      {
 
          if (ChessBoard[x-i][y+i]==1)
 
          {returnn=0;
 
          break;}
 
      }
 
      if (((x+i)<M)&&((y-i)>=0))
 
      {if (ChessBoard[x+i][y-i]==1)
 
         {returnn=0;
 
          break;}
 
      }
 
      if (((x-i)>=0)&&((y-i)>=0))
 
      { if (ChessBoard[x-i][y-i]==1)
 
          {returnn=0;
 
          break;}
 
      }
 
  }
 
  return returnn;
 
}
 
  
int Elephant(int k)///считаем кличесво фигур
+
            if(tryKing(i, j))
{
 
for (int x=0; x<M; x++)
 
    {
 
        int y;
 
        for (y=0; y<M; y++)
 
        {
 
            if (ChessBoard[x][y]==1)
 
 
             {
 
             {
                 if (CheckElephant(x,y))
+
                mass[i][j]=1;
 +
                /// смещаем разрешённую позицию на 1 вправо или в начало следующей строки
 +
                int nextX = i, nextY = j+1;
 +
 
 +
                 if (nextY == n)///если столбец последний
 
                 {
 
                 {
                     sum=sum+1;
+
                     nextY = 0;///идем сначала по столбцам
                }
+
                     nextX++;///к строке прибавляем 1
                else
 
                {
 
                    sum=0;
 
                     break;
 
 
                 }
 
                 }
 +
 +
                /// ставим следующего короля
 +
                setKing(count+1,nextX,nextY);
 +
                mass[i][j]=0;
 +
 
             }
 
             }
 +
 
         }
 
         }
        if (y<M)
+
 
        {
 
            break;
 
        }
 
 
     }
 
     }
    return sum;
+
 
 
}
 
}
  
int main ()
+
bool tryHorse(int a, int b) ///проверка на коней по всем направлениям
 
{
 
{
    ofstream MyFile("MyFile", ios::trunc);
 
    MyFile.close(); // очищаем файл, чтоб при новой записи не было из рошлого запуска
 
  
int figure, z;
+
     if (isFigure(a-1,b-2) || isFigure(a-1,b+2) || isFigure(a+1,b-2) || isFigure(a+1,b+2) || isFigure(a-2,b-1) || isFigure(a-2,b+1) || isFigure(a+2,b-1) || isFigure(a+2,b+1))
     cout<<"enter a figure 1-queen, 2-king, 3-rook , 4-horse or 5-elephant ";
+
                                                        ///если выполняются эти условия,
    cin>>figure;///тип фигуры, 1 - королевА, 2-король,3-ладья,4-конь,6-слон
+
                                                        ///т.е. фигара стоит на одной из этих позиций
      cout << "\n enter a size of a board M - even number ";///ввести ЧЕТНЫЙ размер доски М
+
        return false;///неверно
     cin >> M;
+
 
     if ( M%2 != 0)///проверка М на четность, с помощью остатка от деления на 2
+
     return true;///в остальных случаях верно
     {
+
 
         while (M%2 != 0)
+
}
         {
+
 
            cout<<" you need EVEN number, enter one more time ";
+
///функция поиска результатов решений
            cin>>M;
+
/// count - количество фигур, поставленое к данному моменту.
        }
+
void setHorse(int count, int x, int y)
 +
{
 +
 
 +
     if(count==figura)///figura - количество фигур, вводимых пользователями.
 +
     {
 +
         output_mass();/// вызов функции вывода массива на экран
 +
         zapis("Zapis");///записываем в файл
 +
        return;
 
     }
 
     }
  
     cout<<"\n choose  1- max amount or 2 - your amount of figures ";
+
     if (x == n)/// строки закончились
    cin>>z;///z-один из вариантов 1-максимаьное число фигур на доске,2-пользователь сам вводит
+
        return;
  
     switch (figure)///выбираем фигуру
+
     /// обрабатываем текущую строку
 +
    for (int j=y; j<n; ++j)
 
     {
 
     {
    case 1:///королева
+
 
    {
+
         if(tryHorse(x, j))
         if (z==2)///пользоватеь сам вводит количество
 
 
         {
 
         {
             cout<<"\n enter an amount of figures ";
+
 
             cin >> N;///ввести количество
+
             mass[x][j]=1;
             if (N>M)///проверка на то, сможет ли такое количество уместиться на доске в правильном виде
+
             /// смещаем разрешённую позицию на 1 вправо или в начало следующей строки
 +
            int nextX = x, nextY = j+1;
 +
 
 +
             if (nextY == n)///если столбец последний
 
             {
 
             {
                 while (N>M)
+
                 nextY = 0;///идем сначала по столбцам
                {
+
                 nextX++;///к строке прибавляем 1
                    cout<<" too many figures, enter one more time ";
 
                    cin>>N;
 
                }
 
            }
 
            ///вот ниже i- те числа которые нужно перевести в двоичную форму
 
            for (int i=0; i<=pow(2,(M*M)); i++)///каждый i-новый вариант расстановик фигур
 
            {
 
                 sum=0;
 
                int k=i;
 
                ChessBoards(k);
 
                if (Queen(k)==N)///если в данной варианте фигур столько. сколько ввел пользователь, то выводим
 
                {
 
                    print("MyFile");
 
                }
 
            }
 
        }
 
        else ///вариант максимального числа фигур на доске
 
        {  ///так же как и в предыдущем пункте, только количество фигур N максимально,
 
            /// в случае королевы оно равно размеру доски 
 
            N=M;
 
            for (int i=0; i<=pow(2,(M*M)); i++)
 
            {
 
                sum=0;
 
                int k=i;
 
                ChessBoards(k);
 
                if (Queen(k)==N)
 
                {
 
                    print("MyFile");
 
                }
 
 
             }
 
             }
 +
 +
            /// ставим следующего коня
 +
            setHorse(count+1,nextX,nextY);
 +
            mass[x][j]=0;
 +
 
         }
 
         }
  
        break;
 
 
     }
 
     }
     case 2:///то же самое для короля
+
 
 +
     /// обрабатываем прямоугольник ниже текущей строки
 +
    for(int i=x+1; i<n; ++i)
 
     {
 
     {
         if (z==2)
+
 
 +
         for (int j=0; j<n; ++j)
 
         {
 
         {
            cout<<"\n enter an amount of figures ";
+
 
             cin >> N;
+
             if(tryHorse(i, j))
              if ( N>(M*M)/4)
 
 
             {
 
             {
                while (N>(M*M)/4)
+
 
                {
+
                 mass[i][j]=1;
                    cout<<" too many figures, enter one more time ";
+
                 /// смещаем разрешённую позицию на 1 вправо или в начало следующей строки
                    cin>>N;
+
                 int nextX = i, nextY = j+1;
                 }
+
 
            }
+
                 if (nextY == n)///если столбец последний
            for (int i=0; i<=pow(2,(M*M)); i++)
 
            {
 
                 sum=0;
 
                 int k=i;
 
                ChessBoards(k);
 
                 if (King(k)==N)
 
 
                 {
 
                 {
                     print("MyFile");
+
                     nextY = 0;///идем сначала по столбцам
 +
                    nextX++;///к строке прибавляем 1
 
                 }
 
                 }
 +
 +
                setHorse(count+1,nextX,nextY);
 +
                mass[i][j]=0;
 +
 
             }
 
             }
 +
 
         }
 
         }
else
+
 
        {
 
            N=(M*M)/4;
 
            for (int i=0; i<=pow(2,(M*M)); i++)
 
            {
 
                sum=0;
 
                int k=i;
 
                ChessBoards(k);
 
                if (King(k)==N)
 
                {
 
                    print("MyFile");
 
                }
 
            }
 
        }
 
        break;
 
 
     }
 
     }
    case 3:///для ладьи
 
    {
 
        if (z==2)
 
        {
 
            cout<<"\n enter an amount of figures ";
 
            cin >> N;
 
              if (N>M)
 
            {
 
                while (N>M)
 
                {
 
                    cout<<" too many figures, enter one more time ";
 
                    cin>>N;
 
                }
 
            }
 
  
            for (int i=0; i<=pow(2,(M*M)); i++)
+
}
            {
+
 
                sum=0;
+
int main()
                int k=i;
+
{
                ChessBoards(k);
+
    setlocale(LC_ALL,"RUS");
                if (Rook(k)==N)
+
 
                {
+
  ofstream Zapis("Zapis", ios::trunc);///сохраняем в файл
                    print("MyFile");
+
  Zapis.close();
                }
+
 
            }
+
     do
        }
 
        else
 
        {
 
            N=M;
 
            for (int i=0; i<=pow(2,(M*M)); i++)
 
            {
 
                sum=0;
 
                int k=i;
 
                ChessBoards(k);
 
                if (Rook(k)==N)
 
                {
 
                    print("MyFile");
 
                }
 
            }
 
        }
 
        break;
 
    }
 
     case 4:///конь
 
 
     {
 
     {
         if (z==2)
+
         cout << "Введите размер доски (четный): ";
        {
+
        cin >> n; ///ввод пользователем размера доски
            cout<<"\n enter an amount of figures ";
+
    }while (n%2 != 0);
            cin >> N;
+
 
              if (N>(M*M)/2)
+
    mass=create_mass(n); ///создаём двумерный массив
            {
+
 
                while (N>(M*M)/2)
+
    cout<<"Queen-1, Rook-2, Elephant-3, King-4, Horse-5"<< endl;
                {
+
    cin >> figureID; ///выбор пользователем фигуры
                    cout<<" too many figures, enter one more time ";
+
 
                    cin>>N;
+
    /// устанавливаем максимальное количество в зависимости от фигуры
                }
+
    if (figureID==1)
            }
+
    maxCount=n;
 +
    if (figureID==2)
 +
    maxCount=n;
 +
    if (figureID==3)
 +
    maxCount=2*n-2;
 +
    if (figureID==4)
 +
    maxCount=(n*n)/4;
 +
    if (figureID==5)
 +
    maxCount=(n*n)/2;
  
            for (int i=0; i<=pow(2,(M*M)); i++)
+
    /// запрашиваем количество фигур
            {
+
    do
                sum=0;
+
    {
                int k=i;
+
        cout << "Введите количество фигур (максимальное количество - " << maxCount << "): ";
                ChessBoards(k);
+
        cin >> figura;
                if (Horse(k)==N)
+
    }while (figura>maxCount);
                {
+
 
                    print("MyFile");
+
    /// запускаем перебор
                }
+
    if (figureID==1)
            }
+
    {
        }
+
         for(int i = 0; i<n; i++)
        else
+
        setQueen(i,0);
         {
+
        zapis("Zapis");
            N=(M*M)/2;
+
    }
            for (int i=0; i<=pow(2,(M*M)); i++)
+
    if (figureID==2)
            {
+
    {
                sum=0;
+
        for(int i = 0; i<n; i++)
                int k=i;
+
         setRook(i,0);
                ChessBoards(k);
+
         zapis("Zapis");
                if (Horse(k)==N)
 
                {
 
                    print("MyFile");
 
                }
 
            }
 
         }
 
         break;
 
 
     }
 
     }
     case 5:///слон
+
     if (figureID==3)
 
     {
 
     {
         if (z==2)
+
         for(int i = 0; i<2*n-1; i++)
        {
+
        setElephant(i,0);
            cout<<"\n enter an amount of figures ";
+
        zapis("Zapis");
            cin >> N;
+
    }
                if (N>2*M-2)
+
    if (figureID==4)
            {
+
    {
                while (N>2*M-2)
+
        setKing(0,0,0);
                {
+
        zapis("Zapis");
                    cout<<" too many figures, enter one more time ";
 
                    cin>>N;
 
                }
 
            }
 
            for (int i=0; i<=pow(2,(M*M)); i++)
 
            {
 
                sum=0;
 
                int k=i;
 
                ChessBoards(k);
 
                if (Elephant(k)==N)
 
                {
 
                    print("MyFile");
 
                }
 
            }
 
        }
 
        else
 
        {
 
            N=2*M-2;
 
            for (int i=0; i<=pow(2,(M*M)); i++)
 
            {
 
                sum=0;
 
                int k=i;
 
                ChessBoards(k);
 
                if (Elephant(k)==N)
 
                {
 
                    print("MyFile");
 
                }
 
            }
 
        }
 
        break;
 
 
     }
 
     }
     default : ///а это еси пользоватеь ввел цифру, которая не соответстует ни одной фигуре
+
     if (figureID==5)
 
     {
 
     {
         cout<<"NOOOOO";
+
         setHorse(0,0,0);
         break;
+
         zapis("Zapis");
    }
 
    };
 
 
 
 
 
    return 0;
 
 
     }
 
     }
 +
    system("PAUSE");
 +
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
</div>
 
</div>
  
'''[[Бальцер Анастасия]]'''
 
  
'''Краткое описание алгоритма''': Для каждой фигуры написана отдельная функция, выполняющая поиск расстановок. После выбора типа фигуры, соответствующая функция выполняет поиск возможных расстановок. Она проходя по строкам двумерного массива пытается поставить фигуру в каждую клетку. Проходя по массиву она маркирует клетки, ставит 0 (если клетка свободна), 1 (если клетка находится под ударом), 2 (если клетка занята). Программа аналитически считает максимальное количество фигур для заданного размера доски, возможное число расстановок для заданных типа фигуры, размера доски и количества фигур.
+
'''[[Лебедев Станислав]]'''
  
'''Инструкция''': При запуске программы появляется меню, в котором каждому типу фигуры сопоставлен номер, с помощью которого пользователь и выбирает тип фигуры. Затем пользователю на выбор предлагается 2 режима работы программы: первый выводит число возможных расстановок на экран, а список возможных расстановок в отдельный файл (при этом пользователь дополнительно выбирает число фигур); второй выводит на экран максимальное число фигур выбранного типа, которые можно расставить на заданной доске.
+
'''Функционал программы''': получение всевозможных расстановок n однотипных шахматных фигур первой линии на поле n на n,таких,чтобы фигуры не били друг друга(считается,что фигуры одного цвета также могут бить друг друга) или получения максимального количества фигур первой линии,которые могут стоять на доске n*n;
  
Посмотреть программу можно [http://tm.spbstu.ru/Файл:Расстановка.zip тут]
+
'''Идея алгоритма''': рекурсивно вызывается функция,которая ставит фигуру в пустую и небитую клетку, а также отмечает клетки,которые эта фигура бьет. Рекурсия продолжается до тех пор,пока либо не будет достигнуто нужное количество, либо не будет возможности поставить фигуру. После выхода из рекурсии начинается "обратный ход", в котором отмеченные как битые на этом шаге,"размечаются"(снимается отметка,что эта клетка бьется),а место,занятое самой фигурой, запоминается.
  
'''[[Белоусова Екатерина]]'''
+
Скачать можно  [http://tm.spbstu.ru/Файл:Шахматы.rar тут].  
 
 
'''Краткое описание алгоритма''': доска представлена в виде динамического массива, заполненного 1 и 0. 1-стоит фигура, 0-пустое место. Программа при помощи рекурсии вызывает функцию, которая ставит фигуру в пустую клетку и проверяет, находится ли эта фигура под ударом других.
 
 
 
'''Инструкция''': пользователь вводит четный размер доски М*М, затем выбирает, какую фигуру он хочет расставить на этой доске, после чего ему предлагается выбрать количество фигур(в скобках указывается максимальное количество фигур, которые можно расставить на доске М*М).Программа выводит на экран всевозможные расстановки, пронумеровывая каждую, и сохраняет их в файл.
 
 
 
Скачать можно  [http://tm.spbstu.ru/Файл:задача_1.zip тут].  
 
  
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
#include <iostream>
 
#include <iostream>
#include <stdlib.h>
+
#include <math.h>
#include <stdio.h>
+
#include <cmath>
#include <string>
 
#include <cstring>
 
#include <fstream>
 
#include <locale.h>
 
#include<iomanip>
 
#include<math.h>
 
  
 
using namespace std;
 
using namespace std;
  
 +
int n,type, *a, *stak, variant, maxst = 0;
  
int n, figureID, figura, maxCount; /// n - размер доски, figureID - номер фигуры, figura - колическтво фигур, maxCount - максимальное возможное количество фигур
+
void king(int x, int &top)                     //отметить битые клетки королем
int results_count = 0; /// определяем тип и задаем начальное значение results_count(номер результата)
 
int **mass; /// определяем двумерный массив
 
 
 
///создаем массив размером n*n
 
int** create_mass(int n)
 
 
{
 
{
 +
    // 012
 +
    // 345
 +
    // 678
  
     int **mass = new int* [n];
+
     //0
     for (int a=0; a<n; ++a)
+
     if (((x % n) > 1) && ((x / n) > 1))
 
     {
 
     {
         mass[a] = new int [n];
+
         int ii = x - n - 1;
        memset((char*)mass[a],0,n*sizeof(int)); ///зануление массива
+
        if (a[ii] != -2)
 +
        {
 +
            a[ii]++;
 +
            stak[top] = ii;
 +
            top++;
 +
        }
 
     }
 
     }
  
        return mass;
+
    //1
 
+
    if ((x / n) > 0)
}
 
 
 
///функция вывода массива
 
void output_mass ()
 
{
 
 
 
    for (int a=0; a<n; ++a)///заполнение ячеек массива от 0 до n по горизонтали
 
 
     {
 
     {
 
+
         int ii = x - n;
         for(int b=0; b<n; ++b)///заполнение ячеек массива от 0 до n по вертикали
+
        if (a[ii] != -2)
 
         {
 
         {
             cout << mass[a][b]<<" "; ///вывод массива на экран
+
             a[ii]++;
 +
            stak[top] = ii;
 +
            top++;
 
         }
 
         }
 
        cout << '\n';
 
 
 
     }
 
     }
  
     cout << "Result #" << ++results_count <<"\n\n"; /// вывод номера результата
+
     //2
 
+
    if (((x % n) < (n - 1)) && ((x / n) > 0))
}
 
 
 
void zapis (char Zapis[] ) ///функции записи решений в файл
 
{
 
    ofstream fout(Zapis, ios::app);///запись в фаил "Zapis"
 
 
 
    for (int x=0; x<n; ++x)///заполнение ячеек массива от 0 до n по горизонтали
 
 
     {
 
     {
         for(int y=0; y<n; ++y)///заполнение ячеек массива от 0 до n по вертикали
+
         int ii = x - n + 1;
 +
        if (a[ii] != -2)
 
         {
 
         {
             fout<< mass[x][y]<<" "; ///вывод решений в файл
+
             a[ii]++;
 +
            stak[top] = ii;
 +
            top++;
 
         }
 
         }
        fout<<'\n';
 
 
     }
 
     }
    fout<<"\n\n";
 
    fout.close();
 
}
 
  
///проверяем наличие фигуры в строке а
+
    //3
bool isEmptyHorisontal(int a)
+
    if ((x % n) > 0)
{
 
 
 
    for(int i=0; i<n; ++i)///создаем цикл от 0 до n
 
 
     {
 
     {
         if(mass[a][i])///в каждой ячейке массива [a][i]
+
        int ii = x - 1;
 +
         if (a[ii] != -2)
 
         {
 
         {
             return false;///неверно
+
             a[ii]++;
 +
            stak[top] = ii;
 +
            top++;
 
         }
 
         }
 
     }
 
     }
  
     return true;///в остальных случаях верно
+
     //5
 
+
    if ((x % n) < (n - 1))
}
 
 
 
///проверяем наличие фигур в столбце b
 
bool isEmptyVertical(int b)
 
{
 
 
 
    for(int i=0; i<n; ++i)///создаем цикл от 0 до n
 
 
     {
 
     {
         if(mass[i][b])///в каждой ячейке массива [i][b]
+
        int ii = x + 1;
 +
         if (a[ii] != -2)
 
         {
 
         {
             return false;///неверно
+
             a[ii]++;
 +
            stak[top] = ii;
 +
            top++;
 
         }
 
         }
 
     }
 
     }
  
     return true;///в остальных случаях верно
+
     //6
 
+
    if (((x % n ) > 0) && ((x / n) < (n - 1)))
}
 
 
 
///проверяем наличие фигур на диагоналях
 
bool isEmptyDiagonales(int a, int b)
 
{
 
 
 
    for(int i=1; a-i>=0 && b-i>=0; ++i)///диагональ влево-вверх
 
 
     {
 
     {
         if(mass[a-i][b-i])///в каждой ячейке массива [a-i][b-i]
+
        int ii = x + n - 1;
 +
         if (a[ii] != -2)
 
         {
 
         {
             return false;///неверно
+
             a[ii]++;
 +
            stak[top] = ii;
 +
            top++;
 
         }
 
         }
 
     }
 
     }
  
     for(int i=1; a+i<n && b+i<n; ++i)///диагональ вправо-вниз
+
     //7
 +
    if ((x / n ) < (n - 1))
 
     {
 
     {
         if(mass[a+i][b+i])///в каждой ячейке массива [a+i][b+i]
+
        int ii = x + n;
 +
         if (a[ii] != -2)
 
         {
 
         {
             return false;///неверно
+
             a[ii]++;
 +
            stak[top] = ii;
 +
            top++;
 
         }
 
         }
 
     }
 
     }
  
     for(int i=1; a+i<n && b-i>=0; ++i)///диагональ влево-вниз
+
     //8
 +
    if (((x % n ) < (n - 1)) && ((x / n) < (n - 1)))
 
     {
 
     {
         if(mass[a+i][b-i])///в каждой ячейке массива [a+i][b-i]
+
         int ii = x + n + 1;
 +
    if (a[ii] != -2)
 
         {
 
         {
             return false;///неверно
+
             a[ii]++;
 +
            stak[top] = ii;
 +
            top++;
 
         }
 
         }
 
     }
 
     }
 +
}
  
     for(int i=1; a-i>=0 && b+i<n; ++i)///диагональ вправо-вверх
+
void bishop(int x, int &top)                                                              //отметить битые клетки слоном
 +
{
 +
    //вверх влево
 +
     for (int i = (x - (n + 1)); ((i >= 0) && ((i%n) != (n-1))); i -= (n+1))
 
     {
 
     {
         if(mass[a-i][b+i])///в каждой ячейке массива [a-i][b+i]
+
         if (a[i] != -2)
 
         {
 
         {
             return false;///неверно
+
             a[i]++;
 +
            stak[top] = i;
 +
            top++;
 
         }
 
         }
 
     }
 
     }
  
         return true;///в остальных случаях верно
+
    //вниз вправо
 +
    for (int i = (x + (n + 1)); ((i < n*n) && ((i%n) != 0)); i += (n+1))
 +
    {
 +
         if (a[i] != -2)
 +
        {
 +
            a[i]++;
 +
            stak[top] = i;
 +
            top++;
 +
        }
 +
    }
  
}
+
    //вверх вправо
 
+
    for (int i = x - (n - 1); ((i >= 0) && ((i%n) != 0)); i -= (n-1))
///проверяем наличие фигур по горизонтали, вертикали и диагоналям
+
    {
bool tryQueen(int a, int b)
+
        if (a[i] != -2)
{
+
        {
 
+
            a[i]++;
    if (!isEmptyHorisontal(a) || !isEmptyVertical(b) || !isEmptyDiagonales(a,b))///если не выполняются эти условия,
+
            stak[top] = i;
                                                                                ///т.е. постановка фигуры не удовлетворяет расстановке
+
            top++;
                                                                                ///по горизонтали, или по вертикали, или по диагонали
+
        }
    return false;///неверно
+
     }
 
 
     return true;///в остальных случаях верно
 
  
 +
    //вниз влево
 +
    for (int i = x + (n - 1); ((i < n*n) && ((i%n) != (n-1))); i += (n-1))
 +
    {
 +
        if (a[i] != -2)
 +
        {
 +
            a[i]++;
 +
            stak[top] = i;
 +
            top++;
 +
        }
 +
    }
 
}
 
}
  
/// функция поиска результатов решений.
+
void knight(int x, int &top)                                           //отметить битые клетки конем
/// row - номер очередной строки в которую нужно поставить очередного ферзя.
 
/// count - количество фигур, поставленое к данному моменту
 
void setQueen(int row, int count)
 
 
{
 
{
 
+
     if (((x%n) > 0) && (x/n) > 1)
     for(int column=0; column<n; ++column)///двигаемся по столбцу сверху вниз
 
 
     {
 
     {
 
+
        int ii = x - 2*n - 1;
         if(tryQueen(row, column))/// проверка, если поставить ферзя в ячейку [row][column],
+
         if (a[ii] != -2)
                                ///будет ли он единственным в этих строке, столбце и диагоналях
 
 
         {
 
         {
             mass[row][column]=1;
+
             a[ii]++;
 +
            stak[top] = ii;
 +
            top++;
 +
        }
 +
    }
  
            if(count+1==figura) /// нужное количество фигур поставлено
+
    if (((x%n) > 1) && (x/n) > 0)
            {
+
    {
                output_mass(); /// вызов функции вывода массива на экран
+
        int ii = x - n - 2;
                zapis("Zapis");///записываем в файл
+
        if (a[ii] != -2)
             }
+
        {
 +
            a[ii]++;
 +
            stak[top] = ii;
 +
             top++;
 +
        }
 +
    }
  
            else
+
    if (((x%n) > 1) && (x/n) < (n - 1))
            {
+
    {
                for(int i = row + 1; i<n; i++)/// ставим следующего ферзя в одну из следующих строк
+
        int ii = x + n - 2;
                setQueen(i,count+1);///и повторяем цикл
+
        if (a[ii] != -2)
            }
+
        {
 
+
             a[ii]++;
             mass[row][column]=0;
+
            stak[top] = ii;
 +
            top++;
 +
        }
 +
    }
  
 +
    if (((x%n) > 0) && (x/n) < (n - 2))
 +
    {
 +
        int ii = x + 2*n - 1;
 +
        if (a[ii] != -2)
 +
        {
 +
            a[ii]++;
 +
            stak[top] = ii;
 +
            top++;
 
         }
 
         }
 
 
     }
 
     }
  
}
+
     if (((x%n) < (n - 1)) && (x/n) < (n - 2))
 
 
bool tryRook(int a, int b)///проверка на наличие фигур по вертикали и горизонтали
 
{
 
 
 
     if (!isEmptyHorisontal(a) || !isEmptyVertical(b))///если не выполняются эти условия,
 
                                                    ///т.е. постановка фигуры не удовлетворяет расстановке
 
                                                    ///по горизонтали, или по вертикали
 
    return false;///неверно
 
 
 
    return true;///в остальных случаях верно
 
 
 
}
 
 
 
/// функция поиска результатов решений.
 
/// row - номер очередной строки в которую нужно поставить очередную ладью
 
/// count - количество фигур, поставленое к данному моменту
 
void setRook(int row, int count)
 
{
 
 
 
    for(int column=0; column<n; ++column)///двигаемся по столбцу сверху вниз
 
 
     {
 
     {
 
+
        int ii = x + 2*n + 1;
         if(tryRook(row, column))/// проверка, если поставить ладью в A[row][column], будет ли она единственной в этих строке и столбце
+
         if (a[ii] != -2)
 
         {
 
         {
 
+
             a[ii]++;
             mass[row][column]=1;
+
             stak[top] = ii;
 
+
             top++;
             if(count+1==figura) /// нужное количество фигур поставлено
 
            {
 
                output_mass(); /// вызов функции вывода массива на экран
 
                zapis("Zapis");///записываем в файл
 
            }
 
 
 
            else
 
             {
 
                for(int i = row + 1; i<n; i++)/// ставим следующую ладью в одну из следующих строк
 
                setRook(i,count+1);///и повторяем цикл
 
            }
 
 
 
            mass[row][column]=0;
 
 
 
 
         }
 
         }
 
 
     }
 
     }
  
}
+
     if (((x%n) < (n - 2)) && (x/n) < (n - 1))
 
 
bool tryElephant(int a, int b) ///проверка на наличие фигур по диагоналям.
 
{
 
 
 
     if (!isEmptyDiagonales(a,b))///если не выполняется это условие,
 
                                ///т.е. постановка фигуры не удовлетворяет расстановке по диагоналям
 
    return false;
 
 
 
    return true;
 
 
 
}
 
 
 
/// функция поиска результатов решений.
 
/// diagonale - номер диагонали в которую нужно поставить очередного слона
 
/// count - количество фигур, поставленое к данному моменту
 
void setElephant(int diagonale, int count)
 
{
 
 
 
    int a, b; /// опорная точка диагонали (крайняя левая)
 
 
 
    if (diagonale < n)///если номер диагонали меньше n
 
 
     {
 
     {
         a = diagonale;///значению а присвоить значенье номера диагонали
+
         int ii = x + n + 2;
        b = 0;///значению b присвоить значение 0
+
        if (a[ii] != -2)
 +
        {
 +
            a[ii]++;
 +
            stak[top] = ii;
 +
            top++;
 +
        }
 
     }
 
     }
  
     else///иначе
+
     if (((x%n) < (n - 2)) && (x/n) < 0)
 
     {
 
     {
         a = n-1;///значению а присвоить значение n-1
+
         int ii = x - n + 2;
         b =(diagonale % n)+1;///значению b присвоить значение целого частного от деления номера диагонали на n прибавив к нему 1
+
        if (a[ii] != -2)
 +
         {
 +
            a[ii]++;
 +
            stak[top] = ii;
 +
            top++;
 +
        }
 
     }
 
     }
  
     /// перебираем все "столбцы" текущей диагонали
+
     if (((x%n) < (n - 1)) && (x/n) < 1)
    for(int dcolumn=0; a-dcolumn>=0 && b+dcolumn < n; ++dcolumn)
 
 
     {
 
     {
 
+
         int ii = x - 2*n + 1;
        /// рассчёт координат клетки по координатам крайней точки диагонали и "столбца" в диагонали
+
         if (a[ii] != -2)
         int x = a-dcolumn;
 
        int y = b+dcolumn;
 
 
 
         if(tryElephant(x, y))/// проверка, если поставить слона в A[row][column], будет ли он единственным по диагоналям
 
 
         {
 
         {
 
+
             a[ii]++;
             mass[x][y]=1;
+
             stak[top] = ii;
 
+
             top++;
             if(count+1==figura) /// нужное количество фигур поставлено
 
            {
 
                output_mass(); /// вызов функции вывода массива на экран
 
                zapis("Zapis");///запись в файл
 
            }
 
 
 
            else
 
             {
 
                for(int i = diagonale + 1; i<2*n-1; i++)/// ставим следующего слона в одну из следующих диагоналей
 
                setElephant(i,count+1);///и повторяем цикл
 
            }
 
 
 
            mass[x][y]=0;
 
 
 
 
         }
 
         }
 
 
     }
 
     }
 
 
}
 
}
  
/// проверка на наличие фигуры на позиции x,y
+
void rook(int x, int &top)                                                     //отметить битые клетки ладьей
bool isFigure(int x, int y)
 
 
{
 
{
     return 0 <= x && x < n && 0 <= y && y < n && mass[x][y];
+
     int k = x - (x % n);
}
+
    while ((k/n) == (x/n))
 +
    {
  
///проверка на наличие короля в квадрате 3 на 3
+
        if ((k != x) && (a[k] != -2))
bool tryKing(int a, int b)
 
{
 
 
 
    for(int i = a-1; i <= a+1; i++)///для ячеек находящихся слева и справа от поставленного короля
 
    {
 
        for(int j = b-1; j <= b+1; j++)///для ячеек находящихся снизу и сверху от поставленного короля
 
 
         {
 
         {
             if (isFigure(i,j))///если выполняется это условие
+
             a[k]++;
             return false;///неверно
+
            stak[top] = k;
 +
             top++;
 
         }
 
         }
 +
        k ++;
 
     }
 
     }
  
     return true;///в остальных случаях верно
+
     k = (x % n);
 +
    while (((k/n)) != n)
 +
    {
 +
        if ((k != x) && (a[k] != -2))
 +
        {
 +
            a[k]++;
 +
            stak[top] = k;
 +
            top++;
 +
        }
 +
        k += n;
 +
    }
  
 
}
 
}
 
+
void set_figure(int x, int &top)                                   //ставим фигуры на доску
///функция поиска результатов решений
 
/// count - количество фигур, поставленое к данному моменту
 
///x,y - позиция, начиная с которой разрешено ставить фигуры (все предшествующие позиции уже точно определены)
 
void setKing(int count, int x, int y)
 
 
{
 
{
 
+
    //отмечаем "битые" клетки
     if(count==figura)///figura - количество фигур, вводимых пользователями.
+
     switch (type)
 
     {
 
     {
        output_mass();/// вызов функции вывода массива на экран
+
//король
         zapis("Zapis");///записываем в файл
+
        case 1:
        return;
+
         {
    }
+
            king(x,top);
 +
            break;
 +
        }
  
    if (x == n) /// строки закончились
+
//слон
        return;
+
case 2:
 +
{
 +
    bishop(x,top);
 +
            break;
 +
}
  
    /// обрабатываем текущую строку
+
//конь
    for (int j=y; j<n; ++j)
+
case 3:
    {
+
{
 
+
    knight(x,top);
         if(tryKing(x, j))
+
break;
 +
}
 +
//ладья
 +
        case 4:
 +
         {
 +
            rook(x,top);
 +
            break;
 +
        }
 +
        //ферзь
 +
        case 5:
 
         {
 
         {
             mass[x][j]=1;
+
             rook(x,top);
            /// смещаем разрешённую позицию на 1 вправо или в начало следующей строки
+
             bishop(x,top);
            int nextX = x, nextY = j+1;
+
             break;
 
 
            if (nextY == n)///если столбец последний
 
            {
 
                nextY = 0;///идем сначала по столбцам
 
                nextX++;///к строке прибавляем 1
 
             }
 
 
 
            /// ставим следующего короля
 
            setKing(count+1,nextX,nextY);
 
             mass[x][j]=0;
 
 
 
 
         }
 
         }
 
 
     }
 
     }
  
     /// обрабатываем прямоугольник ниже текущей строки
+
     //отмечаем,что в данной клетке стоит фигура
     for(int i=x+1; i<n; ++i)
+
a[x] = -1;
    {
+
     stak[top] = x;
 +
    top++;
 +
}
  
        for (int j=0; j<n; ++j)
+
void step(int top,int x,int st)
        {
 
 
 
            if(tryKing(i, j))
 
            {
 
                mass[i][j]=1;
 
                /// смещаем разрешённую позицию на 1 вправо или в начало следующей строки
 
                int nextX = i, nextY = j+1;
 
 
 
                if (nextY == n)///если столбец последний
 
                {
 
                    nextY = 0;///идем сначала по столбцам
 
                    nextX++;///к строке прибавляем 1
 
                }
 
 
 
                /// ставим следующего короля
 
                setKing(count+1,nextX,nextY);
 
                mass[i][j]=0;
 
 
 
            }
 
 
 
        }
 
 
 
    }
 
 
 
}
 
 
 
bool tryHorse(int a, int b) ///проверка на коней по всем направлениям
 
 
{
 
{
 +
int xtop = top;
 +
switch (variant)
 +
{
 +
case 1:
 +
{
 +
if (st != (n - 1))
 +
{
 +
set_figure(x,top);
 +
for (int i = 0; i < (n*n); i++)
 +
if (a[i] == 0)
 +
step(top,i,st + 1);
 +
}
 +
else[[:File:Шахматы.rar]]
 +
{
 +
set_figure(x,top);
 +
                cout << endl;
 +
for (int i = 0; i < (n*n); i++)
 +
{
 +
cout.width(3);
 +
if (((i % n) == 0) && (i != 0))
 +
cout << endl;
 +
if (a[i] == -1)
 +
cout << 1;
 +
else
 +
cout << 0;
 +
}
 +
cout << endl;
 +
}
 +
break;
 +
}
 +
case 2:
 +
{
 +
set_figure(x,top);
 +
if ((st+1) > maxst)
 +
maxst = st + 1;
 +
for (int i = 0; i < (n*n); i++)
 +
if (a[i] == 0)
 +
step(top,i,st+1);
 +
break;
 +
}
 +
}
  
    if (isFigure(a-1,b-2) || isFigure(a-1,b+2) || isFigure(a+1,b-2) || isFigure(a+1,b+2) || isFigure(a-2,b-1) || isFigure(a-2,b+1) || isFigure(a+2,b-1) || isFigure(a+2,b+1))
 
                                                        ///если выполняются эти условия,
 
                                                        ///т.е. фигара стоит на одной из этих позиций
 
        return false;///неверно
 
 
    return true;///в остальных случаях верно
 
 
}
 
  
///функция поиска результатов решений
 
/// count - количество фигур, поставленое к данному моменту.
 
void setHorse(int count, int x, int y)
 
{
 
  
     if(count==figura)///figura - количество фигур, вводимых пользователями.
+
// обратный ход
 +
     for (int i = xtop; i < top; i++)
 
     {
 
     {
         output_mass();/// вызов функции вывода массива на экран
+
         if ((a[stak[i]] != -1) && (a[stak[i]] != -2))
        zapis("Zapis");///записываем в файл
+
            a[stak[i]]--;
        return;
+
        else
     }
+
            //не забываем отметить,что фигура уже здесь стояла(чтобы избежать повторов)
 +
            if (a[stak[i]] == -1)
 +
                a[stak[i]] = -2;
 +
//       cerr << " Back "  << stak[i] << endl;
 +
     }
 +
}
 +
 
 +
int main()
 +
{
  
     if (x == n)/// строки закончились
+
     //cin >> n >> type >> variant;
        return;
+
    n = 5;
 +
    type = 4;
 +
variant = 1;
 +
    a    = new int[n*n];
 +
    stak = new int[n*n*4];
  
    /// обрабатываем текущую строку
+
     for (int i = 0; i < (n*n); i++)
     for (int j=y; j<n; ++j)
 
 
     {
 
     {
 +
        for (int j = 0; j < (n*n); j++)
 +
            a[j] = 0;
 +
        if (variant == 1)
 +
            cout << "__________________________________" << endl;
 +
        step(0,i,0);
 +
    }
 +
if (variant == 2)
 +
  cout << maxst;
 +
    return 0;
 +
}
 +
</syntaxhighlight>
 +
</div>
  
        if(tryHorse(x, j))
 
        {
 
  
            mass[x][j]=1;
 
            /// смещаем разрешённую позицию на 1 вправо или в начало следующей строки
 
            int nextX = x, nextY = j+1;
 
  
            if (nextY == n)///если столбец последний
+
'''[[Иванова Яна]]'''
            {
 
                nextY = 0;///идем сначала по столбцам
 
                nextX++;///к строке прибавляем 1
 
            }
 
  
            /// ставим следующего коня
+
'''Краткое описание алгоритма''': Функция, которая выполняет поиск расстановок, пытается поставить фигуру в каждую клетку. В случае неудачи программа отмечает клетки, в которых фигура уже побывала, но постановка не удалась, отрицательной величиной, равной по модулю шагу, на котором эта постановка была испробована. В случае пустой клетки она отмечается нулем, в случае успеха клетка отмечается положительным числом, равным шагу, соответствующему попытке постановки.
            setHorse(count+1,nextX,nextY);
+
Также программа аналитически просчитывает максимальное количество фигур для каждого размера доски.
            mass[x][j]=0;
 
  
        }
+
'''Инструкция''': В меню указывается два варианта развития событий. Пользователь должен выбрать один из путей. Он вводит размер доски и тип фигуры.
 +
Если он выбирает максимальное число расстановок, то программа выводит их количество, а также предлагает вывести все расстановки на экран. Другой вариант работы программы - вывод расстановок N фигур.
  
    }
+
Посмотреть программу можно [http://tm.spbstu.ru/Файл:chess(1).zip здесь]
  
    /// обрабатываем прямоугольник ниже текущей строки
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
    for(int i=x+1; i<n; ++i)
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
    {
 
  
        for (int j=0; j<n; ++j)
+
#include <iostream>
        {
+
#include <algorithm>
 +
#include <exception>
 +
#include <string>
 +
#include <algorithm>
  
            if(tryHorse(i, j))
+
//пусть для определенности максимальный размер доски - 128 клеток
            {
+
#define MAX_SIZE 128
  
                mass[i][j]=1;
+
// перечисление для определения типа фигуры
                /// смещаем разрешённую позицию на 1 вправо или в начало следующей строки
+
enum figure_type
                int nextX = i, nextY = j+1;
+
{
 +
    KING,
 +
    QUEEN,
 +
    ROOK,
 +
    BISHOP,
 +
    KNIGHT
 +
};
  
                if (nextY == n)///если столбец последний
+
// класс для создания доски и расстановки фигур
                {
+
class chess_board
                    nextY = 0;///идем сначала по столбцам
+
{
                    nextX++;///к строке прибавляем 1
+
public:
                }
+
    // конструктор (принимает только размеры)
 
+
    chess_board(const int &size)
                setHorse(count+1,nextX,nextY);
+
    {
                mass[i][j]=0;
+
        if (size >= 0 && size <= MAX_SIZE)
 
+
        {
            }
+
            size_ = size;
 +
            clean_board();
 +
        }
  
 +
        else
 +
        {
 +
            std::cout << "wrong size" << std::endl;
 +
            throw std::string("wrong size");
 
         }
 
         }
 
 
     }
 
     }
  
}
 
  
int main()
+
    // функция очистки доски (занулить все клетки)
{
+
    void clean_board()
    setlocale(LC_ALL,"RUS");
+
    {
 +
        //обнулить счетчик количества фигур на доске
 +
        figures_on_board_ = 0;
 +
        //присвоить всем клеткам значение 0
 +
        for (int i = 0; i < size_; ++i)
 +
        {
 +
            for (int j = 0; j < size_; ++j)
 +
            {
 +
                board_[i][j] = 0;
 +
            }
 +
        }
 +
    }
  
  ofstream Zapis("Zapis", ios::trunc);///сохраняем в файл
+
    // функция, принимающая размер доски
  Zapis.close();
+
    int get_size()
 
 
    do
 
 
     {
 
     {
         cout << "Введите размер доски (четный): ";
+
         return size_;
        cin >> n; ///ввод пользователем размера доски
+
    }
     }while (n%2 != 0);
+
    // функция, обновляющая количество фигур на доске
 
+
     int get_figures_number()
     mass=create_mass(n); ///создаём двумерный массив
+
    {
 +
        return figures_on_board_;
 +
     }
  
     cout<<"Queen-1, Rook-2, Elephant-3, King-4, Horse-5"<< endl;
+
     //функция, пытающаяся поставить фигуру на свободное место и возвращающая
     cin >> figureID; ///выбор пользователем фигуры
+
    //истину в случае успеха и ложь в случае неудачи
 +
    bool put_figure (const figure_type& figure, const int& x, const int& y, const int& step)
 +
     {
 +
        if (board_[x][y] > 0 || board_[x][y] < -step)
 +
        {
 +
          //если здесь уже стоит фигура или мы когда-то пытались ее сюда поставить, вернуть ложь
 +
            return false;
 +
        }
  
    /// устанавливаем максимальное количество в зависимости от фигуры
+
        if (check_figure(figure, x, y))
    if (figureID==1)
+
        {
    maxCount=n;
+
            board_[x][y] = step;
    if (figureID==2)
+
            ++figures_on_board_;
    maxCount=n;
+
            return true;
    if (figureID==3)
+
        }
    maxCount=2*n-2;
+
        else
    if (figureID==4)
+
        {
    maxCount=(n*n)/4;
+
            return false;
    if (figureID==5)
+
        }
     maxCount=(n*n)/2;
+
     }
  
     /// запрашиваем количество фигур
+
     //отметить клетку как ранее пройденную функцией
     do
+
    //вычесть единицу из количества фигур на доске
 +
     void remove_figure(const int& x, const int& y)
 
     {
 
     {
         cout << "Введите количество фигур (максимальное количество - " << maxCount << "): ";
+
         board_[x][y] *= -1;
         cin >> figura;
+
         --figures_on_board_;
     }while (figura>maxCount);
+
     }
  
     /// запускаем перебор
+
     //функция печати доски на экран
     if (figureID==1)
+
     void print() const
 
     {
 
     {
         for(int i = 0; i<n; i++)
+
        using namespace std;
        setQueen(i,0);
+
        cout << "==========================================" << endl;
         zapis("Zapis");
+
         for (int i = 0; i < size_; ++i)
 +
        {
 +
            for (int j = 0; j < size_; ++j)
 +
            {
 +
                //если фигура стоит в клетке, то вывести "*", если нет - вывести "-"
 +
                cout << (board_[i][j] > 0?"*":"-") << " ";
 +
            }
 +
            cout << endl;
 +
         }
 +
        cout << "==========================================" << endl;
 
     }
 
     }
     if (figureID==2)
+
 
 +
private:
 +
 
 +
     //функция, проверяющая возможность или невозможность постановки фигуры на данную клетку
 +
    bool check_figure(const figure_type& figure, const int& x, const int& y)
 
     {
 
     {
         for(int i = 0; i<n; i++)
+
         //выбор следующего действия в зависимости от типа фигуры
         setRook(i,0);
+
        switch (figure)
        zapis("Zapis");
+
         {
    }
+
            case KING:
    if (figureID==3)
+
                return check_king(x, y);
    {
+
            case QUEEN:
        for(int i = 0; i<2*n-1; i++)
+
                return check_queen(x, y);
        setElephant(i,0);
+
            case ROOK:
         zapis("Zapis");
+
                return check_rook(x, y);
 +
            case BISHOP:
 +
                return check_bishop(x, y);
 +
            case KNIGHT:
 +
                return check_knight(x, y);
 +
                //в случае ошибки ввода вернуть ложь
 +
            default:
 +
                return false;
 +
         }
 
     }
 
     }
     if (figureID==4)
+
 
 +
     //поиск расстановок короля
 +
    bool check_king(const int& x, const int& y)
 
     {
 
     {
        setKing(0,0,0);
+
        int min_x = std::max(x - 1, 0);
        zapis("Zapis");
+
        int max_x = std::min(x + 1, size_ - 1);
 +
        int min_y = std::max(y - 1, 0);
 +
        int max_y = std::min(y + 1, size_ - 1);
 +
 
 +
        for (int i = min_x; i <= max_x; ++i)
 +
        {
 +
            for (int j = min_y; j <= max_y; ++j)
 +
            {
 +
                if (board_[i][j] > 0)
 +
                {
 +
                    return false;
 +
                }
 +
            }
 +
        }
 +
        return true;
 
     }
 
     }
     if (figureID==5)
+
 
 +
     //поиск расстановок ладьи
 +
    bool check_rook(const int& x, const int& y)
 
     {
 
     {
         setHorse(0,0,0);
+
         for (int i = 0; i < size_; ++i)
         zapis("Zapis");
+
        {
    }
+
            if (board_[i][y] > 0)
    system("PAUSE");
+
            {
}
+
                return false;
</syntaxhighlight>
+
            }
</div>
+
        }
 +
         for (int j = 0; j < size_; ++j)
 +
        {
 +
            if (board_[x][j] > 0)
 +
            {
 +
                return false;
 +
            }
 +
        }
 +
        return true;
 +
    }
  
'''[[Васильева Анастасия]]'''
+
    //поиск расстановок слона
 +
    bool check_bishop(const int& x, const int& y)
 +
    {
 +
        bool check = true;
  
'''Краткое описание алгоритма''': Доска представлена в виде динамического массива, по ходу программы, в зависимости от алгоритмов для разных фигур, функции заполняют доску числами  0-место свободно, 1-находится под ударом и 2-занято фигурой, потом массив преобразовывается к нормальному виду 0 и 1-фигура. Так программа прогоняет все возможные варианты расстановок. Также программа аналитически просчитывает максимальное количество фигур для каждого размера доски.
+
        int k_start_1 = -std::min(x, y);
 +
        int k_end_1 = std::min( size_ - x, size_ - y) - 1;
  
'''Инструкция''': Сначала программа просит выбрать фигуру, с которой будем работать. Затем 2 варианта развития событий: 1 - вывод в файл всех расстановок, 2 - максимальное количество фигур. В зависимости от выбора, в первом случае еще нужно ввести количество фигур, и программа запишет в файл все возможные варианты и выведет на экран число расстановок, а во втором - на экране появится максимальное кол-во фигур.
+
        int k_start_2 = -std::min( x, size_ - y - 1);
Скачать можно [http://tm.spbstu.ru/Файл:Задача1.zip тут].
+
        int k_end_2 = std::min( y, size_ - x - 1);
  
  
'''[[Гильманов Илья]]'''
+
        for (int k = k_start_1; k <= k_end_1; ++k)
 +
        {
 +
            check = check_coord(x + k, y + k) && check ;
 +
        }
 +
        for (int k = k_start_2; k <= k_end_2; ++k)
 +
        {
 +
            check = check_coord(x + k, y - k) && check;
 +
        }
  
'''Основная идея программы''': пользователь вводит размер доски MxM , тип фигур, их количество. Программа рассчитывает максимально возможное количество фигур , которые можно расположить на доске, чтобы они не били друг друга.
+
        return check;
 +
    }
  
'''Инструкция к программе''': Пользователь вводит размер доски M(size*size).А затем предоставляется выбор между нахождением максимально возможного числа фигур , и их расстановкой.Также пользователь выбирает тип фигуры , и количество(если интересует расстановка).
 
  
Скачать можно [http://mech.spbstu.ru/File:CheEeeSss.rar здесь]
+
    //поиск расстановок коня
 
+
    bool check_knight(const int& x, const int& y)
'''[[Демченко Артём]]'''
+
    {
 
+
        bool check =
'''Основная идея программы''': Программа подсчитывает и выводит расстановку указанного кол-ва фигур на указанном поле и второй опицей выводит максимальную расстановку на поле размером size*size.
+
            check_coord(x - 2, y - 1) &&
 +
            check_coord(x - 2, y + 1) &&
 +
            check_coord(x - 1, y - 2) &&
 +
            check_coord(x - 1, y + 2) &&
 +
            check_coord(x + 1, y - 2) &&
 +
            check_coord(x + 1, y + 2) &&
 +
            check_coord(x + 2, y - 1) &&
 +
            check_coord(x + 2, y + 1);
 +
        return check;
 +
    }
  
'''Инструкция''': Запустите программу и следуйте инструкциям. Сначала идет выбор алгоритма, после чего идет выбор фигуры и размер доски для подсчета максимальной расстановки на поле size*size. Результат будет выведен на экран.
+
    //поиск расстановок королевы
 +
    bool check_queen(const int& x, const int& y)
 +
    {
 +
        return check_rook(x, y) && check_bishop(x, y);
 +
    }
  
Скачать можно [http://tm.spbstu.ru/File:Chessss.zip тут].
+
  //функция поиска расстановок, в случае, когда на доске что-то стоит, вернуть ложь
 +
  //иначе поставить вернуть истину
 +
    bool check_coord(const int& x, const int& y)
 +
    {
 +
        if (x >= 0 && x < size_ && y >= 0 && y < size_)
 +
        {
 +
            if (board_[x][y] > 0)
 +
            {
 +
                return false;
 +
            }
 +
        }
 +
        return true;
 +
    }
  
'''[[Иванова Яна]]'''
+
    // if board_[x][y] == 0
 +
    //    клетка свободна
 +
    // if board_[x][y] == s
 +
    //    фигура была поставлена на шаге S
 +
    // if board_[x][y] == -s
 +
    //    клетка свободна, но была попытка поставить фигуру на шаге S
 +
    int board_[MAX_SIZE][MAX_SIZE];
 +
    int size_;
 +
    int figures_on_board_;
 +
};
  
'''Краткое описание алгоритма''': Функция, которая выполняет поиск расстановок, пытается поставить фигуру в каждую клетку. В случае неудачи программа отмечает клетки, в которых фигура уже побывала, но постановка не удалась, отрицательной величиной, равной по модулю шагу, на котором эта постановка была испробована. В случае пустой клетки она отмечается нулем, в случае успеха клетка отмечается положительным числом, равным шагу, соответствующему попытке постановки.
+
//функция расчета максимума для любой доски в зависимости от типа фигуры
Также программа аналитически просчитывает максимальное количество фигур для каждого размера доски.
+
int get_max_figures (const figure_type& figure, const int& size)
 
+
{
'''Инструкция''': В меню указывается два варианта развития событий. Пользователь должен выбрать один из путей. Он вводит размер доски и тип фигуры.
+
     switch (figure)
Если он выбирает максимальное число расстановок, то программа выводит их количество, а также предлагает вывести все расстановки на экран. Другой вариант работы программы - вывод расстановок N фигур.
 
 
 
Посмотреть программу можно [http://tm.spbstu.ru/Файл:chess(1).zip здесь]
 
 
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
 
 
#include <iostream>
 
#include <algorithm>
 
#include <exception>
 
#include <string>
 
#include <algorithm>
 
 
 
//пусть для определенности максимальный размер доски - 128 клеток
 
#define MAX_SIZE 128
 
 
 
// перечисление для определения типа фигуры
 
enum figure_type
 
{
 
    KING,
 
    QUEEN,
 
    ROOK,
 
    BISHOP,
 
    KNIGHT
 
};
 
 
 
// класс для создания доски и расстановки фигур
 
class chess_board
 
{
 
public:
 
     // конструктор (принимает только размеры)
 
    chess_board(const int &size)
 
 
     {
 
     {
         if (size >= 0 && size <= MAX_SIZE)
+
         case KING:
         {
+
            return (size + 1) / 2;
             size_ = size;
+
        case QUEEN:
             clean_board();
+
            if (size <= 2)
        }
+
            {
 
+
                return 1;
        else
+
            }
        {
+
            else if (size == 3)
             std::cout << "wrong size" << std::endl;
+
            {
             throw std::string("wrong size");
+
                return 2;
         }
+
            }
 +
            else
 +
            {
 +
                return size;
 +
            }
 +
         case ROOK:
 +
             return size;
 +
        case BISHOP:
 +
             if (size == 1)
 +
            {
 +
                return size;
 +
            }
 +
            else
 +
            {
 +
                return 2 * (size - 1);
 +
             }
 +
        case KNIGHT:
 +
            if (size <= 2)
 +
            {
 +
                return size * size;
 +
             }
 +
            else
 +
            {
 +
                return (size * size + 1) / 2;
 +
            }
 +
         default:
 +
            return 1;
 
     }
 
     }
 +
}
  
 
+
//функция для расстановки максимального числа фигур на доске
    // функция очистки доски (занулить все клетки)
+
void place_figures_for_max(chess_board &board, const figure_type& figure, const int& max_figures, int step)
     void clean_board()
+
{
 +
    ++step;
 +
    const int size = board.get_size();
 +
     for (int i = 0; i < size; ++i)
 
     {
 
     {
        //обнулить счетчик количества фигур на доске
+
         for (int j = 0; j < size; ++j)
        figures_on_board_ = 0;
 
        //присвоить всем клеткам значение 0
 
         for (int i = 0; i < size_; ++i)
 
 
         {
 
         {
             for (int j = 0; j < size_; ++j)
+
             //если мы можем поставить фигуру, то добавляем к максимуму единицу и запускаем цикл снова
 +
            if (board.put_figure(figure, i, j, step))
 
             {
 
             {
                 board_[i][j] = 0;
+
                 //если число фигур на доске достигло максимума, то вывести доску
 +
                if (board.get_figures_number() == max_figures)
 +
                {
 +
                    board.print();
 +
                }
 +
                //если число фигур не достигло максимума, продолжить выполнение функции
 +
                else
 +
                {
 +
                    place_figures_for_max(board, figure, max_figures, step);
 +
                }
 +
                board.remove_figure(i, j);
 
             }
 
             }
 
         }
 
         }
 
     }
 
     }
 +
}
 +
 +
//функция, принимающая ввод с клавиатуры как строковый тип данных
 +
figure_type get_figure_type(const std::string& str)
 +
{
 +
    using namespace std;
  
     // функция, принимающая размер доски
+
     figure_type figure;
     int get_size()
+
     if (str == string("king"))
 +
    {
 +
        figure = KING;}
 +
    else if (str == string("queen"))
 +
    {
 +
        figure = QUEEN;}
 +
    else if (str == string("rook"))
 
     {
 
     {
         return size_;
+
         figure = ROOK;
 
     }
 
     }
     // функция, обновляющая количество фигур на доске
+
     else if (str == string("bishop"))
    int get_figures_number()
 
 
     {
 
     {
         return figures_on_board_;
+
         figure = BISHOP;
 
     }
 
     }
 
+
     else if (str == string("knight"))
     //функция, пытающаяся поставить фигуру на свободное место и возвращающая
 
    //истину в случае успеха и ложь в случае неудачи
 
    bool put_figure (const figure_type& figure, const int& x, const int& y, const int& step)
 
 
     {
 
     {
        if (board_[x][y] > 0 || board_[x][y] < -step)
+
      figure = KNIGHT;
        {
 
          //если здесь уже стоит фигура или мы когда-то пытались ее сюда поставить, вернуть ложь
 
            return false;
 
        }
 
 
 
        if (check_figure(figure, x, y))
 
        {
 
            board_[x][y] = step;
 
            ++figures_on_board_;
 
            return true;
 
        }
 
        else
 
        {
 
            return false;
 
        }
 
 
     }
 
     }
 
+
     //вывести ошибку в случае неверного ввода
    //отметить клетку как ранее пройденную функцией
+
     else
     //вычесть единицу из количества фигур на доске
 
     void remove_figure(const int& x, const int& y)
 
 
     {
 
     {
         board_[x][y] *= -1;
+
         cout << "wrong figure type" << endl;
         --figures_on_board_;
+
         throw string("wrong figure type");
 
     }
 
     }
  
     //функция печати доски на экран
+
     return figure;
    void print() const
+
}
     {
+
 
        using namespace std;
+
int main()
        cout << "==========================================" << endl;
+
{
        for (int i = 0; i < size_; ++i)
+
     //использовать стандартное пространств имен
        {
+
    using namespace std;
            for (int j = 0; j < size_; ++j)
+
 
            {
+
    int size;
                //если фигура стоит в клетке, то вывести "*", если нет - вывести "-"
+
    string type_of_figure;
                cout << (board_[i][j] > 0?"*":"-") << " ";
+
    string type_of_action;
            }
+
    figure_type figure;
            cout << endl;
+
 
        }
+
    cout << "Возможные фигуры: king, queen, rook, bishop, knight" << endl;
        cout << "==========================================" << endl;
+
    cout << "Возможные действия: max, placing" << endl;
     }
+
    cout << "----------------------------------------------------" << endl;
 +
 
 +
    cout <<"Введите размер доски: ";
 +
    cin >> size;
 +
    chess_board board(size);
 +
 
 +
    cout << "Введите тип фигуры: ";
 +
     cin >> type_of_figure;
 +
    figure = get_figure_type(type_of_figure);
  
private:
+
    cout << "Введите необходимое действие: ";
 +
    cin >> type_of_action;
  
     //функция, проверяющая возможность или невозможность постановки фигуры на данную клетку
+
     if (type_of_action == string("max"))
    bool check_figure(const figure_type& figure, const int& x, const int& y)
 
 
     {
 
     {
         //выбор следующего действия в зависимости от типа фигуры
+
 
         switch (figure)
+
        int max_figures = get_max_figures(figure, size);
 +
        cout << "Max figures: " << max_figures << endl;
 +
 
 +
        cout << "Хотите ли вы просмотреть все варианты? (yes/no) ";
 +
        string answer;
 +
        cin >> answer;
 +
         //если нужно вывести все расстановки, то применить непосредственно функцию поиска расстановок максимума
 +
         if (answer == string("yes"))
 
         {
 
         {
             case KING:
+
             int step = 0;
                return check_king(x, y);
+
             place_figures_for_max(board, figure, max_figures, step);
             case QUEEN:
+
         }
                return check_queen(x, y);
 
            case ROOK:
 
                return check_rook(x, y);
 
            case BISHOP:
 
                return check_bishop(x, y);
 
            case KNIGHT:
 
                return check_knight(x, y);
 
                //в случае ошибки ввода вернуть ложь
 
            default:
 
                return false;
 
         }
 
 
     }
 
     }
 +
    //иначе если нужно расставить определенное количество фигур, то применить функцию поиска расстановок
 +
    //относительно введенного числа
 +
    else if (type_of_action == string("placing"))
 +
    {
 +
        int figures_to_place;
 +
        cout << "Сколько фигур нужно расставить: ";
 +
        cin >> figures_to_place;
  
     //поиск расстановок короля
+
        int step = 0;
     bool check_king(const int& x, const int& y)
+
        place_figures_for_max(board, figure, figures_to_place, step);
 +
    }
 +
     //иначе вывести ошибку действия
 +
     else
 
     {
 
     {
         int min_x = std::max(x - 1, 0);
+
         cout << "wrong type of action" << endl;
        int max_x = std::min(x + 1, size_ - 1);
+
         throw string("wrong type of action");
        int min_y = std::max(y - 1, 0);
 
        int max_y = std::min(y + 1, size_ - 1);
 
 
 
        for (int i = min_x; i <= max_x; ++i)
 
         {
 
            for (int j = min_y; j <= max_y; ++j)
 
            {
 
                if (board_[i][j] > 0)
 
                {
 
                    return false;
 
                }
 
            }
 
        }
 
        return true;
 
 
     }
 
     }
  
     //поиск расстановок ладьи
+
     return 0;
    bool check_rook(const int& x, const int& y)
+
}
    {
 
        for (int i = 0; i < size_; ++i)
 
        {
 
            if (board_[i][y] > 0)
 
            {
 
                return false;
 
            }
 
        }
 
        for (int j = 0; j < size_; ++j)
 
        {
 
            if (board_[x][j] > 0)
 
            {
 
                return false;
 
            }
 
        }
 
        return true;
 
    }
 
  
    //поиск расстановок слона
 
    bool check_bishop(const int& x, const int& y)
 
    {
 
        bool check = true;
 
  
        int k_start_1 = -std::min(x, y);
+
</syntaxhighlight>
        int k_end_1 = std::min( size_ - x, size_ - y) - 1;
+
</div>
  
        int k_start_2 = -std::min( x, size_ - y - 1);
+
'''[[Андреева Полина]]'''
        int k_end_2 = std::min( y, size_ - x - 1);
 
  
 +
'''Краткое описание алгоритма''':если шахматную доску представить в виде одной строчки(вторую поставить следом за первой, третью за второй и тд), то получится двоичное число. Максимальное число которое может получиться если 111...111 перевести в десятичное ,это число М*М. Тогда абсолютно ВСЕ варианты расстановки фигур это двоичные записи чисел от 0 до М*М. В программе есть цикл, который рассматривает каждый вариант для числа от 0 до М*М, переводит его в двоичную форму. Программа рассматривает каждую клетку, где стоит фигура. Если эта фигура бьет других, то цикл прерывается, нам такой вариант не подходит. Если никакая фигура не бьет никакую другую, то идет подсчет количества фигур на доске. Если фигур столько, сколько нужно, то вывод на экран.
  
        for (int k = k_start_1; k <= k_end_1; ++k)
+
'''Инструкция''': На экране показано соответствие каждому номеру типа фигуры. Пользователь выбирает тип фигуры, испольуя номер. Дальше нужно ввести размер доски. Затем на экране появляется два варианта количества фигур на доске: максимальное или введенное пользователем. Пользователь выбирает вариант. Если второй, то затем надо будет ввести количество фигур.
        {
+
[http://tm.spbstu.ru/Файл:ШахматыАП.rar Программа]
            check = check_coord(x + k, y + k) && check ;
 
        }
 
        for (int k = k_start_2; k <= k_end_2; ++k)
 
        {
 
            check = check_coord(x + k, y - k) && check;
 
        }
 
 
 
        return check;
 
    }
 
  
 +
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
#include <cstring>
 +
#include <iostream>
 +
#include"math.h"
 +
#include <fstream>
 +
using namespace std;
  
    //поиск расстановок коня
+
int M, N;  // M-размер доски, N-коичество шахмат.
    bool check_knight(const int& x, const int& y)
+
int    sum;//нужно в процессе для подсчета количества шахмат
    {
+
int **ChessBoard= new int* [M];
        bool check =
 
            check_coord(x - 2, y - 1) &&
 
            check_coord(x - 2, y + 1) &&
 
            check_coord(x - 1, y - 2) &&
 
            check_coord(x - 1, y + 2) &&
 
            check_coord(x + 1, y - 2) &&
 
            check_coord(x + 1, y + 2) &&
 
            check_coord(x + 2, y - 1) &&
 
            check_coord(x + 2, y + 1);
 
        return check;
 
    }
 
  
    //поиск расстановок королевы
+
void ChessBoards(int k) //создание доски, k-число, которое переводим в двоичную запись, чтобы отобразить на доске расстановку фигур, 1-фигура есть, 0-нет.
     bool check_queen(const int& x, const int& y)
+
{
 +
     for (int i=0; i<M; i++) //создание массива
 
     {
 
     {
         return check_rook(x, y) && check_bishop(x, y);
+
         ChessBoard[i] = new int[M];
 
     }
 
     }
 
+
    for (int x=(M-1); x>=0; x=x-1)//заполнение массива фигурами (переводя k в двоичную форму)
  //функция поиска расстановок, в случае, когда на доске что-то стоит, вернуть ложь
 
  //иначе поставить вернуть истину
 
    bool check_coord(const int& x, const int& y)
 
 
     {
 
     {
         if (x >= 0 && x < size_ && y >= 0 && y < size_)
+
         for (int y=(M-1); y>=0; y=y-1)
 
         {
 
         {
             if (board_[x][y] > 0)
+
             ChessBoard[x][y]=(k%2);
             {
+
             k=k/2;
                return false;
 
            }
 
 
         }
 
         }
        return true;
 
 
     }
 
     }
 +
}
 +
void print (char filename[] ) ///создание функции вывода массива в файл
 +
    {
 +
        ofstream fout(filename, ios::app);
 +
 +
        for (int x=0; x<M; ++x)
 +
        {
 +
            for(int y=0; y<M; ++y)
 +
            {
 +
                fout << ChessBoard[x][y]<<" "; ///вывод массива в файл
 +
            }
 +
            fout <<'\n';
 +
 +
        }
 +
        fout <<"\n\n";
 +
 +
        fout.close();
 +
    }
 +
  
    // if board_[x][y] == 0
 
    //    клетка свободна
 
    // if board_[x][y] == s
 
    //    фигура была поставлена на шаге S
 
    // if board_[x][y] == -s
 
    //    клетка свободна, но была попытка поставить фигуру на шаге S
 
    int board_[MAX_SIZE][MAX_SIZE];
 
    int size_;
 
    int figures_on_board_;
 
};
 
  
//функция расчета максимума для любой доски в зависимости от типа фигуры
+
bool CheckHorse(int x, int y)//проверка для коня в клетке с номером x, y
int get_max_figures (const figure_type& figure, const int& size)
 
 
{
 
{
     switch (figure)
+
 
 +
     if (((x+1)<M) && ((y+2)<M) && (ChessBoard[x+1][y+2]==1))//если в клетке, куда может сходить конь (х+1,у+2) уже есть фигура, то этот вариант не подходит, так как один конь бьет другого.
 +
    {
 +
        return false;
 +
 
 +
    }
 +
    else if (((x+1)<M ) && ((y-2)>=0) && (ChessBoard[x+1][y-2]==1))//то же самое и в остальных случаях проверяем бьет ли один конь другого.
 
     {
 
     {
         case KING:
+
         return false;
            return (size + 1) / 2;
+
 
        case QUEEN:
+
    }
            if (size <= 2)
+
    else if (((x-1)>=0) && ((y+2)<M) && (ChessBoard[x-1][y+2]==1))
            {
+
    {
                return 1;
+
         return false;
            }
 
            else if (size == 3)
 
            {
 
                return 2;
 
            }
 
            else
 
            {
 
                return size;
 
            }
 
        case ROOK:
 
            return size;
 
        case BISHOP:
 
            if (size == 1)
 
            {
 
                return size;
 
            }
 
            else
 
            {
 
                return 2 * (size - 1);
 
            }
 
        case KNIGHT:
 
            if (size <= 2)
 
            {
 
                return size * size;
 
            }
 
            else
 
            {
 
                return (size * size + 1) / 2;
 
            }
 
         default:
 
            return 1;
 
 
     }
 
     }
}
+
    else if (((x-1)>=0) && ((y-2)>=0) && (ChessBoard[x-1][y-2]==1))
 
 
//функция для расстановки максимального числа фигур на доске
 
void place_figures_for_max(chess_board &board, const figure_type& figure, const int& max_figures, int step)
 
{
 
    ++step;
 
    const int size = board.get_size();
 
    for (int i = 0; i < size; ++i)
 
 
     {
 
     {
         for (int j = 0; j < size; ++j)
+
         return false;
        {
+
    }
            //если мы можем поставить фигуру, то добавляем к максимуму единицу и запускаем цикл снова
+
    else if (((x+2)<M) && ((y+1)<M) && (ChessBoard[x+2][y+1]==1))
            if (board.put_figure(figure, i, j, step))
+
    {
            {
+
        return false;
                //если число фигур на доске достигло максимума, то вывести доску
 
                if (board.get_figures_number() == max_figures)
 
                {
 
                    board.print();
 
                }
 
                //если число фигур не достигло максимума, продолжить выполнение функции
 
                else
 
                {
 
                    place_figures_for_max(board, figure, max_figures, step);
 
                }
 
                board.remove_figure(i, j);
 
            }
 
        }
 
 
     }
 
     }
}
+
    else if (((x+2)<M ) && ((y-1)>=0) && (ChessBoard[x+2][y-1]==1))
 
 
//функция, принимающая ввод с клавиатуры как строковый тип данных
 
figure_type get_figure_type(const std::string& str)
 
{
 
    using namespace std;
 
 
 
    figure_type figure;
 
    if (str == string("king"))
 
 
     {
 
     {
         figure = KING;}
+
         return false;
     else if (str == string("queen"))
+
    }
 +
     else if (((x-2)>=0 ) && ((y+1)<M) && (ChessBoard[x-2][y+1]==1))
 
     {
 
     {
         figure = QUEEN;}
+
         return false;
    else if (str == string("rook"))
 
    {
 
        figure = ROOK;
 
 
     }
 
     }
     else if (str == string("bishop"))
+
     else if (((x-2)>=0 ) && ((y-1)>=0) && (ChessBoard[x-2][y-1]==1))
 
     {
 
     {
         figure = BISHOP;
+
         return false;
 
     }
 
     }
     else if (str == string("knight"))
+
     else //в итоге, если конь, стоящий в данной клетке никого не бьет, то этот вариант подходит
 
     {
 
     {
      figure = KNIGHT;
+
        return true;
 
     }
 
     }
    //вывести ошибку в случае неверного ввода
+
}
     else
+
 
 +
int Horse(int k)//k-то число которое нужно будет перевести в двоичную форму, это делается в main'е
 +
//в этой функции считаем количество фигур, если он равно введенному  или максимальному,то доска подходит и выводится в файл (все это в main'е)
 +
{
 +
     for (int x=0; x<M; x++)
 
     {
 
     {
         cout << "wrong figure type" << endl;
+
         int y;
         throw string("wrong figure type");
+
        for (y=0; y<M; y++)
 +
        {
 +
            if (ChessBoard[x][y]==1)//если в данной клетке стоит конь, то нужно проверить,
 +
            // бьет оно кого-то или нет...
 +
            //если в клетке нет коня, то ее проверять не нужно
 +
            {
 +
                if (CheckHorse(x,y))//...делаем это с помощью этой функции,если конь в данной клетке х;у 
 +
                //никого не бьет, то прибавляем 1 к количеству шахмат на доске и считаем дальше 
 +
                {
 +
                    sum=sum+1;
 +
                }
 +
                else //а если бьет, то выходим из цикла, на данной этапе выйдем только из внуреннего
 +
                {
 +
                    sum=0;//количество фигур обнуляем
 +
                    break;
 +
                }
 +
            }
 +
         }
 +
        if (y<M)//если из внутреннего цикла вышли раньше, значит у досчитался не до конца,
 +
        //то есть он меньше своего максимального значения М
 +
        {
 +
           
 +
            break;//тогда выходим и из внешнего цикла
 +
        }
 
     }
 
     }
 
+
     return sum; //возвращаем количество фигур
     return figure;
 
 
}
 
}
  
int main()
+
bool CheckKing(int x, int y) //все то же самое для проверки короля, стоящего в клетке х,у
 
{
 
{
    //использовать стандартное пространств имен
 
    using namespace std;
 
  
     int size;
+
     if (((x+1)<M) && ((y+1)<M) && (ChessBoard[x+1][y+1])==1)//если в клетке куда может сходить король
    string type_of_figure;
+
    //уже есть фигура, то клетка не подходит и т.д
    string type_of_action;
 
    figure_type figure;
 
 
 
    cout << "Возможные фигуры: king, queen, rook, bishop, knight" << endl;
 
    cout << "Возможные действия: max, placing" << endl;
 
    cout << "----------------------------------------------------" << endl;
 
 
 
    cout <<"Введите размер доски: ";
 
    cin >> size;
 
    chess_board board(size);
 
 
 
    cout << "Введите тип фигуры: ";
 
    cin >> type_of_figure;
 
    figure = get_figure_type(type_of_figure);
 
 
 
    cout << "Введите необходимое действие: ";
 
    cin >> type_of_action;
 
 
 
    if (type_of_action == string("max"))
 
 
     {
 
     {
 +
        return false;
  
        int max_figures = get_max_figures(figure, size);
 
        cout << "Max figures: " << max_figures << endl;
 
 
        cout << "Хотите ли вы просмотреть все варианты? (yes/no) ";
 
        string answer;
 
        cin >> answer;
 
        //если нужно вывести все расстановки, то применить непосредственно функцию поиска расстановок максимума
 
        if (answer == string("yes"))
 
        {
 
            int step = 0;
 
            place_figures_for_max(board, figure, max_figures, step);
 
        }
 
 
     }
 
     }
    //иначе если нужно расставить определенное количество фигур, то применить функцию поиска расстановок
+
     else if (((x+1)<M ) && (ChessBoard[x+1][y]==1))
    //относительно введенного числа
 
     else if (type_of_action == string("placing"))
 
 
     {
 
     {
         int figures_to_place;
+
         return false;
        cout << "Сколько фигур нужно расставить: ";
 
        cin >> figures_to_place;
 
  
        int step = 0;
 
        place_figures_for_max(board, figure, figures_to_place, step);
 
 
     }
 
     }
    //иначе вывести ошибку действия
+
     else if (((x+1)<M) && ((y-1)>=0) && (ChessBoard[x+1][y-1]==1))
     else
 
 
     {
 
     {
         cout << "wrong type of action" << endl;
+
         return false;
        throw string("wrong type of action");
+
    }
 +
    else if (((x-1)>=0) && ((y-1)>=0) && (ChessBoard[x-1][y-1]==1))
 +
    {
 +
        return false;
 +
    }
 +
    else if (((x-1)>=0) && ((y+1)<M) && (ChessBoard[x-1][y+1]==1))
 +
    {
 +
        return false;
 +
    }
 +
    else if (((x-1)>=0) &&  (ChessBoard[x-1][y]==1))
 +
    {
 +
        return false;
 +
    }
 +
    else if (((y+1)<M) && (ChessBoard[x][y+1]==1))
 +
    {
 +
        return false;
 +
    }
 +
    else if (((y-1)>=0) && (ChessBoard[x][y-1]==1))
 +
    {
 +
        return false;
 +
    }
 +
    else
 +
    {
 +
        return true;
 
     }
 
     }
 
    return 0;
 
 
}
 
}
  
 +
int King(int k) //так же как и для коня, проверяем каждую клетку
 +
//подходит-прибавляем к количеству фигур sum единичку, нет-обнуляем сумму и выходим из цикла
 +
{
 +
    for (int x=0; x<M; x++)
 +
    {
 +
        int y;
 +
        for (y=0; y<M; y++)
 +
        {
 +
            if (ChessBoard[x][y]==1)
 +
            {
 +
                if (CheckKing(x,y))
 +
                {
 +
                    sum=sum+1;
 +
                }
 +
                else
 +
                {
 +
                    sum=0;
 +
                    break;
 +
                }
 +
            }
 +
        }
 +
        if (y<M)
 +
        {
 +
            break;
 +
        }
 +
    }
 +
    return sum;
 +
}
  
</syntaxhighlight>
+
int CheckQueen(int x, int y)///проверка для королевы, принцип тот же, королева стит в клеке x,y
</div>
+
///1 значит как true в bool (как в коне или короле), 0 - false
 
+
{ int returnn=1;//начала true, дальше если будет false, то return примет значение 0, а если все пдходит
 
+
///то так и стается 1
 
+
int m;
'''[[Капитанюк Светлана]]'''
+
    for (m=1; m<M; m++)
 
+
  { //проверяем для диагоналей
'''Краткое описание алгоритма''': Доска представлена в виде динамического массива. Если в клетке присутствует фигура, то тогада она обозначается '+', если же клетка осталась путсая, то тогда '0'.
+
    ///если по диагонале клетки х,у стоит еще королва, то такой вариант не подходит, выходим из цикла
 
+
    ///разбито на 4 услвия, так как если не разбивать, то клетка в кторой стоит данная королева
'''Инструкция''': Инструкция: при запуске программа предлагает пользователю ввести размер доски, при этом число должно быть четным (если же пользователь вводит нечетное число, программа предлагает ввести размер еще раз, и так до тех пор, пока не будет введено четное число). Далее пользователь выбирает режим работы программы - либо расстановка фигур, либо расчет максимального количества фигур. В режиме расстановки фигур программа предлагает выбрать тип фигуры, выводит максимальное число фигур для доски заданного размера и предлагает ввести желаемое число фигур для расстановки (если оно больше максимального, предлагается повторная попытка ввода). В режиме расчета максимального числа программа предлагает выбрать тип фигуры, выводит рассчитанное число и задает вопрос о необходимости вывода всех возможных расстановок максимального количества для данной фигуры. Оба режима работают (т.е. все запросы повторяются) до тех пор, пока пользователь не даст команду на завершение цикла. Кроме того, в программе есть возможность изменения размера доски после выхода из всех циклов. При положительном ответе пользователя и изменении размера доступны оба режима работы.
+
    ///тоже будет считаться и выходить из цикла
 
+
      if (((x+m)<M)&&((y+m)<M))
Скачать можно  [http://tm.spbstu.ru/File:Chess_03.zip тут].
+
      {
 
+
          if (ChessBoard[x+m][y+m]==1)
'''[[Киселёв Лев]]'''
+
          {returnn=0;
 
+
          break;
'''Основная идея программы''': реализация задачи о расстановке фигур одинакового типа на произвольной доске MxM
+
          }
Скачать можно [http://mech.spbstu.ru/File:main.rar здесь]
+
      }
 
+
      if (((x-m)>=0)&&((y+m)<M))
'''[[Козловская Анна]]'''
+
      {
 
+
          if (ChessBoard[x-m][y+m]==1)
'''Краткое описание алгоритма:''' Доска представлена в виде динамического массива[m;m], при выводе на экран пустые клетки обозначаются звездочками,а клетки, заполненные фигурами-буквами(каждая буква соответствует первой букве названия фигуры на английском языке). Для всех фигур написаны алгоритмы проверки на возможность расстановки фигуры. После выбора типа фигуры,используется рекурсивная функция,которая проверяет возможные расстановки через данную функцию проверки ,для данного типа фигуры. Во втором варианте работы программы,она аналитически высчитывает максимально возможное количество заданных фигур на доске.В программу встроена функция,проверяющая доску на повторные и симметричные относительно всех осей симметрии способы расстановки фигур.
+
          {returnn=0;
 
+
          break;}
'''Инструкция:''' В меню указывается два варианта развития событий. Пользователь должен выбрать один из путей. Он вводит размер доски и тип фигуры и кол-во фигур(для первого типа работы программы).Если он выбирает первый вариант работы программы  - вывод всех различных расстановок N фигур.Другой вариант работы программы максимальное число расстановок- программа выводит их количество.
+
      }
 +
      if (((x+m)<M)&&((y-m)>=0))
 +
      {
 +
          if (ChessBoard[x+m][y-m]==1)
 +
        {returnn=0;
 +
          break;}
 +
      }
 +
      if (((x-m)>=0)&&((y-m)>=0))
 +
      { if (ChessBoard[x-m][y-m]==1)
 +
          {returnn=0;
 +
          break;}
 +
      }
 +
      if (m!=x) ///тут считаем по вертикали и горизонтали, так как длаем в цикле для m, то m меняется
 +
        ///и в какой-то момент может стать х, и тогда роверятьбуде клетку в которой стоит ДАННАЯ и выходить
 +
        ///это не нужно так что выходим только если m не равен x
 +
        {
 +
            if (ChessBoard[m][y]==1) //если по горизонтали есть какая-о клетка, где стоит королева, то выходим
 +
            {
 +
                returnn=0;
 +
                break;
 +
            }
 +
        }
 +
        if (m!=y)//то же по вертикали
 +
        {
 +
          if (ChessBoard[x][m]==1)
 +
            {
 +
                returnn=0;
 +
                break;
 +
            }
 +
        }
 +
  }
 +
  return returnn;
 +
}
  
Скачать можно  [http://tm.spbstu.ru/File:Chess3.rar тут].
+
int Queen(int k)//тут также как и для коня и короля
 
+
{
'''[[Лебедев Станислав]]'''
+
  for (int x=0; x<M; x++)
 
 
'''Функционал программы''': получение всевозможных расстановок n однотипных шахматных фигур первой линии на поле n на n,таких,чтобы фигуры не били друг друга(считается,что фигуры одного цвета также могут бить друг друга) или получения максимального количества фигур первой линии,которые могут стоять на доске n*n;
 
 
 
'''Идея алгоритма''': рекурсивно вызывается функция,которая ставит фигуру в пустую и небитую клетку, а также отмечает клетки,которые эта фигура бьет. Рекурсия продолжается до тех пор,пока либо не будет достигнуто нужное количество, либо не будет возможности поставить фигуру. После выхода из рекурсии начинается "обратный ход", в котором отмеченные как битые на этом шаге,"размечаются"(снимается отметка,что эта клетка бьется),а место,занятое самой фигурой, запоминается.
 
 
 
Скачать можно [http://tm.spbstu.ru/Файл:Шахматы.rar тут].
 
 
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
#include <iostream>
 
#include <math.h>
 
#include <cmath>
 
 
 
using namespace std;
 
 
 
int n,type, *a, *stak, variant, maxst = 0;
 
 
 
void king(int x, int &top)                      //отметить битые клетки королем
 
{
 
    // 012
 
    // 345
 
    // 678
 
 
 
    //0
 
    if (((x % n) > 1) && ((x / n) > 1))
 
 
     {
 
     {
         int ii = x - n - 1;
+
         int y;
         if (a[ii] != -2)
+
         for (y=0; y<M; y++)
 
         {
 
         {
             a[ii]++;
+
             if (ChessBoard[x][y]==1)//если в клетке королева, проверяем подходи ли она нам
            stak[top] = ii;
+
            {
             top++;
+
                if (CheckQueen(x,y))
 +
                {
 +
                    sum=sum+1;
 +
                }
 +
                else
 +
                {
 +
                    sum=0;
 +
                    break;
 +
                }
 +
             }
 +
        }
 +
        if (y<M)
 +
        {
 +
            break;
 
         }
 
         }
 
     }
 
     }
 +
    return sum;
 +
}
 +
 +
int CheckRook(int x, int y)///ладья, просто берем ту часть из проверки королевы, где проверка по горизонтали и вертикали
 +
{ int returnn=1;
 +
int m;
 +
    for (m=0; m<M; m++)
  
    //1
 
    if ((x / n) > 0)
 
 
     {
 
     {
        int ii = x - n;
+
         if (m!=x)
         if (a[ii] != -2)
 
 
         {
 
         {
             a[ii]++;
+
             if (ChessBoard[m][y]==1)
             stak[top] = ii;
+
             {
             top++;
+
                returnn=0;
 +
                break;
 +
             }
 
         }
 
         }
    }
+
         if (m!=y)
 
 
    //2
 
    if (((x % n) < (n - 1)) && ((x / n) > 0))
 
    {
 
        int ii = x - n + 1;
 
         if (a[ii] != -2)
 
 
         {
 
         {
            a[ii]++;
+
          if (ChessBoard[x][m]==1)
             stak[top] = ii;
+
             {
             top++;
+
                returnn=0;
 +
                break;
 +
             }
 
         }
 
         }
 
     }
 
     }
  
    //3
+
 
     if ((x % n) > 0)
+
      return returnn;
 +
}
 +
 
 +
int Rook(int k)//все то же самое, количество фигур на доске
 +
{
 +
     for (int x=0; x<M; x++)
 
     {
 
     {
         int ii = x - 1;
+
         int y;
         if (a[ii] != -2)
+
         for (y=0; y<M; y++)
 
         {
 
         {
             a[ii]++;
+
             if (ChessBoard[x][y]==1)
            stak[top] = ii;
+
             {
             top++;
+
                if (CheckRook(x,y)==1)
        }
+
                {
    }
+
                    sum=sum+1;
  
    //5
+
                }
    if ((x % n) < (n - 1))
+
                else
    {
+
                {
        int ii = x + 1;
+
                    sum=0;
        if (a[ii] != -2)
+
                    break;
        {
+
                }
            a[ii]++;
+
             }
            stak[top] = ii;
 
             top++;
 
 
         }
 
         }
    }
+
        if (y<M)
 
 
    //6
 
    if (((x % n ) > 0) && ((x / n) < (n - 1)))
 
    {
 
        int ii = x + n - 1;
 
        if (a[ii] != -2)
 
 
         {
 
         {
             a[ii]++;
+
             break;
            stak[top] = ii;
 
            top++;
 
 
         }
 
         }
 
     }
 
     }
  
     //7
+
     return sum;
    if ((x / n ) < (n - 1))
 
    {
 
        int ii = x + n;
 
        if (a[ii] != -2)
 
        {
 
            a[ii]++;
 
            stak[top] = ii;
 
            top++;
 
        }
 
    }
 
 
 
    //8
 
    if (((x % n ) < (n - 1)) && ((x / n) < (n - 1)))
 
    {
 
        int ii = x + n + 1;
 
    if (a[ii] != -2)
 
        {
 
            a[ii]++;
 
            stak[top] = ii;
 
            top++;
 
        }
 
    }
 
 
}
 
}
  
void bishop(int x, int &top)                                                             //отметить битые клетки слоном
+
int CheckElephant(int x, int y)//для слона берем ту часть прроверки королевы, где по диагонали
{
+
{ int returnn=1;
    //вверх влево
+
  for (int i=1; i<M; i++)
    for (int i = (x - (n + 1)); ((i >= 0) && ((i%n) != (n-1))); i -= (n+1))
+
  {
    {
+
      if (((x+i)<M)&&((y+i)<M))
        if (a[i] != -2)
+
      {
        {
+
          if (ChessBoard[x+i][y+i]==1)
            a[i]++;
+
          {returnn=0;
            stak[top] = i;
+
          break;
            top++;
+
          }
        }
+
      }
    }
+
      if (((x-i)>=0)&&((y+i)<M))
 +
      {
 +
          if (ChessBoard[x-i][y+i]==1)
 +
          {returnn=0;
 +
          break;}
 +
      }
 +
      if (((x+i)<M)&&((y-i)>=0))
 +
      {if (ChessBoard[x+i][y-i]==1)
 +
        {returnn=0;
 +
          break;}
 +
      }
 +
      if (((x-i)>=0)&&((y-i)>=0))
 +
      { if (ChessBoard[x-i][y-i]==1)
 +
          {returnn=0;
 +
          break;}
 +
      }
 +
  }
 +
  return returnn;
 +
}
  
    //вниз вправо
+
int Elephant(int k)///считаем кличесво фигур
    for (int i = (x + (n + 1)); ((i < n*n) && ((i%n) != 0)); i += (n+1))
+
{
 +
for (int x=0; x<M; x++)
 
     {
 
     {
         if (a[i] != -2)
+
         int y;
 +
        for (y=0; y<M; y++)
 +
        {
 +
            if (ChessBoard[x][y]==1)
 +
            {
 +
                if (CheckElephant(x,y))
 +
                {
 +
                    sum=sum+1;
 +
                }
 +
                else
 +
                {
 +
                    sum=0;
 +
                    break;
 +
                }
 +
            }
 +
        }
 +
        if (y<M)
 
         {
 
         {
             a[i]++;
+
             break;
            stak[top] = i;
 
            top++;
 
 
         }
 
         }
 
     }
 
     }
 +
    return sum;
 +
}
 +
 +
int main ()
 +
{
 +
    ofstream MyFile("MyFile", ios::trunc);
 +
    MyFile.close(); // очищаем файл, чтоб при новой записи не было из рошлого запуска
  
     //вверх вправо
+
int figure, z;
    for (int i = x - (n - 1); ((i >= 0) && ((i%n) != 0)); i -= (n-1))
+
     cout<<"enter a figure 1-queen, 2-king, 3-rook , 4-horse or 5-elephant ";
 +
    cin>>figure;///тип фигуры, 1 - королевА, 2-король,3-ладья,4-конь,6-слон
 +
      cout << "\n enter a size of a board M - even number ";///ввести ЧЕТНЫЙ размер доски М
 +
    cin >> M;
 +
    if ( M%2 != 0)///проверка М на четность, с помощью остатка от деления на 2
 
     {
 
     {
         if (a[i] != -2)
+
         while (M%2 != 0)
 
         {
 
         {
             a[i]++;
+
             cout<<" you need EVEN number, enter one more time ";
             stak[top] = i;
+
             cin>>M;
            top++;
 
 
         }
 
         }
 
     }
 
     }
  
     //вниз влево
+
     cout<<"\n choose  1- max amount or 2 - your amount of figures ";
    for (int i = x + (n - 1); ((i < n*n) && ((i%n) != (n-1))); i += (n-1))
+
    cin>>z;///z-один из вариантов 1-максимаьное число фигур на доске,2-пользователь сам вводит
 +
 
 +
    switch (figure)///выбираем фигуру
 
     {
 
     {
        if (a[i] != -2)
+
     case 1:///королева
        {
 
            a[i]++;
 
            stak[top] = i;
 
            top++;
 
        }
 
     }
 
}
 
 
 
void knight(int x, int &top)                                            //отметить битые клетки конем
 
{
 
    if (((x%n) > 0) && (x/n) > 1)
 
 
     {
 
     {
        int ii = x - 2*n - 1;
+
         if (z==2)///пользоватеь сам вводит количество
         if (a[ii] != -2)
 
 
         {
 
         {
             a[ii]++;
+
             cout<<"\n enter an amount of figures ";
             stak[top] = ii;
+
            cin >> N;///ввести количество
             top++;
+
            if (N>M)///проверка на то, сможет ли такое количество уместиться на доске в правильном виде
 +
            {
 +
                while (N>M)
 +
                {
 +
                    cout<<" too many figures, enter one more time ";
 +
                    cin>>N;
 +
                }
 +
            }
 +
            ///вот ниже i- те числа которые нужно перевести в двоичную форму
 +
            for (int i=0; i<=pow(2,(M*M)); i++)///каждый i-новый вариант расстановик фигур
 +
            {
 +
                sum=0;
 +
                int k=i;
 +
                ChessBoards(k);
 +
                if (Queen(k)==N)///если в данной варианте фигур столько. сколько ввел пользователь, то выводим
 +
                {
 +
                    print("MyFile");
 +
                }
 +
            }
 +
        }
 +
        else ///вариант максимального числа фигур на доске
 +
        {  ///так же как и в предыдущем пункте, только количество фигур N максимально,
 +
             /// в случае королевы оно равно размеру доски 
 +
            N=M;
 +
             for (int i=0; i<=pow(2,(M*M)); i++)
 +
            {
 +
                sum=0;
 +
                int k=i;
 +
                ChessBoards(k);
 +
                if (Queen(k)==N)
 +
                {
 +
                    print("MyFile");
 +
                }
 +
            }
 
         }
 
         }
 +
 +
        break;
 
     }
 
     }
 
+
     case 2:///то же самое для короля
     if (((x%n) > 1) && (x/n) > 0)
 
 
     {
 
     {
        int ii = x - n - 2;
+
         if (z==2)
         if (a[ii] != -2)
 
 
         {
 
         {
             a[ii]++;
+
             cout<<"\n enter an amount of figures ";
             stak[top] = ii;
+
            cin >> N;
             top++;
+
              if ( N>(M*M)/4)
 +
            {
 +
                while (N>(M*M)/4)
 +
                {
 +
                    cout<<" too many figures, enter one more time ";
 +
                    cin>>N;
 +
                }
 +
            }
 +
            for (int i=0; i<=pow(2,(M*M)); i++)
 +
            {
 +
                sum=0;
 +
                int k=i;
 +
                ChessBoards(k);
 +
                if (King(k)==N)
 +
                {
 +
                    print("MyFile");
 +
                }
 +
            }
 +
        }
 +
else
 +
        {
 +
             N=(M*M)/4;
 +
             for (int i=0; i<=pow(2,(M*M)); i++)
 +
            {
 +
                sum=0;
 +
                int k=i;
 +
                ChessBoards(k);
 +
                if (King(k)==N)
 +
                {
 +
                    print("MyFile");
 +
                }
 +
            }
 
         }
 
         }
 +
        break;
 
     }
 
     }
 
+
     case 3:///для ладьи
     if (((x%n) > 1) && (x/n) < (n - 1))
 
 
     {
 
     {
        int ii = x + n - 2;
+
         if (z==2)
         if (a[ii] != -2)
 
 
         {
 
         {
             a[ii]++;
+
             cout<<"\n enter an amount of figures ";
             stak[top] = ii;
+
            cin >> N;
             top++;
+
              if (N>M)
 +
             {
 +
                while (N>M)
 +
                {
 +
                    cout<<" too many figures, enter one more time ";
 +
                    cin>>N;
 +
                }
 +
             }
 +
 
 +
            for (int i=0; i<=pow(2,(M*M)); i++)
 +
            {
 +
                sum=0;
 +
                int k=i;
 +
                ChessBoards(k);
 +
                if (Rook(k)==N)
 +
                {
 +
                    print("MyFile");
 +
                }
 +
            }
 
         }
 
         }
    }
+
         else
 
 
    if (((x%n) > 0) && (x/n) < (n - 2))
 
    {
 
         int ii = x + 2*n - 1;
 
        if (a[ii] != -2)
 
 
         {
 
         {
             a[ii]++;
+
             N=M;
            stak[top] = ii;
+
            for (int i=0; i<=pow(2,(M*M)); i++)
             top++;
+
            {
 +
                sum=0;
 +
                int k=i;
 +
                ChessBoards(k);
 +
                if (Rook(k)==N)
 +
                {
 +
                    print("MyFile");
 +
                }
 +
             }
 
         }
 
         }
 +
        break;
 
     }
 
     }
 
+
     case 4:///конь
     if (((x%n) < (n - 1)) && (x/n) < (n - 2))
 
 
     {
 
     {
        int ii = x + 2*n + 1;
+
         if (z==2)
         if (a[ii] != -2)
 
 
         {
 
         {
             a[ii]++;
+
             cout<<"\n enter an amount of figures ";
             stak[top] = ii;
+
             cin >> N;
             top++;
+
              if (N>(M*M)/2)
        }
+
             {
    }
+
                while (N>(M*M)/2)
 +
                {
 +
                    cout<<" too many figures, enter one more time ";
 +
                    cin>>N;
 +
                }
 +
            }
  
    if (((x%n) < (n - 2)) && (x/n) < (n - 1))
+
            for (int i=0; i<=pow(2,(M*M)); i++)
    {
+
            {
        int ii = x + n + 2;
+
                sum=0;
        if (a[ii] != -2)
+
                int k=i;
        {
+
                ChessBoards(k);
            a[ii]++;
+
                if (Horse(k)==N)
            stak[top] = ii;
+
                {
             top++;
+
                    print("MyFile");
 +
                }
 +
             }
 
         }
 
         }
    }
+
         else
 
 
    if (((x%n) < (n - 2)) && (x/n) < 0)
 
    {
 
         int ii = x - n + 2;
 
        if (a[ii] != -2)
 
 
         {
 
         {
             a[ii]++;
+
             N=(M*M)/2;
            stak[top] = ii;
+
            for (int i=0; i<=pow(2,(M*M)); i++)
             top++;
+
            {
 +
                sum=0;
 +
                int k=i;
 +
                ChessBoards(k);
 +
                if (Horse(k)==N)
 +
                {
 +
                    print("MyFile");
 +
                }
 +
             }
 
         }
 
         }
 +
        break;
 
     }
 
     }
 
+
     case 5:///слон
     if (((x%n) < (n - 1)) && (x/n) < 1)
 
 
     {
 
     {
        int ii = x - 2*n + 1;
+
         if (z==2)
         if (a[ii] != -2)
 
 
         {
 
         {
             a[ii]++;
+
             cout<<"\n enter an amount of figures ";
             stak[top] = ii;
+
            cin >> N;
             top++;
+
                if (N>2*M-2)
 +
             {
 +
                while (N>2*M-2)
 +
                {
 +
                    cout<<" too many figures, enter one more time ";
 +
                    cin>>N;
 +
                }
 +
             }
 +
            for (int i=0; i<=pow(2,(M*M)); i++)
 +
            {
 +
                sum=0;
 +
                int k=i;
 +
                ChessBoards(k);
 +
                if (Elephant(k)==N)
 +
                {
 +
                    print("MyFile");
 +
                }
 +
            }
 
         }
 
         }
    }
+
        else
}
+
        {
 
+
            N=2*M-2;
void rook(int x, int &top)                                                     //отметить битые клетки ладьей
+
            for (int i=0; i<=pow(2,(M*M)); i++)
{
+
            {
    int k = x - (x % n);
+
                sum=0;
    while ((k/n) == (x/n))
+
                int k=i;
    {
+
                ChessBoards(k);
 
+
                if (Elephant(k)==N)
        if ((k != x) && (a[k] != -2))
+
                {
        {
+
                    print("MyFile");
            a[k]++;
+
                }
            stak[top] = k;
+
             }
             top++;
 
 
         }
 
         }
         k ++;
+
         break;
 
     }
 
     }
 
+
     default : ///а это еси пользоватеь ввел цифру, которая не соответстует ни одной фигуре
     k = (x % n);
 
    while (((k/n)) != n)
 
 
     {
 
     {
         if ((k != x) && (a[k] != -2))
+
         cout<<"NOOOOO";
        {
+
         break;
            a[k]++;
 
            stak[top] = k;
 
            top++;
 
        }
 
         k += n;
 
 
     }
 
     }
 +
    };
 +
  
}
+
     return 0;
void set_figure(int x, int &top)                                    //ставим фигуры на доску
+
     }
{
+
</syntaxhighlight>
     //отмечаем "битые" клетки
+
</div>
     switch (type)
+
 
    {
+
'''[[Бальцер Анастасия]]'''
//король
 
        case 1:
 
        {
 
            king(x,top);
 
            break;
 
        }
 
  
//слон
+
'''Краткое описание алгоритма''': Для каждой фигуры написана отдельная функция, выполняющая поиск расстановок. После выбора типа фигуры, соответствующая функция выполняет поиск возможных расстановок. Она проходя по строкам двумерного массива пытается поставить фигуру в каждую клетку. Проходя по массиву она маркирует клетки, ставит 0 (если клетка свободна), 1 (если клетка находится под ударом), 2 (если клетка занята). Программа аналитически считает максимальное количество фигур для заданного размера доски, возможное число расстановок для заданных типа фигуры, размера доски и количества фигур.
case 2:
 
{
 
    bishop(x,top);
 
            break;
 
}
 
  
//конь
+
'''Инструкция''': При запуске программы появляется меню, в котором каждому типу фигуры сопоставлен номер, с помощью которого пользователь и выбирает тип фигуры. Затем пользователю на выбор предлагается 2 режима работы программы: первый выводит число возможных расстановок на экран, а список возможных расстановок в отдельный файл (при этом пользователь дополнительно выбирает число фигур); второй выводит на экран максимальное число фигур выбранного типа, которые можно расставить на заданной доске.
case 3:
+
 
{
+
Посмотреть программу можно [http://tm.spbstu.ru/Файл:Расстановка.zip тут]
    knight(x,top);
 
break;
 
}
 
//ладья
 
        case 4:
 
        {
 
            rook(x,top);
 
            break;
 
        }
 
        //ферзь
 
        case 5:
 
        {
 
            rook(x,top);
 
            bishop(x,top);
 
            break;
 
        }
 
    }
 
  
    //отмечаем,что в данной клетке стоит фигура
 
a[x] = -1;
 
    stak[top] = x;
 
    top++;
 
}
 
  
void step(int top,int x,int st)
 
{
 
int xtop = top;
 
switch (variant)
 
{
 
case 1:
 
{
 
if (st != (n - 1))
 
{
 
set_figure(x,top);
 
for (int i = 0; i < (n*n); i++)
 
if (a[i] == 0)
 
step(top,i,st + 1);
 
}
 
else[[:File:Шахматы.rar]]
 
{
 
set_figure(x,top);
 
                cout << endl;
 
for (int i = 0; i < (n*n); i++)
 
{
 
cout.width(3);
 
if (((i % n) == 0) && (i != 0))
 
cout << endl;
 
if (a[i] == -1)
 
cout << 1;
 
else
 
cout << 0;
 
}
 
cout << endl;
 
}
 
break;
 
}
 
case 2:
 
{
 
set_figure(x,top);
 
if ((st+1) > maxst)
 
maxst = st + 1;
 
for (int i = 0; i < (n*n); i++)
 
if (a[i] == 0)
 
step(top,i,st+1);
 
break;
 
}
 
}
 
  
 +
'''[[Васильева Анастасия]]'''
  
 +
'''Краткое описание алгоритма''': Доска представлена в виде динамического массива, по ходу программы, в зависимости от алгоритмов для разных фигур, функции заполняют доску числами  0-место свободно, 1-находится под ударом и 2-занято фигурой, потом массив преобразовывается к нормальному виду 0 и 1-фигура. Так программа прогоняет все возможные варианты расстановок. Также программа аналитически просчитывает максимальное количество фигур для каждого размера доски.
  
// обратный ход
+
'''Инструкция''': Сначала программа просит выбрать фигуру, с которой будем работать. Затем 2 варианта развития событий: 1 - вывод в файл всех расстановок, 2 - максимальное количество фигур. В зависимости от выбора, в первом случае еще нужно ввести количество фигур, и программа запишет в файл все возможные варианты и выведет на экран число расстановок, а во втором - на экране появится максимальное кол-во фигур.
    for (int i = xtop; i < top; i++)
+
Скачать можно [http://tm.spbstu.ru/Файл:Задача1.zip тут].
    {
 
        if ((a[stak[i]] != -1) && (a[stak[i]] != -2))
 
            a[stak[i]]--;
 
        else
 
            //не забываем отметить,что фигура уже здесь стояла(чтобы избежать повторов)
 
            if (a[stak[i]] == -1)
 
                a[stak[i]] = -2;
 
//       cerr << " Back "  << stak[i] << endl;
 
    }
 
}
 
  
int main()
+
'''[[Тимошенко Валентина]]'''
{
 
  
    //cin >> n >> type >> variant;
+
'''Краткое описание алгоритма''': доска представлена в виде динамического массива, при выводе на экран пустые клетки обозначаются точками, а клетки, заполненные фигурами, обозначаются буквами (каждая буква соответствует первой букве названия фигуры на английском языке). Для каждой фигуры написаны функции проверки на возможность установки фигуры и функции расстановки. Кроме того, программа аналитически считает максимальное количество фигур для доски заданного пользователем размера и, при наличии команды пользователя, выводит все возможные расстановки рассчитанного максимального количества фигур на экран.
    n = 5;
 
    type = 4;
 
variant = 1;
 
    a    = new int[n*n];
 
    stak = new int[n*n*4];
 
  
    for (int i = 0; i < (n*n); i++)
+
'''Инструкция''': при запуске программа предлагает пользователю ввести размер доски, при этом число должно быть четным (если же пользователь вводит нечетное число, программа предлагает ввести размер еще раз, и так до тех пор, пока не будет введено четное число). Далее пользователь выбирает режим работы программы - либо расстановка фигур, либо расчет максимального количества фигур. В режиме расстановки фигур программа предлагает выбрать тип фигуры, выводит максимальное число фигур для доски заданного размера и предлагает ввести желаемое число фигур для расстановки (если оно больше максимального, предлагается повторная попытка ввода). В режиме расчета максимального числа программа предлагает выбрать тип фигуры, выводит рассчитанное число и задает вопрос о необходимости вывода всех возможных расстановок максимального количества для данной фигуры. Оба режима работают (т.е. все запросы повторяются) до тех пор, пока пользователь не даст команду на завершение цикла. Кроме того, в программе есть возможность изменения размера доски после выхода из всех циклов. При положительном ответе пользователя и изменении размера доступны оба режима работы.
    {
 
        for (int j = 0; j < (n*n); j++)
 
            a[j] = 0;
 
        if (variant == 1)
 
            cout << "__________________________________" << endl;
 
        step(0,i,0);
 
    }
 
if (variant == 2)
 
  cout << maxst;
 
    return 0;
 
}
 
</syntaxhighlight>
 
</div>
 
  
'''[[Лобанов Илья]]'''
+
Скачать можно  [http://tm.spbstu.ru/Файл:Chessboard.zip здесь].
  
'''Описание алгоритма''':
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
  
Программа проверяет возможность расстановки фигур на доске M*M . При выводе на экран на экран клетки,занятые фигурами ,помечаются буквами,соответствующими первой букве типа фигуры. Также программа считает максимальное число фигур определенного типа,которые можно расставить на доске.
+
#include <iostream> ///расстановка одинаковых шахматных фигур одного цвета на доске произвольного размера так, чтобы они друг друга не били
 +
#include <cstring>
 +
#include <cstdlib>
 +
#include <ctime>
  
'''Инструкция''':
+
using namespace std;
 +
int result_count = 0; ///переменная, в которую закладывается номер варианта расстановки фигур
 +
int N; ///то количество фигур для расстановки, которое задает пользователь
 +
int **Board; ///двумерный массив для отображения шахматной доски
 +
int M; /// размер шахматной доски
  
В окне консоли пользователю предлагается выбрать 2 типа работы программы, затем пользователь вводит размер доски(четный),тип и количество фигур,которые необходимо разместить на доске.В зависимости от режима работы программы ,будет выведено либо максимально возможное число расстановок фигур,либо максимальное число фигур.
+
///Функция вывода доски
Скачать можно [[http://tm.spbstu.ru/File:ConsoleApplication54.rar тут]]
+
void showBoard(string F) ///данная функция отображает доску
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
{
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    for(int i = 0; i < M; ++i) /// цикл, прогоняющий значения по строкам
#include <iostream>
+
    {
#include <windows.h>
+
        for(int j = 0; j < M; ++j)  /// цикл, прогоняющий значения по столбцам
using namespace std;
+
            cout << ((Board[i][j]) ? F : "."); ///заполнение как строки, так и столбца символом, который обозначает позицию на шахматной доске
 +
        cout << endl;                          ///точка - если данная клетка пустая, буква - если в клетке стоит соответствующая фигура
 +
    }
 +
    cout << "Result # " << ++result_count << "\n\n"; ///вывод номера варианта расположения с последующим переходом на новую строку
 +
    return;
 +
}
  
enum type{peshka, king, kon, ladya, slon, queen}; // все возможные типы фигур
+
///Функции проверки и установки для ферзя
const char symbols[] = "pKklsQ"; // буквенное обозначение каждой фигуры:p - пешка, K - король, k - конь, l- ладья, s - слон, Q - ферзь
 
const int NONE = INT_MAX;//константа для обозначения пустой клетки
 
int M, **desk, *colons, *rows, *diag_1, *diag_2;
 
  
// структура для описания клектки доски
+
bool tryQueen(int a, int b) /// проверка на возможность поставить фигуру в данную клетку, a- очередная строка, b- очередной столбец
struct point
 
 
{
 
{
int x, y;
+
    for (int i = 0; i < M; ++i) ///проверка единственности ферзя в строке
point(int x = 0, int y = 0): x(x), y(y) {}
+
    {
point &operator++()
+
        if(Board[a][i])
{
+
            return false;
if (y == M - 1)
+
    }
{
+
 
++x;
+
    for(int i = 0; i < M; ++i) ///проверка единственности ферзя в столбце
y = 0;
+
    {
}
+
        if(Board[i][b])
else
+
            return false;
++y;
+
    }
return *this;
 
}
 
point operator+(const point &p) const
 
{
 
return point(x + p.x, y + p.y);
 
}
 
point next() const
 
{
 
point r = *this;
 
return ++r;
 
}
 
};
 
  
 +
    for(int i = 1; a-i >= 0 && b-i >= 0; ++i)///проверка единственности ферзя по диагонали влево-вверх
 +
    {
 +
        if(Board[a-i][b-i])
 +
            return false;
 +
    }
  
int *new_array(int n)
+
    for(int i = 1; a+i < M && b+i < M; ++i)///проверка единственности ферзя по диагонали вправо-вниз
{
+
    {
int *a = new int[n];
+
        if(Board[a+i][b+i])
fill(a, a + n, NONE);
+
            return false;
return a;
+
    }
}
 
  
// Количество свободных клеток от клетки p до конца доски
+
    for(int i = 1; a+i < M && b-i >= 0; ++i)///проверка единственности ферзя по диагонали влево-вниз
int rest(const point &p, type t)
+
    {
{
+
        if(Board[a+i][b-i])
int r0 = (M - p.x) * M - p.y, r,
+
            return false;
m = M - p.x,
+
    }
s_2 = (m + 1) / 2 * M;
+
 
switch (t)
+
    for(int i = 1; a-i >= 0 && b+i < M; ++i)///проверка единственности ферзя по диагонали вправо-вверх
{
+
    {
case peshka:
+
        if(Board[a-i][b+i])
case kon:
+
            return false;
r = s_2; break;
+
    }
case king:
 
r = s_2 / 2; break;
 
case ladya:
 
case queen:
 
return m;
 
case slon:
 
r = m + M - 1;
 
}
 
return min(r0, r);
 
}
 
  
// Помечает клетку доски номером i
+
    return true; ///если в ходе проверки ферзей и угроз не обнаружилось, в данную клетку можно поставить фигуру
void set(const point &p, type t, int i)
 
{
 
if (t == peshka || t == king || t == kon)
 
desk[p.x][p.y] = i;
 
else
 
{
 
if (t == ladya || t == queen)
 
colons[p.y] = rows[p.x] = i;
 
if (t == slon || t == queen)
 
diag_1[p.x+p.y] = diag_2[p.x-p.y+M-1] = i;
 
}
 
 
}
 
}
  
// Можно ли поставить фигуру номер i на клетку p
+
void setQueen(int a, int count) ///функция расстановки ферзей; a - очередная строка, count - счетчик количества фигур, которое необходимо расставить
bool empty(const point &p, type t, int i)
 
 
{
 
{
const int n_attack[3] = {4, 8, 8};
+
    for(int b = 0; b < M; ++b) ///b - очередной столбец, расстановка идет по строкам
const point attack[3][8] = {{point(1, 1), point(1, -1), point(-1, 1), point(-1, -1)}, //кол-во вариантов атаки для пешки
+
    {
{point(1, 1), point(1, -1), point(-1, 1), point(-1, -1), point(1, 0), point(-1, 0), point(0, 1), point(0, -1)}, // кол-во вариантов атаки для короля
+
        if(tryQueen(a, b)) ///проверка данной клетки на возможность установки фигуры
{point(1, 2),point(-1, 2),point(1, -2), point (-1,-2), point (2, 1), point (2,-1), point (-2, 1),point (-2,-1)}}; //количество вариантов атаки для коня
+
        {
switch(t)
+
            Board[a][b] = 1; ///установка ферзя в первую клетку поля, присваивание ей значения 1 (true)
{
+
 
case peshka:
+
            for(int i = a + 1; i < M; ++i) ///расстановка указанного пользователем количества фигур
case king:
+
                setQueen(i,count+1);
case kon:
+
 
for (int k = 0; k < n_attack[t]; k++)
+
            if(count+1 == N) /// если нужное количество фигур поставлено, то
{
+
                showBoard("Q"); /// вызов функции вывода шахматной доски на экран
point q = p + attack[t][k];
+
 
if (q.x >= 0 && q.x < M && q.y >= 0 && q.y < M && desk[q.x][q.y] < i)
+
            Board[a][b]=0; ///обнуление переменной для установки следующей фигуры в следующую клетку
return false;
+
        }
}
+
    }
return true;
 
case ladya:
 
return colons[p.y] > i && rows[p.x] > i;
 
case slon:
 
return diag_1[p.x+p.y] > i && diag_2[p.x-p.y+M-1] > i;
 
case queen:
 
return colons[p.y] > i && rows[p.x] > i && diag_1[p.x+p.y] > i && diag_2[p.x-p.y+M-1] > i;
 
}
 
 
}
 
}
  
//печатает заданное количество досок на экране
+
///Функции проверки и установки для ладьи
void print(point **figures, int n_desks, int N, type t, ostream &out = cout)
+
 
 +
bool tryRook(int a, int b) /// проверка на возможность поставить фигуру в данную клетку, a- очередная строка, b- очередной столбец
 
{
 
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
+
    for (int i = 0; i < M; ++i) ///проверка единственности ладьи в строке
for (int n = 0; n < n_desks; n++)
+
    {
{
+
        if(Board[a][i])
out << " \xdb";
+
            return false;
for (int i = 0; i < M * 2 + 2; i++)
+
    }
out << "\xdf";
 
out << "\xdb";
 
}
 
out << endl;
 
  
int *K = new int[n_desks];
+
    for(int i = 0; i < M; ++i) ///проверка единственности ладьи в столбце
fill(K, K + n_desks, 0);
+
    {
for (int i = 0; i < M; i++)
+
        if(Board[i][b])
{
+
            return false;
for (int n = 0; n < n_desks; n++)
+
    }
{
 
int &k = K[n];
 
out << " \xdb ";
 
for (int j = 0; j < M; j++)
 
{
 
SetConsoleTextAttribute(hConsole, (i + j) % 2 == 0 ? 0xf0 : 0xf);
 
if (k < N && i == figures[n][k].x && j == figures[n][k].y)
 
{
 
out << ' ' << symbols[t];
 
k++;
 
}
 
else
 
out << "  ";
 
}
 
SetConsoleTextAttribute(hConsole, 0x70);
 
out << " \xdb";
 
}
 
out << endl;
 
}
 
delete[] K;
 
  
for (int n = 0; n < n_desks; n++)
+
    return true; ///если в ходе проверки ладей и угроз не обнаружилось, в данную клетку можно поставить фигуру
{
 
out << " \xdb";
 
for (int i = 0; i < M * 2 + 2; i++)
 
out << "\xdc";
 
out << "\xdb";
 
}
 
out << endl << endl;
 
 
}
 
}
  
// Вывести все возможные расположения на доске N фигур
+
void setRook(int a, int count) ///функция расстановки ладей; a - очередная строка, count - счетчик количества фигур, которое необходимо расставить
void all_placements(int N, type t)
 
 
{
 
{
desk = NULL;
+
    for(int b = 0; b < M; ++b) ///b - очередной столбец, расстановка идет по строкам
colons = rows = diag_1 = diag_2 = NULL;
+
    {
// создание необходимых массивов, отмечающих занятость клеток, в зависимости от вида фигуры
+
        if(tryRook(a, b)) ///проверка данной клетки на возможность установки фигуры
if (t == peshka || t == king || t == kon)
+
        {
{
+
            Board[a][b] = 1; ///установка ладьи в первую клетку, присваивание ей значения 1 (true)
desk = new int*[M];
+
 
for (int j = 0; j < M; j++)
+
            for(int i = a + 1; i < M; ++i) ///расстановка указанного пользователем количества фигур
desk[j] = new_array(M);
+
                setRook(i,count+1);
}
+
 
else
+
            if(count+1 == N) /// если нужное количество фигур поставлено, то
{
+
                showBoard("R"); /// вызов функции вывода шахматной доски на экран
if (t == ladya || t == queen)
 
{
 
colons = new_array(M);
 
rows = new_array(M);
 
}
 
if (t == slon || t == queen)
 
{
 
diag_1 = new_array(2*M-1);
 
diag_2 = new_array(2*M-1);
 
}
 
}
 
 
const int W = 80 / (2 * M + 5);//количество досок,помещающихся на экране
 
point **figures = new point*[W];//массив фигур
 
for (int j = 0; j < W; j++)
 
figures[j] = new point[N];
 
  
int i = 0, // номер фигуры
+
            Board[a][b]=0; ///обнуление переменной для установки следующей фигуры в следующую клетку
k = 0; //номер комбинации
+
        }
while (true)
+
    }
{
+
}
if (rest(figures[k%W][i], t) < N - i) // если оставшиеся фигуры не помещаются на доске
+
 
{
+
///Функции проверки и установки для слона
if (i == 0) // если все комбинации закончились
 
{
 
// вывод оставшихся досок
 
if (k % W)
 
print(figures, k % W, N, t);
 
cout << "Amount of combinations: " << k << endl;
 
break;
 
}
 
// переходим к предыдущей фигуре и помечаем клетку пустой
 
set(figures[k%W][--i], t, NONE);
 
// сдвигаем фигуру на шаг вперёд
 
++figures[k%W][i];
 
}
 
else if (!empty(figures[k%W][i], t, i)) // если фигуры помещаются, но текущая клетка под ударом
 
// сдвигаем текущую фигуру на шаг вперёд
 
++figures[k%W][i];
 
else if (i == N - 1) // если ставим последнюю фигуру
 
{
 
// если текущая доска - последняя на строке экрана, выводим W досок
 
if ((k + 1) % W == 0)
 
print(figures, W, N, t);
 
// копирование комбинаций фигур на следующую доску
 
for (int j = 0; j < N; j++)
 
figures[(k+1)%W][j] = figures[k%W][j];
 
// переход к следующей доске
 
k++;
 
//сдвигаем текущую фигуру на шаг вперёд
 
++figures[k%W][i];
 
}
 
else // если ставим не последнюю фигуру
 
{
 
// помечаем текущую клетку номером i
 
set(figures[k%W][i], t, i);
 
//ставим следующую фигуру на клетку после текущей
 
figures[k%W][i+1] = figures[k%W][i].next();
 
// переходим к следующей фигуре
 
i++;
 
}
 
}
 
  
//освобождение памяти
+
bool tryEl(int a, int b) /// проверка на возможность поставить фигуру в данную клетку, a- очередная строка, b- очередной столбец
for (int j = 0; j < W; j++)
+
{
delete[] figures[j];
+
    for(int i = 1; a-i >= 0 && b-i >= 0; ++i)///проверка единственности слона по диагонали влево-вверх
delete[] figures;
+
    {
if (desk)
+
        if(Board[a-i][b-i])
{
+
            return false;
for (int j = 0; j < M; j++)
+
    }
delete[] desk[j];
+
 
delete[] desk;
+
    for(int i = 1; a+i < M && b+i < M; ++i)///проверка единственности слона по диагонали вправо-вниз
}
+
    {
if (colons)
+
        if(Board[a+i][b+i])
{
+
            return false;
delete[] colons;
+
    }
delete[] rows;
 
}
 
if (diag_1)
 
{
 
delete[] diag_1;
 
delete[] diag_2;
 
}
 
}
 
  
 +
    for(int i = 1; a+i < M && b-i >= 0; ++i)///проверка единственности слона по диагонали влево-вниз
 +
    {
 +
        if(Board[a+i][b-i])
 +
            return false;
 +
    }
  
int main()
+
    for(int i = 1; a-i >= 0 && b+i < M; ++i)///проверка единственности слона по диагонали вправо-вверх
{
+
    {
system("color 70"); // Установка серого фона и чёрного текста
+
        if(Board[a-i][b+i])
while (true)
+
            return false;
{
+
    }
cout << "Choose the mode:\n1 - all possible variants of figures' placement\n2 - maximum number of figures which can be placed on the desk\nq - quit\n\n";
+
 
char c;
+
    return true; ///если в ходе проверки слонов и угроз не обнаружилось, в данную клетку можно поставить фигуру
cin >> c;
+
}
cin.ignore(100, '\n');
+
void setEl(int dia, int count) ///функция расстановки слонов; line - очередная строка, count - счетчик количества фигур, которое необходимо расставить
switch (c)
+
{
{
+
    ///dia - очередная диагональ, которую нужно исследовать на наличие фигуры и угрозы
case '1':
+
    int a, b; ///клетка, с которой начинается расстановка, a- очередная строка, b- очередной столбец
case '2':
+
 
cout << "Enter the desk size please. (The number must be even and not more than 37.)\n";
+
    if (dia < M) ///условие, что клеткa данной диагонали лежат на доске
cin >> M;
+
    {
while (!cin || M % 2 != 0 || M > 37 || M <= 0)
+
        a = dia; ///начало отсчёта диагоналей, цикл движется по строке
{
+
        b = 0; ///обнуление переменной для столбца, цикл движется по столбцу
cout << "Error: wrong desk size. Try again please.\n";
+
    }
cin.clear();
+
  else ///если клеткa данной диагонали выходит за размер доски (когда цикл по строке доберется до конца
cin.ignore(100, '\n');
+
    {
cin >> M;
+
        a = M-1; ///самая последняя диагональ
}
+
        b =(dia % M)+1; ///соответственно расчёт переменной для столбца этой диагонали
cin.ignore(100, '\n');
+
    }
cout << "Choose a figure, please.\n p - peshka, k - kon, l - ladya, s - slon, Q - Queen, K - King\n";
+
 
char f;
+
    for(int i=0; a-i>=0 && b+i < M; ++i)/// цикл движется по строкам и столбцам снизу слева вправо вверх
cin >> f;
+
    {
cin.ignore(100, '\n');
+
        int line = a-i; ///строковая координата данной клетки диагонали
type t;
+
        int column = b+i; ///столбцовая координата данной клетки диагонали
int i;
+
 
do
+
        if(tryEl(line, column))/// проверка на единственность слона по диагоналям
{
+
        {
for (i = 0; i < 6; i++)
+
            Board[line][column]=1; ///установка слона в первую клетку, присваивание ей значения 1 (true)
{
+
 
if (symbols[i] == f)
+
            for(int i = dia + 1; i<2*M-1; ++i) ///расстановка указанного пользователем количества фигур
{
+
                setEl(i,count+1);
t = type(i);
+
 
break;
+
            if(count+1 == N) /// если нужное количество фигур поставлено, то
}
+
                showBoard("E"); /// вызов функции вывода шахматной доски на экран
}
+
 
if (i == 6)
+
            Board[line][column]=0; ///обнуление переменной для установки следующей фигуры в следующую клетку
{
+
        }
cout << "Enter the right letter, you've chosen the wrong one.\n";
+
    }
cin >> f;
+
}
cin.ignore(100, '\n');
+
 
}
+
///Функции проверки и установки для коня
} while (i == 6);
+
 
if (c == '1')
+
bool tryHorse(int a, int b) /// проверка на возможность поставить фигуру в данную клетку, a- очередная строка, b- очередной столбец
{
+
{
cout << "Enter the number of figures please.\n";
+
    ///проверка на наличие фигур и угроз во всех 8 точках, которые могут быть под ударом в квадрате 5х5 вокруг установленной фигуры
int N;
 
cin >> N;
 
while (!cin || N <= 0)
 
{
 
cout << "Error: wrong argument. Try again please.\n";
 
cin.clear();
 
cin.ignore(100, '\n');
 
cin >> N;
 
}
 
cin.ignore(100, '\n');
 
all_placements(N, t);
 
}
 
else
 
{
 
cout << "The maximal number of figures is ";
 
switch (t)
 
{
 
case peshka:
 
cout << M*M/2; break;
 
case king:
 
cout << M*M/4; break;
 
case kon:
 
cout << (M == 2 ? 4 : M*M/2); break;
 
case ladya:
 
cout << M; break;
 
case slon:
 
cout << 2*M - 2; break;
 
case queen:
 
cout << (M == 2 ? 1 : M);
 
}
 
cout << ".\n";
 
}
 
break;
 
case 'q':
 
cout << endl;
 
return 0;
 
default:
 
cout << "You've chosen the wrong command, try again please.\n";
 
}
 
cout << endl << endl;
 
}
 
}
 
</syntaxhighlight>
 
</div>
 
  
'''[[Лосева Татьяна]]'''
+
    if ((a-1) >=0 && (b-2)>=0 && Board[a-1][b-2])
 +
        return false;
  
'''Краткое описание алгоритма :'''
+
    if ((a-1)>=0 && (b+2) < M && Board[a-1][b+2])
Доска представлена в виде динамического массива;Для каждой фигуры написана отдельная функция проверки на возможность установки фигуры,проверяющая, находится ли эта фигура под ударом других.
+
        return false;
После выбора типа фигуры,используется  рекурсивная функция,которая проверяет возможные  расстановки через данную функцию проверки ,для данного типа фигуры.
 
Для поиска максимального значения мы проверяем расстановку начиная с 0 количество фигур ,каждый раз увеличивая на 1,если количество расстановок станет равно нулю,то предыдущее количество фигур было максимальным.
 
  
'''Инструкция''' : Пользователя попросят ввести размер доски,затем выбрать один из вариантов работы программы:1.поиск возможных расстановок для M фигур или 2.поиск максимального количества расстановок для данного поля,затем попросят выбрать тип фигуры и в первом случае количество фигур.При выводе на экран выводится номер расстановки и доска,на доске F- обозначены занятые клетки,0-пуская клетка.
+
    if ((a+1) < M && (b-2) >=0 && Board[a+1][b-2])
Для 2 пункта выводится лишь число: максимальное количество фигур,которое можно расставить.
+
        return false;
  
Скачать можно : [http://tm.spbstu.ru/Файл:Шахматы_Лосева.rar тут]
+
    if ((a+1) < M && (b+2) < M && Board[a+1][b+2])
 +
        return false;
  
 +
    if ((a-2) >=0 && (b-1) >=0 && Board[a-2][b-1])
 +
        return false;
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
    if ((a-2) >=0 && (b+1) < M && Board[a-2][b+1])
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
        return false;
#include<iostream>
 
using namespace std;
 
int N;//размер доски NxN
 
int **a;
 
int *ax;
 
int *by;
 
int l = 0;//L-номер пункта в меню
 
int M;//количество фигур
 
bool isPrint = false;//переменная для вывода на экран,когда требуется,для удобства обозначим в начале false
 
  
 +
    if ((a+2) < M && (b-1) >= 0 && Board[a+2][b-1])
 +
        return false;
  
void print()//функция вывода на экран
+
    if ((a+2) < M && (b+1) < M && Board[a+2][b+1])
{
+
        return false;
for (int i = N - 1; i >= 0; --i)
 
{
 
for (int j = 0; j < N; ++j)
 
{
 
cout << ((a[j][i]) ? "F " : "0 ");//если (a[j][i]) истина,то есть клетка занята,ставим F,в другом случае,т.е.свободна,ставим 0
 
}
 
cout << '\n';
 
}
 
cout << '\n';
 
  
 +
    return true; ///если в ходе проверки коней и угроз не обнаружилось, в данную клетку можно поставить фигуру
 
}
 
}
bool Lad(int x, int y)//Ладья
+
 
 +
void setHorse(int count, int a, int b) ///функция расстановки коней; a - очередная строка, b - очередной столбец, count - счетчик количества фигур, которое необходимо расставить
 
{
 
{
for (int i = 0; i < N; ++i)
+
    if(count==N) /// если нужное количество фигур поставлено, то
{
+
    {
if (a[i][y] == 1 )//проверяем горизонталь:если клетка занята
+
        showBoard("H"); /// вызов функции вывода шахматной доски на экран
{
+
    }
return false;//возвращаем false
 
}
 
if (a[x][i] == 1)//проверяем вертикаль : если хотя бы одна клетка занята,то
 
{
 
return false;//возврашаем false
 
}
 
}
 
return true;//ничего выше не выполняется,значит возвращаем правду:вертикаль и горизонталь свободна
 
  
}
+
    if (a == M) ///условие необходимо; прогоняет алгоритм по всем строкам
 +
        return;
  
bool Kon(int x, int y)//Коняша
+
    for (int j=b; j<M; ++j) ///установка коней в первой строке
{
+
    {
int i[8] = {-2, -2, -1, -1, 1, 1, 2, 2};//координаты клеток,на которые может ходить конь,относительно текущей (8 вариантов)
+
        if(tryHorse(a, j)) ///проверка данной клетки на возможность установки фигуры
int j[8] = {-1, 1, -2, 2, -2, 2, -1, 1};
+
        {
+
            Board[a][j]=1; ///установка коня в первую клетку, присваивание ей значения 1 (true)
for (int k = 0; k < 8; k++)//8 вариантов хода
+
            int line = a, b = j+1; ///смещение в строке на одну позицию вправо, переобозначение строки на line
 
{
 
if (x + i[k] >= 0 && x + i[k] < N && y + j[k] >= 0 && y + j[k] < N)//проверка выхода за границы массива
 
{
 
if (a[x + i[k]][y + j[k]] != 0)//клетка занята
 
{
 
return false;//возвращем false
 
}
 
}
 
}
 
return true;////ничего выше не выполняется,значит возвращаем правду:все варианты ходов  свободны и конь никого не перебивает,тогда можно занять клетку
 
 
 
}
 
  
 +
            if (b == M) ///если данный столбец - самый крайний
 +
            {
 +
                b = 0; ///обнуление переменной, чтобы использовать ее при заполнении следующей строки
 +
                line++;    ///то переход на следующую строку и дальнейшее ее заполнение
 +
            }
 +
            setHorse(count+1,line,b); ///установка фигуры, увеличение счетчика
 +
            Board[a][j]=0; ///обнуление переменной для установки следующей фигуры в следующую клетку
 +
        }
 +
    }
  
 +
    for(int i=a+1; i<M; ++i) ///дальнейшее заполнение оставшихся строк
 +
    {
 +
        for (int j=0; j<M; ++j)
 +
        {
 +
            if(tryHorse(i, j)) ///проверка данной клетки на возможность установки фигуры
 +
            {
 +
                Board[i][j]=1; ///установка коня в первую клетку, присваивание ей значения 1 (true)
 +
                int line = i, b = j+1; ///смещение в строке на одну позицию вправо
  
 +
                if (b == M) ///если данный столбец - самый крайний
 +
                {
 +
                    b = 0;
 +
                    line++;  ///то переход на следующую строку и дальнейшее ее заполнение
 +
                }
 +
                setHorse(count+1,line,b); ///установка фигуры, увеличение счетчика
 +
                Board[i][j]=0;  ///обнуление переменной для установки следующей фигуры в следующую клетку
 +
            }
 +
        }
 +
    }
 +
}
  
bool Korol(int x, int y)//Король
+
///для короля
{
 
  
int i[8] = { -1, -1, -1, 0, 0, 1, 1, 1 };//координаты клеток,на которые может ходить король,относительно текущей
+
bool tryKing(int a, int b) /// проверка на возможность поставить фигуру в квадрате 3х3, a- очередная строка, b- очередной столбец
    int j[8] = { -1, 0, 1, -1, 1, -1, 0, 1 };
+
{
 +
///проверка на наличие фигур и угроз во всех 8 точках, которые могут быть под ударом в квадрате 3х3 вокруг установленной фигуры
  
for(int k = 0; k < 8; k++)//8 вариантов хода
+
    for(int i = a-1; i <= a+1; ++i) ///проверка по строкам
{
+
    {
if (x + i[k] >= 0 && x + i[k] < N && y + j[k] >= 0 && y + j[k] < N)//прроверяем не выходит ли фигура за границы массива
+
        for(int j = b-1; j <= b+1; ++j) ///проверка по столбцам
{
+
        {
if (a[x + i[k]][y + j[k]] != 0)//если какой нибудь из вариантов хода занят
+
            if (a>=0 && a < M && b>=0 && b < M && Board[a][b]) ///условие наличия клетки в пределах доски
{
+
                return false;
return false;//то false
+
 
}
+
            if ((a+1) < M && (b-1) >=0 && Board[a+1][b-1])
}
+
                return false;
}
+
 
return true;//свободно,можно занимать
+
            if ((a+1) < M && Board[a+1][b])
 +
                return false;
 +
 
 +
            if ((a+1) < M && (b+1) < M && Board[a+1][b+1])
 +
                return false;
 +
 
 +
            if ((b+1) < M && Board[a][b+1])
 +
                return false;
 +
 
 +
            if ((a-1)>=0 && (b+1) < M && Board[a-1][b+1])
 +
                return false;
 +
 
 +
            if ((a-1) >=0 && Board[a-1][b])
 +
                return false;
 +
 
 +
            if ((a-1) >=0 && (b-1)>=0 && Board[a-1][b-1])
 +
                return false;
 +
 
 +
            if ((b-1) >= 0 && Board[a][b-1])
 +
                return false;
 +
        }
 +
    }
 +
 
 +
    return true; ///если в ходе проверки королей и угроз не обнаружилось, в данную клетку можно поставить фигуру
 
}
 
}
  
bool Slon(int x, int y)
+
void setKing (int count, int a, int b) ///функция расстановки коней; a - очередная строка, b - очередной столбец, count -  счетчик количества фигур, которое необходимо расставить
 
{
 
{
int p1 = y - x;//номер диагонали слева направо
+
    for (int j=b; j<M; ++j)  ///установка королей в первой строке
int p2 = y + x;//номер диагонали с права налево
+
    {
for (int i = 0; i < N; i++)//проверяем левую диагональ
+
        if(tryKing(a, j)) ///проверка данной клетки на возможность установки фигуры
{
+
        {
if (i + p1 >= 0 && i + p1 < N)//проверка на выход за границы массива
+
            Board[a][j]=1; ///проверка данной клетки на возможность установки фигуры
{
+
            setKing(count+1,a,j); ///расстановка фигур в первой строке
if (a[i][i + p1] == 1) //проверяем диагональ
+
            Board[a][j]=0;  ///обнуление переменной для установки следующей фигуры в следующую клетку
{
+
        }
return false;//диагональ занята
+
    }
}
+
 
}
+
    for(int i=a+1; i<M; ++i) ///установка фигур в оставшуюся часть шахматной доски по строкам
if (-i + p2 >= 0 && -i + p2 < N)//вторая диагональ
+
    {
{
+
        for (int j=0; j<M; ++j)
if (a[i][-i + p2] == 1)  
+
        {
{
+
            if(tryKing(i, j)) ///проверка данной клетки на возможность установки фигуры
return false;//вторая диагональ занята
+
            {
}
+
                Board[i][j]=1; ///проверка данной клетки на возможность установки фигуры
}
+
                setKing(count+1,i,j); ///расстановка фигур
}
+
                Board[i][j]=0; ///обнуление переменной для установки следующей фигуры в следующую клетку
return true;//обе диагонали свободны,ура!
+
            }
 +
        }
 +
    }
 +
 
 +
    if(count==N) /// если нужное количество фигур поставлено, то
 +
    {
 +
        showBoard("K");/// вызов функции вывода шахматной доски на экран
 +
        return;
 +
    }
 
}
 
}
  
bool Check(int x, int y)//Ферзь=Ладья+Слон
+
int main()
 
{
 
{
int p1 = y - x;//диагональ 1
+
    char s; ///переменная, будет использована в цикле
int p2 = y + x;//диагональ 2
+
    do      /// цикл, выводящий на экран данные в зависимости от введенных пользователем значений переменных
for (int i = 0; i < N; ++i)
+
    {
{
+
        do ///цикл для считывания введенного пользователем размера доски
if (a[i][y] == 1 )//проверяем горизонталь
+
        {
{
+
            cout << "Input the size of the board: " << endl; ///ввод размера доски
return false;//занято
+
            cin >> M;
}
 
if (a[x][i] == 1)//проверяем вертикаль
 
{
 
return false;//занято
 
}
 
 
if (i + p1 >= 0 && i + p1 < N)//выход за границы массива
 
{
 
if (a[i][i + p1] == 1) //проверяем 1 диагональ
 
{
 
return false;//занято
 
}
 
}
 
if (-i + p2 >= 0 && -i + p2 < N)//выход за границы массива
 
{
 
if (a[i][-i + p2] == 1)//проверяем 2ую диагональ
 
{
 
return false;//занято
 
}
 
}
 
}
 
return true;//свободно!
 
}
 
  
int  menu1()
+
            if ( (M%2) == 1) ///цикл, работающий только в том случае, если пользователь введет нечетное число
{
+
            {
cout << "Type of figure:" << endl << "1 - Ferz" << endl << "2 - Ladya" << endl << "3 - Slon" << endl << "4 - Kon" << endl << "5 - Korol" << endl;
+
                cout << '\n' << "The number must be even, so try to input the size again" << '\n' << endl;
cin >> l;
+
            }
return l;
 
}
 
  
int num = 0;//номер расстановки
+
        }
//пробует найти результаты решений.
+
        while (M%2 !=0); ///пока пользователь не введет допуcтимое число, цикл не прерывается
  
void Func(int d,int K) //d-глубина рекурсии;K-сколько фигур нужно расставить
+
        Board = new int*[M];  ///создание двумерного массива для отображения шахматной доски
{
+
        for (int i = 0; i<M; i++)
if (d == K)//когда расставили нужное количество
+
            Board[i] = new int[M]; ///создание первую строку доски
{
+
        for (int i = 0; i<M; i++)
if (isPrint)//если true,то печатаем(в случае с MAX количеством доску печатать не нужно)
+
            for (int j = 0; j<M; j++)
{
+
                Board[i][j] = 0; ///зануление массива
cout << "Result: " << num + 1 << '\n';//выводим нормер расстановки
 
print();//печатаем доску
 
}
 
num++;//номер расстановки увеличивается
 
return;
 
}
 
  
int minX = d != 0 ? ax[d - 1] : 0;//исходя из того куда быда поставлена предыдущая фигура
+
        int V; ///пользователь выбирает один из двух вариантов работы программы
//,накладываются ограничения для выбора места новой,чтобы избежать поторений
+
        cout << '\n' << "Input your choice: 1=placing of figures, 2=for max amount of figures" << endl;
int minY = d != 0 ? by[d - 1] + 1 : 0;
+
        cin >> V;
  
 +
        if (V==1) ///цикл, расставляющий фигуры по введенным пользователем данным
 +
        {
 +
            char k; ///переменная, будет использована в цикле
 +
            do      /// цикл, выводящий на экран данные в зависимости от введенных пользователем значений переменных
 +
            {
 +
                int T; ///пользователь выбирает фигуру
 +
                cout << '\n' << "Input type of figure: 1-queen, 2-king, 3-horse, 4-rook, 5-elephant"<< endl;
 +
                cin >> T;
  
bool isPossible = false;//Проверяет,возможно ли занять клетку
+
                int maximum; ///переменная, хранящая максимальное количество фигур, которое можно расставить на заданной доске
for (int i = minX; i < N; ++i)
+
                if (T==1) ///максимальное количество фигур на заданной доске для ферзя
{
+
                {
 
+
                    maximum=M;
for (int j = (i != minX) ? 0 : minY; j < N; ++j)
+
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
{
+
                }
switch (l)//l- номер пункта в меню с фигурами
+
                if (T==2) ///максимальное количество фигур на заданной доске для короля
{
+
                {
case 1://ферзь
+
                    maximum=0.25*M*M;
isPossible = Check(i, j);
+
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
break;
+
                }
case 2://Ладья
+
                if (T==3) ///максимальное количество фигур на заданной доске для коня
isPossible = Lad(i, j);
+
                {
break;
+
                    maximum=0.5*M*M;
case 3://Слон
+
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
+
                }
isPossible = Slon(i, j);
+
                if (T==4) ///максимальное количество фигур на заданной доске для ладьи
break;
+
                {
case 4://Конь
+
                    maximum=M;
isPossible = Kon(i, j);
+
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
break;
+
                }
case 5://Король
+
                if (T==5) ///максимальное количество фигур на заданной доске для слона
isPossible = Korol(i, j);
+
                {
break;
+
                    maximum=2*M-2;
}
+
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
if (isPossible)//если клетку занять возмоно(функция вернула true)
+
                }
{
 
  a[i][j] = 1;//занимаем клетку
 
ax[d] = i;//запоминаем куда была поставлена фигура
 
by[d] = j;//запоминаем куда была поставлена фигура
 
Func(d + 1, K);//вызываем рекурсивно
 
a[i][j] = 0;
 
}
 
}
 
}
 
  
return;
+
                do ///цикл, считывающий количество фигур, заданное пользователем
}
+
                {
 +
                    cout << "Input the amount of figures, it must be less than max amount or equals that" << endl;
 +
                    cin >> N;
 +
                }
 +
                while (N>maximum);  ///пока пользователь не введет допуcтимое число, цикл не прерывается
  
int main()
+
                cout << '\n' << "All possible variants for this amount of figures on this board:" << '\n' << endl;
{
 
  
cout << "Enter size: ";//нужно ввести размер доски
+
                if (T==1) ///цикл, вызывающий на экран все варианты расстановки заданного пользователем числа фигур для ферзя
cin >> N;//считываем размер доски
+
                {
 +
                    result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 +
                    for (int i=0; i <M; ++i)
 +
                        setQueen(i,0);
 +
                }
 +
                if (T==2) ///цикл, вызывающий на экран все варианты расстановки заданного пользователем числа фигур для короля
 +
                {
 +
                    result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 +
                    setKing(0,0,0);
 +
                }
 +
                if (T==3) ///цикл, вызывающий на экран все варианты расстановки заданного пользователем числа фигур для коня
 +
                {
 +
                    result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 +
                    setHorse(0,0,0);
 +
                }
 +
                if (T==4) ///цикл, вызывающий на экран все варианты расстановки заданного пользователем числа фигур для ладьи
 +
                {
 +
                    result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 +
                    for (int i=0; i <M; ++i)
 +
                        setRook(i,0);
 +
                }
 +
                if (T==5) ///цикл, вызывающий на экран все варианты расстановки заданного пользователем числа фигур для слона
 +
                {
 +
                    result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 +
                    for(int i = 0; i<2*M-1; ++i)
 +
                        setEl(i,0);
 +
                }
  
a = new int*[N];//создаём двумерный массив,т.е.нашу доску
+
                cout << '\n' << "If you want continue placing figures, input +, if not, input -" << endl;
for (int i = 0; i < N; i++)
+
                cin >> k;
{
+
            }
a[i] = new int[N];
+
            while (k != '-'); ///цикл работает до тех пор, пока пользователь не даст команду на его завершение
for (int j = 0; j < N; j++)
+
        }
a[i][j] = 0;//заполняем нулями
 
}
 
 
ax = new int[N];//массивы для сохранения координаты каждой фигуры,чтобы избежать повторений
 
by = new int[N];
 
  
int d;//пункт в меню
+
        else if (V==2) ///цикл, вычисляющий максимальное количество фигур по введенным пользователем данным
cout<<"1 - Rasstanovka figur"<<endl<<"2 - MAX znachenie"<<endl;//два варианта работы программы
+
        {
cin>>d;//считываем выбор пользователя
+
            char z; ///переменная, будет использована в цикле
if(d==1)//если выбирает расстановку
+
            do      /// цикл, выводящий на экран данные в зависимости от введенных пользователем значений переменных
{  
+
            {
menu1();//то спрашиваем для какой фигуры
+
                int T; ///переменная для выбора фигуры пользователем
cout<<"How many figures?"<<endl;//и как много будет фигур
+
                cout << '\n' << "Input type of figure: 1-queen, 2-king, 3-horse, 4-rook, 5-elephant"<< endl;
    cin>>M;//считываем количество фигур
+
                cin >> T;
isPrint = true;//в этом случае будем выводить на экран
+
                char d;  ///переменная, будет использована в циклах
Func(0,M);//запуск рекурсивной функции
+
                int maximum; ///переменная, хранящая максимальное количество фигур, которое можно расставить на заданной доске
}
+
                if (T==1) ///максимальное количество фигур на заданной доске для ферзя
 +
                {
 +
                    maximum=M; ///формула расчёта максимального количества фигур для заданной доски
 +
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
 +
                    cout << "If you want to see all locations of max amount, input +, if not, input -" << endl;
 +
                    cin >> d;
 +
                    cout << '\n' << "All possible variants for this amount of figures on this board:" << '\n' << endl;
 +
                    if (d=='+') ///по выбору пользователя вывод всех возможных расстановок для максимального количества для данной фигуры
 +
                    {
 +
                        result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 +
                        N=maximum; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 +
                        for (int i=0; i < M; ++i)
 +
                            setQueen(i,0);
 +
                    }
  
if (d == 2)//случай подсчёта максимального значения
+
                }
{
+
                if (T==2) ///максимальное количество фигур на заданной доске для короля
int n = 0;//изачально max=0
+
                {
menu1();//выбираем фигуру
+
                    maximum=0.25*M*M; ///формула расчёта максимального количества фигур для заданной доски
+
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
do//начало цикла  
+
                    cout << "If you want to see all locations of max amount, input +, if not, input -" << endl;
{
+
                    cin >> d;
num = 0;
+
                    cout << '\n' << "All possible variants for this amount of figures on this board:" << '\n' << endl;
Func(0, ++n);//запускаем каждый раз увеличивая значение фигур и считаем количество расстановок
+
                    if (d=='+') ///по выбору пользователя вывод всех возможных расстановок для максимального количества для данной фигуры
} while (num != 0);//количество вариантов не должно быть равно нулю
+
                    {
cout <<"MAX ="<< n - 1 << endl;//если количество вариантов = 0,то выходим из цикла и предыдущее значение  максимальное
+
                        result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
}
+
                        N=maximum; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
+
                        setKing(0,0,0);
 
+
                    }
int z;
+
                }
cin >> z;
+
                if (T==3) ///максимальное количество фигур на заданной доске для коня
 
+
                {
return 0;
+
                    maximum=0.5*M*M; ///формула расчёта максимального количества фигур для заданной доски
}
+
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
</syntaxhighlight>
+
                    cout << "If you want to see all locations of max amount, input +, if not, input -" << endl;
</div>
+
                    cin >> d;
 
+
                    cout << '\n' << "All possible variants for this amount of figures on this board:" << '\n' << endl;
'''[[Сергей Ляжков]]'''
+
                    if (d=='+') ///по выбору пользователя вывод всех возможных расстановок для максимального количества для данной фигуры
Инструкция:
+
                    {
Вводите необходимые данные(кол-во строк, столбцов, фигуры, тип расстановки) согласно последовательности выполнения программы
+
                        result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
Краткое описание алгоритма:
+
                        N=maximum; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
1)Выделяет память под доску(динамическая матрица)
+
                        setHorse(0,0,0);
2)Устанавливает каждую следующую фигуру на n-е свободное место которое он нашел после последней установленной фигуры, где n изменяется от 1 до бесконечности(установка заканчивается тогда, когда программа не может установить очередную фигуру).
+
                    }
3)Счетчик количества фигур, которые необходимо установить, уменьшается на 1 после каждой установки.
+
                }
4)После того, как фигура установлена, программа рекурсивно вызывает функцию установки очередной фигуры(возвращается в пункт 2)
+
                if (T==4) ///максимальное количество фигур на заданной доске для ладьи
5)В рекурсивную функцию отправляется только копия доски. Таким образом, возвращаясь из рекурсии, мы получаем доску без последующих установленных фигур. Когда счетчик фигур, которые необходимо установить, уменьшается до нуля, данное поле сохраняется в списке.
+
                {
6)Вывод списка.
+
                    maximum=M; ///формула расчёта максимального количества фигур для заданной доски
Скачать можно [http://tm.spbstu.ru/File:Шахматы.zip тут]
+
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
 +
                    cout << "If you want to see all locations of max amount, input +, if not, input -" << endl;
 +
                    cin >> d;
 +
                    cout << '\n' << "All possible variants for this amount of figures on this board:" << '\n' << endl;
 +
                    if (d=='+') ///по выбору пользователя вывод всех возможных расстановок для максимального количества для данной фигуры
 +
                    {
 +
                        result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 +
                        N=maximum; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 +
                        for (int i=0; i <M; ++i)
 +
                            setRook(i,0);
 +
                    }
 +
                }
 +
                if (T==5) ///максимальное количество фигур на заданной доске для слона
 +
                {
 +
                    maximum=2*M-2; ///формула расчёта максимального количества фигур для заданной доски
 +
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
 +
                    cout << "If you want to see all locations of max amount, input +, if not, input -" << endl;
 +
                    cin >> d;
 +
                    cout << '\n' << "All possible variants for this amount of figures on this board:" << '\n' << endl;
 +
                    if (d=='+') ///по выбору пользователя вывод всех возможных расстановок для максимального количества для данной фигуры
 +
                    {
 +
                        result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 +
                        N=maximum; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 +
                        for(int i = 0; i<2*M-1; ++i)
 +
                            setEl(i,0);
 +
                    }
 +
                }
  
<br>'''[[Нарядчиков Александр]]'''<br>
+
                cout << '\n' << "If you want continue counting, input +, if not, input -" << '\n' << endl;
'''Инструкция:''' Запустить программу, следовать указаниям, полученным в меню программы.<br>
+
                cin >> z;
'''Описание программы:''' Шахматное поле представлено в виде двумерного массив N на M, значения N и M пользователь вводит самостоятельно, память выделяется динамически. Также пользователь выбирает тип и количество фигур на поле. В меню можно выбрать между поиском максимально возможного числа фигур на столе и поиском всех расстановок с дальнейшей записью полей в файл.<br>
+
            }
'''Описание алгоритма:''' При поиске всех расстановок происходит установка выбранной фигуры в свободную клетку, далее происходит маркирование тех клеток, в которые уже невозможно поставить фигуру данного типа, затем процесс происходит снова(рекурсия) пока на поле не окажется выбранное пользователем число фигур. Под конец данное поле записывается в файл и происходит поиск других возможных расстановок данного типа. В конце получаем файл со всеми вариантами расстановок и их количеством. При поиске наибольшего числа фигур на доске программа ищет расстановку для одной фигуры, затем для двух, если это возможно и т.д. С каждым разом происходит увеличение счетчика количества фигур на поле, тем самым в конце данного алгоритма мы получаем максимально возможное число данного типа фигур на доске данного размера.<br>
+
            while (z != '-'); ///цикл работает до тех пор, пока пользователь не даст команду на его завершение
 +
        }
 +
        cout << '\n' << "If you want to change the size of board, input +, if not, input -" << endl;
 +
        cin >> s;
 +
        if (s=='-')
 +
        {
 +
            cout << '\n' << "The program is finished." << '\n' << endl; ///вывод на экран сообщения о завершении работы программы
 +
        }
 +
    }
 +
    while (s != '-'); ///цикл работает до тех пор, пока пользователь не даст команду на его завершение, а также на завершение всей программы
 +
}
 +
 
 +
</syntaxhighlight>
 +
</div>
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
'''[[Александр Сюрис]]'''
 +
 
 +
Программа работает в двух режимах: поиск максимального числа фигур для заданного поля и количество возможных расстановок заданного числа фигур для заданного поля.
 +
 
 +
'''Алгоритм:'''
 +
 
 +
#Для поиска количества возможных расстановок заданного числа фигур для заданного поля – Проверяется, возможно ли поставить фигуру в данную клетку, рекурсивно перебирает для каждой клетки поля, как начальной клетки, все варианты расстановки заданного количества  фигур относительно нее и выводит на экран все расстановки, которые подходят условиям.
 +
#Для поиска максимального числа фигур для заданного поля –  Проверяется, можно ли поставить одну фигуру, две, три и так далее, пока фигур больше поставить будет нельзя.
 +
 
 +
Скачать можно  [http://mech.spbstu.ru/File:%D0%A8%D0%B0%D1%85%D0%BC%D0%B0%D1%82%D1%8B(%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%A1%D1%8E%D1%80%D0%B8%D1%81).zip  тут].
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
"'''T04CHESS.CPP'''"
 
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
/* FILENAME: T04CHESS.CPP
+
#include <vector>
* LAST UPDATE: 17.01.2016
+
#include <iostream>
*/
+
#include <algorithm>
  
#include "CHESS.h"
 
  
/* Main function */
+
using namespace std;
int main( void )
 
{
 
// Переменная, отвечающая за выход из меню
 
int IsReady = 1;
 
// Количество строк поля; количество столбцов поля
 
int N, M;
 
// Если идет поиск всех расстановок - 0; если идет поиск максимального числа фигур на доске - 1
 
int IsCount;
 
// Количество фигур на поле
 
int Number;
 
// Тип фигуры; количество разных расстановок; максимальное число фигур на доске
 
int tmp, count, max_value = 1;
 
// Создание указателя на тип FILE
 
FILE *F;
 
  
// Консольное меню
+
int n,k, o, m, l, g, maxi, a, sum=0,y, mozno=1;//mozno=1 если можно поставить n фигур
while (IsReady == 1)
+
vector<vector<int> > matrix;// двухмерный вектор
{
 
cout << "Input figure type:\n1 - castle\n2 - bishop\n3 - knight\n4 - queen\n5 - king\n";
 
cin >> tmp;
 
  
cout << "Input number of rows on the field:\n";
+
bool ladia(int x, int y) {      //проверка, можно ли в эту клетку поставить ладью
cin >> N;
+
    for(int i = 0; i<n; i++)
 +
        if(matrix[x][i] == 1)
 +
            return false;
 +
    for(int j=0; j<n; j++)
 +
        if(matrix[j][y]==1)
 +
            return false;
 +
    return true;
 +
}
  
cout << "Input number of columns on the field:\n";
+
bool slon(int x, int y) {  //    --//-- слона
cin >> M;
 
  
// Поле шахмат
+
  for (int i=x, j=y;i<n && j>=0; i++, j--)
chess desk(N, M);
+
      if(matrix[i][j] == 1)
 
+
            return false;
// Обнуление поля
+
  for (int i=x, j=y;i>=0 && j>=0; i--, j--)
desk.Clear();
+
      if(matrix[i][j] == 1)
 
+
            return false;
cout << "Input in what mode do you want to work:\n0 - Searching for all fields variants\n1 - Searching for the maximum number of chessmen\n";
+
  for (int i=x, j=y;i>=0 && j<n; i--, j++)
cin >> IsCount;
+
      if(matrix[i][j] == 1)
 +
            return false;
 +
  for (int i=x, j=y;i<n && j<n; i++, j++)
 +
      if(matrix[i][j] == 1)
 +
            return false;
 +
 
 +
    return true;
  
// Если идет поиск всех расстановок
+
}
if (IsCount == 0)
 
{
 
cout << "Input number of chessmen on the field:\n";
 
cin >> Number;
 
  
// Создание файла и его открытие
+
bool fruz(int x, int y){      //    --//-- ферзя
fopen_s(&F, "chess.txt", "wt");
+
    if(slon(x,y) && ladia(x,y))
if ((type)(tmp + 1) == 2)
+
        return true;
fputs("Castles' fields:\n", F);
 
else if ((type)(tmp + 1) == 3)
 
fputs("Bishops' fields:\n", F);
 
else if ((type)(tmp + 1) == 4)
 
fputs("Knights' fields:\n", F);
 
else if ((type)(tmp + 1) == 5)
 
fputs("Quenns' fields:\n", F);
 
else if ((type)(tmp + 1) == 6)
 
fputs("Kings' fields:\n", F);
 
else
 
{
 
fputs("Error\n", F);
 
return 0;
 
}
 
// Закрытие файла
 
fclose(F);
 
  
// Количество разных расстановок
+
    return false;
count = desk.FillField(IsCount, (type)(tmp + 1), 0, 0, Number, 0);
 
  
// Открытие файла в режиме повторной записи
 
fopen_s(&F, "chess.txt", "at");
 
fprintf(F, "\nNumber of fields: %i", count);
 
// Закрытие файла
 
fclose(F);
 
  
cout << "Done!\nCheck 'chess.txt' to see results\n";
+
}
}
 
  
// Если идет поиск максимального числа фигур на доске
+
bool kon(int x, int y) {   // --//-- коня
else if (IsCount == 1)
 
{
 
while (desk.FillField(IsCount, (type)(tmp + 1), 0, 0, max_value, 0))
 
max_value++;
 
cout << "The maximum number of chessmen on the board is " << (max_value - 1) << endl;
 
max_value = 1;
 
}
 
  
// Если было введено некорректное значение для IsCount
+
  if (x-1>=0 && y-2>=0 && matrix[x-1][y-2]==1)
else
+
        return false;
cout << "Error\n";
+
  if (y-2>=0 && x+1<n && matrix[x+1][y-2]==1)
 +
        return false;
 +
  if (x-2>=0 && y-1>=0 && matrix[x-2][y-1]==1)
 +
        return false;
 +
  if (x+2<n && y-1>=0 && matrix[x+2][y-1]==1)
 +
        return false;
 +
  if (x-2>=0 && y+1<n && matrix[x-2][y+1]==1)
 +
        return false;
 +
  if (x+2<n && y+1<n && matrix[x+2][y+1]==1)
 +
        return false;
 +
  if (x-1>=0 && y+2<n && matrix[x-1][y+2]==1)
 +
        return false;
 +
  if (x+1<n && y+2<n && matrix[x+1][y+2]==1)
 +
        return false;
 +
return true;
 +
}
  
// Продолжение работы с программой
+
bool king(int x, int y) {  // --//--  короля
cout << "Press '1' if you want to continue\nPress another number if you want to exit\n";
 
cin >> IsReady;
 
  
if (IsReady == 1)
+
    if (x-1>=0 && y-1>=0 && matrix[x-1][y-1]==1)
continue;
+
        return false;
else
+
    if (x-1>=0 && matrix[x-1][y]==1)
exit(0);
+
        return false;
}
+
    if (y+1<n && x-1>=0 && matrix[x-1][y+1]==1)
 +
        return false;
 +
    if (y+1<n && matrix[x][y+1]==1)
 +
        return false;
 +
    if (y+1<n && x+1>n && matrix[x+1][y+1]==1)
 +
        return false;
 +
    if (x+1<n && matrix[x+1][y]==1)
 +
        return false;
 +
    if (x+1<n && y-1>=0 && matrix[x+1][y-1]==1)
 +
        return false;
 +
    if (y-1>=0 && matrix[x][y-1]==1)
 +
        return false;
 +
    return true;
 +
 
 +
}
  
return 0;
+
int mass() {  // вывод доски на экран
} // End of 'main' function
 
  
// END OF 'T04CHESS.CPP' FILE
+
for(int i = 0; i<n; i++)
</syntaxhighlight>
+
  {
"'''CHESS.CPP'''"
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
/* FILENAME: CHESS.CPP
 
* LAST UPDATE: 17.01.2016
 
*/
 
  
#include "CHESS.H"
+
    for(int j = 0; j<n; j++)
 +
        cout<<matrix[i][j]<<" ";
  
// Количество расстановок
+
        cout<<endl;
int Result_count = 0;
+
    }
  
/* Clear field function */
+
}
// Обнуление поля
 
void chess::Clear( void )
 
{
 
// Все клетки свободны
 
for (int i = 0; i < N; i++)
 
for (int j = 0; j < M; j++)
 
Field[i][j] = Free;
 
} // End of 'Clear' function
 
  
/* Check if the cell is available that function */
+
int del() { // очистка доски(все нули)
// Проверка, свободна и существует ли данная клетка
 
int chess::IsAvailable( int x, int y )
 
{
 
if (x >= 0 && y >= 0 && x < M && y < N)
 
if (Field[y][x] == Free)
 
  return 1;
 
 
return 0;
 
} // End of 'IsAvailable' function
 
  
/* Output field in file function */
+
for (int i=0; i<n; i++) {
// Запись одного поля в файл
 
void chess::OutputInFile( void )
 
{
 
// Создание указателя на тип FILE
 
FILE *F;
 
  
// Открытие файла в режиме повторной записи
+
    for (int j=0; j<n; j++)
fopen_s(&F, "chess.txt", "at");
+
        matrix[i][j]=0;
 +
}
  
// Переход на следующую строку файла
+
}
fputc('\n', F);
 
  
// Заполнение файла текущем полем
 
for (int i = 0; i < N; ++i)
 
{
 
// '*' - свободная клетка; '#' - клетка, которая уже занята
 
for (int j = 0; j < M; ++j)
 
(Field[i][j] == Free || Field[i][j] == busy) ? fputc('*', F) : fputc('#', F);
 
// Переход на следующую строку файла
 
fputc('\n', F);
 
}
 
  
// Закрытие файла
 
fclose(F);
 
} /* End of 'OutputInFile' function */
 
  
/* Copy desks function */
+
void vsevarintyrasstavitnfigur(int x,int y){  // рекурсивный поиск всех вараинтов расстановок заданнного количества фигур (x - номер фигуры в доске, если ее растянуть в линию, y - кол-во фигур)
// Копирование поля
+
    if(y==0) {
void chess::Copy( chess &desk2 )
+
        if (a==1){
{
+
            mass();
  for (int i = 0; i < N; i++)
+
            cout<<'\n';
for (int j = 0; j < M; j++)
+
        }
desk2.Field[i][j] = Field[i][j];
+
        if(a==2) {
} // End of 'Copy' function
+
                mozno = 1;  //mozno=1 если можно поставить n фигур
 +
 
 +
        }
 +
 
 +
        return;
 +
    }
 +
 
 +
    for(int i=x;i<n*n;i++){
 +
 
 +
        if (o==1)
 +
        if(fruz(i/n,i%n) && y>0) {matrix[i/n][i%n]=1; y--;}
 +
 
 +
        if (o==2)
 +
        if(ladia(i/n,i%n) && y>0) {matrix[i/n][i%n]=1; y--;}
  
/* Fill field function */
+
        if (o==3)
// Заполнение полей и поиск максимального числа расстановок
+
        if(slon(i/n,i%n) && y>0) {matrix[i/n][i%n]=1; y--;}
// Chessmen_num - количество фигур, которое нужно поставить; Already_stood - количество, которое уже стоит
 
int chess::FillField( int IsCount, type set, int x, int y, int Chessmen_num, int Already_stood )
 
{
 
int i, j, k, l;
 
chess desk2(N, M);
 
  
// Обнуление поля
+
        if (o==4)
desk2.Clear();
+
        if(kon(i/n,i%n) && y>0) {matrix[i/n][i%n]=1; y--;}
 +
 
 +
        if (o==5)
 +
        if(king(i/n,i%n) && y>0) {matrix[i/n][i%n]=1; y--;}
 +
 
 +
 
 +
        vsevarintyrasstavitnfigur(i+1, y);
 +
        matrix[i/n][i%n]=0;//удаление фигуры из прошлой клетки для проверки других вариантов
 +
        y++;
 +
 
 +
    }
 +
 
 +
}
 +
 
 +
void maxfig(){  //поиск максимального количества фигур
 +
    int i=0;
 +
while(mozno==1){ //проверяет для данной доски возможность расставить 1,2... фигуры, пока не доходит до количества, которое расставить невозхможно. Тогда это количество фигур -1 - искомая величина
 +
        i++;
 +
        mozno=0;
 +
        vsevarintyrasstavitnfigur(0,i);
 +
    }
 +
    setlocale(LC_ALL, "Russian");
 +
    cout<<"Максимальное количество фигур = "<<i-1<<endl;
 +
}
 +
 
 +
 
 +
int main() {
 +
setlocale(LC_ALL, "Russian");
 +
    g=0;
 +
    cout<<"Введите размер доски:"<<endl;
 +
    cin >>n;
 +
        for(int i=0; i<n; i++) {
 +
            vector<int> z;
 +
            for(int j=0; j<n; j++){
 +
                    z.push_back(0);  //создание вектора z  из n нулей и добавление его к двухмерному вектору
 +
            }
 +
            matrix.push_back(z);
 +
        }
 +
 
 +
        cout<<"1 - расстановки фигур на доске n*n"<<endl<<"2 - максимум фигур на доске n*n"<<endl;
 +
          cin>>a;
 +
 
 +
        while(2>1){
 +
            cout<<" 1 - ферзь"<<endl;
 +
            cout<<" 2 - ладья"<<endl;
 +
            cout<<" 3 - слон"<<endl;
 +
            cout<<" 4 - конь"<<endl;
 +
            cout<<" 5 - король"<<endl;
 +
            cout<<" 6 - выход"<<endl;
 +
 
 +
          cout<<"Введите число от 1 до 6:"<<endl;
 +
          cin>>o;
 +
            mozno=1;
 +
            if(o==6) break;
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
    if (o==1)  {
 +
                cout<<"Ферзь"<<endl;
 +
 
 +
            if(a==1)
 +
                {
 +
                    cin>>y;
 +
                    vsevarintyrasstavitnfigur(0,y);
 +
                }
 +
 
 +
 
 +
            if (a==2)
 +
                maxfig();
 +
 
 +
                }
  
// Пробег по всем оставшимся клеткам поля, начиная с той, на которой мы закончили предыдущую итерацию
 
for (i = y; i < N; i++)
 
for (j = ((i == y) ? x : 0); j < M; j++)
 
{
 
// Если клетка свободна
 
if (Field[i][j] == Free)
 
{
 
// Копируем доску
 
Copy(desk2);
 
 
// Множественный выбор типа фигуры
 
switch (set)
 
{
 
// Ладья
 
case castle:
 
for (k = 0; k < N; k++)
 
{
 
// Движение по столбцу
 
if (desk2.Field[k][j] == Free)
 
  desk2.Field[k][j] = busy;
 
// Движение по строке
 
if (desk2.Field[i][k] == Free)
 
  desk2.Field[i][k] = busy;
 
}
 
break;
 
// Слон
 
case bishop:
 
// Выбор и поиск наибольшей существующей на поле диагонали
 
for (k = 1 - (N < M ? N : M); k < (N < M ? N : M); k++)
 
{
 
// Проход из левого верхнего угла до правого нижнего
 
if (IsAvailable(j + k, i + k))
 
desk2.Field[i + k][j + k] = busy;
 
// Проход из левого нижнего до правого верхнего
 
if (IsAvailable(j + k, i - k))
 
desk2.Field[i - k][j + k] = busy;
 
}
 
break;
 
// Конь
 
case knight:
 
// Ходы коня, k - приращение по X, l - по Y
 
k = -2, l = 1;
 
// Проверка возможности хода в данную клетку
 
if (IsAvailable(j + k, i + l))
 
desk2.Field[i + l][j + k] = busy;
 
 
k = -2, l = -1;
 
// Проверка возможности хода в данную клетку
 
if (IsAvailable(j + k, i + l))
 
desk2.Field[i + l][j + k] = busy;
 
 
k = -1, l = 2;
 
// Проверка возможности хода в данную клетку
 
if (IsAvailable(j + k, i + l))
 
desk2.Field[i + l][j + k] = busy;
 
 
k = -1, l = -2;
 
// Проверка возможности хода в данную клетку
 
if (IsAvailable(j + k, i + l))
 
desk2.Field[i + l][j + k] = busy;
 
 
k = 1, l = 2;
 
// Проверка возможности хода в данную клетку
 
if (IsAvailable(j + k, i + l))
 
desk2.Field[i + l][j + k] = busy;
 
 
k = 1, l = -2;
 
// Проверка возможности хода в данную клетку
 
if (IsAvailable(j + k, i + l))
 
desk2.Field[i + l][j + k] = busy;
 
 
k = 2, l = 1;
 
// Проверка возможности хода в данную клетку
 
if (IsAvailable(j + k, i + l))
 
desk2.Field[i + l][j + k] = busy;
 
 
k = 2, l = -1;
 
// Проверка возможности хода в данную клетку
 
if (IsAvailable(j + k, i + l))
 
desk2.Field[i + l][j + k] = busy;
 
break;
 
// Ферзь
 
case queen:
 
for (k = 0; k < N; k++)
 
{
 
// Движение по столбцу
 
if (desk2.Field[k][j] == Free)
 
desk2.Field[k][j] = busy;
 
// Движение по строке
 
if (desk2.Field[i][k] == Free)
 
desk2.Field[i][k] = busy;
 
}
 
 
// Выбор и поиск наибольшей существующей на поле диагонали
 
for (k = 1 - (N < M ? N : M); k < (N < M ? N : M); k++)
 
{
 
// Проход из левого верхнего угла до правого нижнего
 
if (IsAvailable(j + k, i + k))
 
desk2.Field[i + k][j + k] = busy;
 
// Проход из левого нижнего до правого верхнего
 
if (IsAvailable(j + k, i - k))
 
desk2.Field[i - k][j + k] = busy;
 
}
 
break;
 
// Король
 
case king:
 
  // Проход по квадрату 3 на 3, построенному центром на клетке, в которой стоит король
 
for (k = -1; k < 2; k++)
 
for (l = -1; l < 2; l++)
 
if (IsAvailable(j + k, i + l))
 
desk2.Field[i + l][j + k] = busy;
 
break;
 
}
 
// Установка фигуры в данную клетку
 
desk2.Field[i][j] = set;
 
       
 
// Проверяем, что количество поставленных фигур, которое равно номеру итерации, меньше чем необходимое число фигур
 
if ((Already_stood + 1) < Chessmen_num)
 
{
 
// Если идет поиск всех расстановок, то запускаем следующий шаг
 
if (IsCount == 0)
 
desk2.FillField(IsCount, set, j, i, Chessmen_num, Already_stood + 1);
 
// Если идет поиск максимального числа фигур на доске и была найдена хотя бы одна расстоновка, то возвращаем 1
 
else if ((IsCount == 1) && desk2.FillField(IsCount, set, j, i, Chessmen_num, Already_stood + 1))
 
return 1;
 
}
 
  
// Если количество поставленных фигур равно необходимому числу фигур
 
else if ((Already_stood + 1) == Chessmen_num)
 
{
 
// Если идет поиск всех расстановок, то увеличиваем количество расстоновок на одну и записываем поле в файл 
 
if (IsCount == 0)
 
{
 
Result_count++;
 
  desk2.OutputInFile();
 
}
 
// Если идет поиск максимального числа фигур на доске, значит расстановка существует, возвращаем 1
 
else if (IsCount == 1)
 
return 1;
 
  }
 
}
 
}
 
// Если идет поиск всех расстановок, то возвращаем количество расстановок
 
if (IsCount == 0)
 
  return Result_count;
 
// Если идет поиск максимального числа фигур на доске, то возвращаем 0
 
else if (IsCount == 1)
 
  return 0;
 
} // End of 'FillField' function
 
  
// END OF 'CHESS.CPP' FILE
 
</syntaxhighlight>
 
"'''CHESS.H'''"
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
/* FILENAME: CHESS.H
 
* LAST UPDATE: 17.01.2016
 
*/
 
  
#ifndef __CHESS_H_
 
#define __CHESS_H_
 
  
#include <iostream>
 
#include <conio.h>
 
  
using namespace std;
+
    if (o==2)  {
 +
                cout<<endl<<"Ладья"<<endl;
  
// свободен, занят, ладья, слон, конь, ферзь, король
+
                    if(a==1)
enum type { Free, busy, castle, bishop, knight, queen, king };
+
                    {
  
/* Chess class */
+
                        cin>>y;
class chess
+
                        vsevarintyrasstavitnfigur(0,y);
{
+
                    }
private:
+
 
// Поле данных фигур
+
                    if (a==2)
type **Field;
+
                        maxfig();
// Количество строк поля; количество столбцов поля
+
 
int N, M;
+
                }
public:
 
/* Default constructor */
 
chess( void )
 
{
 
N = 8, M = 8;
 
 
// Выделение памяти под массив поля
 
Field = new type*[N];
 
for (int i = 0; i < N; i++)
 
Field[i] = new type[M];
 
}
 
 
/* Class constructor */
 
chess( int _N, int _M ) : N(_N), M(_M)
 
{
 
// Выделение памяти под массив поля
 
Field = new type* [N];
 
for (int i = 0; i < N; i++)
 
Field[i] = new type [M];
 
}
 
  
/* Class destructor */
 
~chess( void )
 
{
 
// Чистка памяти
 
for (int i = 0; i < N; i++)
 
delete[] Field[i];
 
delete[] Field;
 
}
 
  
/* Clear field function */
+
    if (o==3)   {
void Clear( void );
+
                cout<<endl<<"Слон"<<endl;
 
/* Check if the cell is available that function */
 
int IsAvailable( int x, int y );
 
 
/* Output field in file function */
 
void OutputInFile( void );
 
 
/* Copy desks function */
 
void Copy( chess& desk2 );
 
 
/* Fill field function */
 
int FillField ( int IsCount, type set, int x, int y, int Chessmen_num, int Already_stood);
 
}; // end of 'chess' class
 
  
#endif /*__CHESS_H_ */
+
                if(a==1)
 +
                    {
 +
                    cin>>y;
 +
                    vsevarintyrasstavitnfigur(0,y);
 +
                    }
  
// END OF 'CHESS.H' FILE
+
                    if (a==2)
</syntaxhighlight>
+
                    maxfig();
</div>
 
[http://tm.spbstu.ru/File:T04CHESS.7z Скачать архив]
 
<br>
 
  
 +
                }
  
'''[[Рубинова Раиса]]'''
 
  
'''Основная идея программы''': программа позволяет выводить на экран всевозможные расстановки n однотипных фигур на шахматной доске размером n*n так, чтобы ни одна из фигур не била другую.
+
    if (o==4)  {
 +
                cout<<endl<<"Конь"<<endl;
  
Скачать можно [http://tm.spbstu.ru/File:nmk.rar тут.]
+
                if(a==1)
 +
                    {
 +
                    cin>>y;
 +
                    vsevarintyrasstavitnfigur(0,y);
 +
                    }
 +
                    if (a==2)
 +
                    maxfig();
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
              }
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
 
#include <iostream>
+
    if (o==5)  {
#include <cstring>
+
                cout<<"Король"<<endl;
#include <cstdlib>
+
 
#include <ctime>
+
                if(a==1)
 +
                {
 +
                    cin>>y;
 +
                    vsevarintyrasstavitnfigur(0,y);
 +
 
 +
                }
 +
                if (a==2)
 +
 
 +
                      maxfig();
 +
 
 +
                }
 +
 
 +
            }
  
using namespace std;
 
int R = 0; ///переменная, отвечающая за количество вариантов расстановок
 
int N; ///количество фигур для расстановки, которое задает пользователь
 
int **B; ///двумерный массив, отображающий шахматную доску
 
int M; /// размер шахматной доски
 
  
  
void showBoard() ///функция, выводящая доску на экран
 
{
 
    for(int i=0; i<M; ++i) /// строки
 
    {
 
        for(int j=0; j<M; ++j)  /// столбцы
 
            {cout << B[i][j] << " ";} ///заполнение клетки с координатами i;j
 
        cout << endl;
 
    }
 
    cout << "Variant " << ++R << "\n\n"; ///вывод номера варианта расположения с последующим переходом на новую строку
 
    return;
 
 
}
 
}
  
bool checkQueen(int a, int b) /// функция, проверяющая, не бьется ли ферзь другим ферзем
 
{
 
    for (int i = 0; i < M; ++i) ///проверка строки
 
    {
 
        if(B[a][i])
 
            return false;
 
    }
 
  
    for(int i = 0; i < M; ++i) ///проверка столбца
 
    {
 
        if(B[i][b])
 
            return false;
 
    }
 
  
    for(int i = 1; a-i >= 0 && b-i >= 0; ++i)///по диагонали влево-вверх
 
    {
 
        if(B[a-i][b-i])
 
            return false;
 
    }
 
  
    for(int i = 1; a+i < M && b+i < M; ++i)///по диагонали вправо-вниз
+
</syntaxhighlight>
    {
+
</div>
        if(B[a+i][b+i])
 
            return false;
 
    }
 
  
    for(int i = 1; a+i < M && b-i >= 0; ++i)///по диагонали влево-вниз
 
    {
 
        if(B[a+i][b-i])
 
            return false;
 
    }
 
  
    for(int i = 1; a-i >= 0 && b+i < M; ++i)///по диагонали вправо-вверх
 
    {
 
        if(B[a-i][b+i])
 
            return false;
 
    }
 
  
    return true;
 
}
 
  
void Queen(int a, int count) ///функция, расстанавливающая ферзи
+
'''[[Лосева Татьяна]]'''
{
 
    for(int b = 0; b < M; ++b) /// расстановка по изменению номера столбца
 
    {
 
        if(checkQueen(a, b)) ///проверка, бьется ли данная клетка ферзем
 
        {
 
            B[a][b] = 1; ///заполнение первой клетки
 
            for(int i = a+1; i < M; ++i) ///расстановка указанного пользователем количества фигур
 
                Queen(i,count+1);
 
            if(count+1==N) /// проверка, расставили ли мы нужное количество фигур
 
                showBoard();
 
            B[a][b]=0; ///обнуление переменной
 
        }
 
    }
 
}
 
  
bool checkRook(int a, int b) /// функция, проверяющая ли данную клетку ладья
+
'''Краткое описание алгоритма :'''
{
+
Доска представлена в виде динамического массива;Для каждой фигуры написана отдельная функция проверки на возможность установки фигуры,проверяющая, находится ли эта фигура под ударом других.
    for (int i = 0; i < M; ++i) ///проверка строки
+
После выбора типа фигуры,используется  рекурсивная функция,которая проверяет возможные  расстановки через данную функцию проверки ,для данного типа фигуры.
    {
+
Для поиска максимального значения мы проверяем расстановку начиная с 0 количество фигур ,каждый раз увеличивая на 1,если количество расстановок станет равно нулю,то предыдущее количество фигур было максимальным.
        if(B[a][i])
 
            return false;
 
    }
 
  
    for(int i = 0; i < M; ++i) ///проверка столбца
+
'''Инструкция''' : Пользователя попросят ввести размер доски,затем выбрать один из вариантов работы программы:1.поиск возможных расстановок для M фигур или 2.поиск максимального количества расстановок для данного поля,затем попросят выбрать тип фигуры и в первом случае количество фигур.При выводе на экран выводится номер расстановки и доска,на доске F- обозначены занятые клетки,0-пуская клетка.
    {
+
Для 2 пункта выводится лишь число: максимальное количество фигур,которое можно расставить.
        if(B[i][b])
+
 
            return false;
+
Скачать можно : [http://tm.spbstu.ru/Файл:Шахматы_Лосева.rar тут]
    }
 
  
    return true;
 
}
 
  
void Rook(int a, int count) ///функция, расстанавливающая ладьи
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
{
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
    for(int b = 0; b < M; ++b) /// расстановка по строкам с изменением номера столбца
+
#include<iostream>
    {
+
using namespace std;
        if(checkRook(a, b)) ///проверка, бьется ли данная клетка ладьей
+
int N;//размер доски NxN
        {
+
int **a;
            B[a][b] = 1; ///установка ладьи
+
int *ax;
            for(int i =a+1; i<M; ++i)
+
int *by;
                Rook(i,count+1);
+
int l = 0;//L-номер пункта в меню
            if(count+1 == N) /// проверка, расставили ли мы нужное количество элементов
+
int M;//количество фигур
                showBoard();
+
bool isPrint = false;//переменная для вывода на экран,когда требуется,для удобства обозначим в начале false
  
            B[a][b]=0; ///обнуление переменной
 
        }
 
    }
 
}
 
  
bool checkElephant(int a, int b) /// функция, проверяющая, бьется ли данная клетка слоном
+
void print()//функция вывода на экран
 
{
 
{
    for(int i = 1; a-i >= 0 && b-i >= 0; ++i)///проверка по диагонали влево-вверх
+
for (int i = N - 1; i >= 0; --i)
    {
+
{
        if(B[a-i][b-i])
+
for (int j = 0; j < N; ++j)
            return false;
+
{
    }
+
cout << ((a[j][i]) ? "F " : "0 ");//если (a[j][i]) истина,то есть клетка занята,ставим F,в другом случае,т.е.свободна,ставим 0
 +
}
 +
cout << '\n';
 +
}
 +
cout << '\n';
  
    for(int i = 1; a+i < M && b+i < M; ++i)///проверка по диагонали вправо-вниз
+
}
    {
+
bool Lad(int x, int y)//Ладья
        if(B[a+i][b+i])
+
{
            return false;
+
for (int i = 0; i < N; ++i)
    }
+
{
 +
if (a[i][y] == 1 )//проверяем горизонталь:если клетка занята
 +
{
 +
return false;//возвращаем false
 +
}
 +
if (a[x][i] == 1)//проверяем вертикаль : если хотя бы одна клетка занята,то
 +
{
 +
return false;//возврашаем false
 +
}
 +
}
 +
return true;//ничего выше не выполняется,значит возвращаем правду:вертикаль и горизонталь свободна
  
    for(int i = 1; a+i < M && b-i >= 0; ++i)///проверка по диагонали влево-вниз
+
}
    {
 
        if(B[a+i][b-i])
 
            return false;
 
    }
 
  
    for(int i = 1; a-i >= 0 && b+i < M; ++i) ///проверка по диагонали вправо-вверх
+
bool Kon(int x, int y)//Коняша
    {
 
        if(B[a-i][b+i])
 
            return false;
 
    }
 
 
 
    return true;
 
}
 
void Elephant(int dia, int count) ///функция, расстанавливающая слоны
 
 
{
 
{
    int a, b; /// задача клетки, соответствующекй данной диагонали
+
int i[8] = {-2, -2, -1, -1, 1, 1, 2, 2};//координаты клеток,на которые может ходить конь,относительно текущей (8 вариантов)
    if (dia < M) /// проверка диагонали
+
int j[8] = {-1, 1, -2, 2, -2, 2, -1, 1};
    {
+
        a = dia; /// номер строки - номер диагонали
+
for (int k = 0; k < 8; k++)//8 вариантов хода
        b = 0; ///обнуление переменной для столбца, цикл движется по столбцу
+
    }
+
{
  else ///если все диагонали рассмотрены
+
if (x + i[k] >= 0 && x + i[k] < N && y + j[k] >= 0 && y + j[k] < N)//проверка выхода за границы массива
    {
+
{
        a = M-1; /// рассматриваем самую последнюю диагональ
+
if (a[x + i[k]][y + j[k]] != 0)//клетка занята
        b =(dia % M)+1; ///рассчитываем координату столбца для данной диагонали
+
{
    }
+
return false;//возвращем false
 +
}
 +
}
 +
}
 +
return true;////ничего выше не выполняется,значит возвращаем правду:все варианты ходов  свободны и конь никого не перебивает,тогда можно занять клетку
 +
 
 +
}
  
    for(int i=0; a-i>=0 && b+i < M; ++i)/// цикл движется по строкам и столбцам из нижнего левого угла в правый верхний
 
    {
 
        int line=a-i; ///координата строки (мы уменьшаем координату строки)
 
        int column=b+i; ///координата столбца  (но увеличиваем координату столбца)
 
  
        if(checkElephant(line, column))/// проверка, бьется ли слон по диагонали
 
        {
 
            B[line][column]=1; ///установка слона
 
  
            for(int i=dia+1; i<2*M-1; ++i) ///расстановка фигур, основанная на изменении параметров (номера диагонали и количества рсставленных фигур)
 
                Elephant(i,count+1);
 
  
            if(count+1 == N) /// проверка количества расставленных фигур
+
bool Korol(int x, int y)//Король
                showBoard();
+
{
  
            B[line][column]=0; ///обнуление переменной
+
int i[8] = { -1, -1, -1, 0, 0, 1, 1, 1 };//координаты клеток,на которые может ходить король,относительно текущей
        }
+
     int j[8] = { -1, 0, 1, -1, 1, -1, 0, 1 };
     }
 
}
 
  
bool checkHorse(int a, int b) /// функция, проверяющая, бьется ли данная клетка конями
+
for(int k = 0; k < 8; k++)//8 вариантов хода
{
+
{
    if ((a-1) >=0 && (b-2)>=0 && B[a-1][b-2])
+
if (x + i[k] >= 0 && x + i[k] < N && y + j[k] >= 0 && y + j[k] < N)//прроверяем не выходит ли фигура за границы массива
        return false;
+
{
 
+
if (a[x + i[k]][y + j[k]] != 0)//если какой нибудь из вариантов хода занят
    if ((a-1)>=0 && (b+2) < M && B[a-1][b+2])
+
{
        return false;
+
return false;//то false
 
+
}
    if ((a+1) < M && (b-2) >=0 && B[a+1][b-2])
+
}
        return false;
+
}
 
+
return true;//свободно,можно занимать
    if ((a+1) < M && (b+2) < M && B[a+1][b+2])
 
        return false;
 
 
 
    if ((a-2) >=0 && (b-1) >=0 && B[a-2][b-1])
 
        return false;
 
 
 
    if ((a-2) >=0 && (b+1) < M && B[a-2][b+1])
 
        return false;
 
 
 
    if ((a+2) < M && (b-1) >= 0 && B[a+2][b-1])
 
        return false;
 
 
 
    if ((a+2) < M && (b+1) < M && B[a+2][b+1])
 
        return false;
 
 
 
    return true;
 
 
}
 
}
  
void Horse(int count, int a, int b) ///функция расстановки коней; a - очередная строка, b - очередной столбец, count - счетчик количества фигур, которое необходимо расставить
+
bool Slon(int x, int y)
 
{
 
{
    if(count==N) /// проверка количества расставленных фигур
+
int p1 = y - x;//номер диагонали слева направо
    {
+
int p2 = y + x;//номер диагонали с права налево
        showBoard();
+
for (int i = 0; i < N; i++)//проверяем левую диагональ
    }
+
{
    if (a == M) /// не выходит ли за предел доски
+
if (i + p1 >= 0 && i + p1 < N)//проверка на выход за границы массива
        return;
+
{
    for (int j=b; j<M; ++j) ///рассматриваем первую строку
+
if (a[i][i + p1] == 1) //проверяем диагональ
    {
+
{
        if(checkHorse(a, j)) ///проверка
+
return false;//диагональ занята
        {
+
}
            B[a][j]=1; ///установка коня
+
}
            int l = a, b = j+1; ///смещение в другой столбец
+
if (-i + p2 >= 0 && -i + p2 < N)//вторая диагональ
 +
{
 +
if (a[i][-i + p2] == 1)
 +
{
 +
return false;//вторая диагональ занята
 +
}
 +
}
 +
}
 +
return true;//обе диагонали свободны,ура!
 +
}
  
            if (b == M) ///проверка, не крайний ли это столбец, так как тогда мы не можем продолжать расстановку (мы ее завершили)
+
bool Check(int x, int y)//Ферзь=Ладья+Слон
            {
+
{
                b=0; ///обнуление переменной
+
int p1 = y - x;//диагональ 1
                l++;    ///переход на следующую
+
int p2 = y + x;//диагональ 2
            }
+
for (int i = 0; i < N; ++i)
            Horse(count+1,l,b); ///установка фигуры, увеличение счетчика
+
{
            B[a][j]=0; ///обнуление переменной для установки следующей фигуры в следующую клетку
+
if (a[i][y] == 1 )//проверяем горизонталь
        }
+
{
    }
+
return false;//занято
    for(int i=a+1; i<M; ++i) ///заполнение строк
+
}
    {
+
if (a[x][i] == 1)//проверяем вертикаль
        for (int j=0; j<M; ++j)
+
{
        {
+
return false;//занято
            if(checkHorse(i, j)) ///проверка клетки, не бьется ли она другими конями
+
}
            {
+
                B[i][j]=1; ///установка коня
+
if (i + p1 >= 0 && i + p1 < N)//выход за границы массива
                int l = i, b = j+1; ///смещаемся на другой столбец
+
{
                if (b == M)
+
if (a[i][i + p1] == 1) //проверяем 1 диагональ
                {
+
{
                    b = 0;
+
return false;//занято
                    l++;
+
}
                }
+
}
                Horse(count+1,l,b); ///установка фигуры с увеличением счетчика
+
if (-i + p2 >= 0 && -i + p2 < N)//выход за границы массива
                B[i][j]=0; ///обнуление переменной
+
{
            }
+
if (a[i][-i + p2] == 1)//проверяем 2ую диагональ
        }
+
{
    }
+
return false;//занято
 +
}
 +
}
 +
}
 +
return true;//свободно!
 
}
 
}
  
bool checkKing(int a, int b) /// функция, проверяющая, бьет ли данную клетку король
+
int  menu1()
 
{
 
{
    for(int i = a-1; i <= a+1; ++i)
+
cout << "Type of figure:" << endl << "1 - Ferz" << endl << "2 - Ladya" << endl << "3 - Slon" << endl << "4 - Kon" << endl << "5 - Korol" << endl;
    {
+
cin >> l;
        for(int j = b-1; j <= b+1; ++j)
+
return l;
        {
+
}
            if (a>=0 && a < M && b>=0 && b < M && B[a][b])
 
                return false;
 
  
            if ((a+1) < M && (b-1) >=0 && B[a+1][b-1])
+
int num = 0;//номер расстановки
                return false;
+
//пробует найти результаты решений.
  
            if ((a+1) < M && B[a+1][b])
+
void Func(int d,int K) //d-глубина рекурсии;K-сколько фигур нужно расставить
                return false;
+
{
 +
if (d == K)//когда расставили нужное количество
 +
{
 +
if (isPrint)//если true,то печатаем(в случае с MAX количеством доску печатать не нужно)
 +
{
 +
cout << "Result: " << num + 1 << '\n';//выводим нормер расстановки
 +
print();//печатаем доску
 +
}
 +
num++;//номер расстановки увеличивается
 +
return;
 +
}
  
            if ((a+1) < M && (b+1) < M && B[a+1][b+1])
+
int minX = d != 0 ? ax[d - 1] : 0;//исходя из того куда быда поставлена предыдущая фигура
                return false;
+
//,накладываются ограничения для выбора места новой,чтобы избежать поторений
 +
int minY = d != 0 ? by[d - 1] + 1 : 0;
  
            if ((b+1) < M && B[a][b+1])
 
                return false;
 
  
            if ((a-1)>=0 && (b+1) < M && B[a-1][b+1])
+
bool isPossible = false;//Проверяет,возможно ли занять клетку
                return false;
+
for (int i = minX; i < N; ++i)
 +
{
  
            if ((a-1) >=0 && B[a-1][b])
+
for (int j = (i != minX) ? 0 : minY; j < N; ++j)
                return false;
+
{
 
+
switch (l)//l- номер пункта в меню с фигурами
            if ((a-1) >=0 && (b-1)>=0 && B[a-1][b-1])
+
{
                return false;
+
case 1://ферзь
 
+
isPossible = Check(i, j);
            if ((b-1) >= 0 && B[a][b-1])
+
break;
                return false;
+
case 2://Ладья
        }
+
isPossible = Lad(i, j);
    }
+
break;
 +
case 3://Слон
 +
 +
isPossible = Slon(i, j);
 +
break;
 +
case 4://Конь
 +
isPossible = Kon(i, j);
 +
break;
 +
case 5://Король
 +
isPossible = Korol(i, j);
 +
break;
 +
}
 +
if (isPossible)//если клетку занять возмоно(функция вернула true)
 +
{
 +
  a[i][j] = 1;//занимаем клетку
 +
ax[d] = i;//запоминаем куда была поставлена фигура
 +
by[d] = j;//запоминаем куда была поставлена фигура
 +
Func(d + 1, K);//вызываем рекурсивно
 +
a[i][j] = 0;
 +
}
 +
}
 +
}
  
    return true;
+
return;
 
}
 
}
  
void King (int count, int a, int b) ///функция, расставляющая коней
+
int main()
 
{
 
{
    for (int j=b; j<M; ++j)  ///установка королей в первой строке
 
    {
 
        if(checkKing(a, j)) ///проверка данной клетки на возможность установки фигуры
 
        {
 
            B[a][j]=1; ///если по результатам проверки можно поставить фигуру, то мы ее ставим
 
            King(count+1,a,j); ///расстановка фигур для первой доски
 
            B[a][j]=0;  ///обнуление переменной
 
        }
 
    }
 
  
    for(int i=a+1; i<M; ++i) ///расстановка фигур
+
cout << "Enter size: ";//нужно ввести размер доски
    {
+
cin >> N;//считываем размер доски
        for (int j=0; j<M; ++j)
+
 
        {
+
a = new int*[N];//создаём двумерный массив,т.е.нашу доску
            if(checkKing(i, j)) ///проверка данной клетки на возможность установки фигуры
+
for (int i = 0; i < N; i++)
            {
+
{
                B[i][j]=1; /// если короля можно поставить, то ставим его в данную клетку
+
a[i] = new int[N];
                King(count+1,i,j);
+
for (int j = 0; j < N; j++)
                B[i][j]=0; ///обнуление переменной
+
a[i][j] = 0;//заполняем нулями
            }
+
}
        }
+
    }
+
ax = new int[N];//массивы для сохранения координаты каждой фигуры,чтобы избежать повторений
 +
by = new int[N];
  
    if(count==N)
+
int d;//пункт в меню
    {
+
cout<<"1 - Rasstanovka figur"<<endl<<"2 - MAX znachenie"<<endl;//два варианта работы программы
        showBoard();/// вывод шахмат на экран
+
cin>>d;//считываем выбор пользователя
        return;
+
if(d==1)//если выбирает расстановку
    }
+
{  
}
+
menu1();//то спрашиваем для какой фигуры
 +
cout<<"How many figures?"<<endl;//и как много будет фигур
 +
    cin>>M;//считываем количество фигур
 +
isPrint = true;//в этом случае будем выводить на экран
 +
Func(0,M);//запуск рекурсивной функции
 +
}
 +
 
 +
if (d == 2)//случай подсчёта максимального значения
 +
{
 +
int n = 0;//изачально max=0
 +
menu1();//выбираем фигуру
 +
 +
do//начало цикла
 +
{
 +
num = 0;
 +
Func(0, ++n);//запускаем каждый раз увеличивая значение фигур и считаем количество расстановок
 +
} while (num != 0);//количество вариантов не должно быть равно нулю
 +
cout <<"MAX ="<< n - 1 << endl;//если количество вариантов = 0,то выходим из цикла и предыдущее значение  максимальное
 +
}
 +
 +
 
 +
int z;
 +
cin >> z;
 +
 
 +
return 0;
 +
}
 +
</syntaxhighlight>
 +
</div>
 +
 
 +
'''[[Степанянц Степан]]'''
 +
 
 +
'''Программа''': 1)Программа получает все возможные варианты расстановок одинаковых фигур на поле боя(шахматной доске) так, чтобы они не смогли бить друг друга.2)Программа выводит максимальное число фигур, которые можно поставить на шахматную доску nxn так, чтобы они не смогли бить друг друга.
 +
 
 +
'''Идея алгоритма''': Функция вызывает саму себя(рекурсия) в рекурсии фигура ставится на небьющуюся клетку и помечаются клетки, которые бьются этой фигурой.Если дальше ставить нельзя, то начинается обратный ход:фигура убирается, и запоминается место, где она стояла, и вновь вызывается функция.
 +
 
 +
Скачать можно  [http://tm.spbstu.ru/Файл:Шахматы.rar тут].
 +
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
#include <iostream>
 +
#include <vector>
 +
 
 +
using namespace std;
  
int main()
 
{
 
        cout << "Enter the size of the board: " << endl; ///ввод размера доски
 
        cin >> M;
 
        B = new int*[M];
 
        for (int i=0; i<M; i++)
 
            B[i] = new int[M];
 
        for (int i = 0; i<M; i++)
 
            for (int j = 0; j<M; j++)
 
                B[i][j] = 0;
 
        int Var;
 
        cout << '\n' << "1=your number of figures, 2=max number of figures" << endl;
 
        cin >> Var;
 
        int F;
 
                cout << '\n' << "Input type of figure: 1-queen, 2-king, 3-horse, 4-rook, 5-elephant"<< endl;
 
                cin >> F;
 
        if (Var==1) /// если пользователь выбрал свое количество фигур, то мы выполняем следующие действия:
 
        {
 
                int mn;
 
                    cout << "Input the number of figures" << endl;
 
                    cin >> N;
 
                if (F==1)
 
                {
 
                    for (int i=0; i <M; ++i)
 
                        Queen(i,0);
 
                }
 
                if (F==2)
 
                {
 
                    King(0,0,0);
 
                }
 
                if (F==3)
 
                {
 
                    Horse(0,0,0);
 
                }
 
                if (F==4)
 
                {
 
                    for (int i=0; i <M; ++i)
 
                        Rook(i,0);
 
                }
 
                if (F==5)
 
                {
 
                    for(int i = 0; i<2*M-1; ++i)
 
                        Elephant(i,0);
 
                }
 
            }
 
        else if (Var==2)      /// если пользователь выбрал максимальное количество фигур
 
        {
 
                int mn;
 
                if (F==1)
 
                {
 
                    mn=M;
 
                    cout <<  "Max number " << mn  << endl;  /// выводим максимальное количество фигур
 
                    N=mn; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 
                        for (int i=0; i < M; ++i)
 
                            Queen(i,0);
 
                    }
 
  
                if (F==2)
 
                {
 
                    mn=0.25*M*M;
 
                    cout << '\n' << "Max number " << mn <<  endl;
 
                    N=mn; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 
                    King(0,0,0);
 
                    }
 
                if (F==3)
 
                {
 
                    mn=0.5*M*M;
 
                    cout <<  "Max number " << mn  << endl;
 
                    N=mn; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 
                    Horse(0,0,0);
 
                    }
 
                if (F==4)
 
                {
 
                    mn=M;
 
                    cout <<  "Max number " << mn  << endl;
 
                    N=mn; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 
                        for (int i=0; i <M; ++i)
 
                            Rook(i,0);
 
                    }
 
                if (F==5)
 
                {
 
                    mn=2*M-2;
 
                    cout <<  "Max number " << mn  << endl;
 
                    N=mn; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 
                        for(int i = 0; i<2*M-1; ++i)
 
                            Elephant(i,0);
 
                    }
 
                }
 
    }
 
  
 +
//задаю массивы в которых изображены все ходы определенных фигур
 +
int d = 0;
 +
int d_knight[2][8] = {{1, 1, -1, -1, 2, 2, -2, -2},
 +
    {2, -2, 2, -2, 1, -1, 1, -1}};
 +
int d_bish[4][2] = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
 +
int d_king[8][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
 +
//Проверяем, не выходим ли мы за поле
 +
bool ok(int x, int y, int n) {
 +
    if (x < 0 || y < 0 || x >= n || y >= n)
 +
        return false;
 +
    return true;
 +
}
  
 
+
void print(int n, vector<vector<pair<bool, int> > > board) {
</syntaxhighlight>
+
     for (int i = 0; i < n; i++) {
</div>
+
         for (int j = 0; j < n; j++) {
 
+
            cout << ((board[i][j].first) ? " X " : " 0 ");
'''[[Савельева Ольга]]'''
+
        }
 
+
        cout << '\n';
 
+
     }
'''Инструкция''': В меню указывается два варианта развития событий. Пользователь должен выбрать один из путей: либо максимальное число вариантов, либо посмотреть наглядно на варианты. Человек вводит размер доски и тип фигуры.
+
    cout << "-------------------------------------\n";
 
 
Скачать программу можно  [http://tm.spbstu.ru/:File:Шахматы0001.zip    ]
 
 
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
 
 
#define windows
 
 
 
#include <stdio.h>
 
#include <vector>
 
 
 
#ifdef windows
 
#include <windows.h>
 
#endif  // windows
 
 
 
using namespace std;
 
 
 
#ifdef windows
 
HANDLE hCon;
 
#endif // windows
 
 
 
unsigned fact(int n) //factorial of a number
 
{
 
    unsigned long long ret = 1;
 
     for(int i = 2; i <= n; i++)
 
         ret *= i;
 
     return ret;
 
 
}
 
}
 
+
//Рекурсивная функция
struct desk
+
int func(int n, int k, int count, vector<vector<pair<bool, int> > > board, int ii, int jj, int fig, int task) {
{
+
     int ans = 0;
    char **deskFigures, **deskOccupy;  //desk with figures, desk with occupation counter for each cell
+
    if (count == k && !task) {
    int x, y, size, a, f;  //pointer position(x, y), size of the desk, amount of prints, amount of figures
+
         print(n, board);
    vector<pair<int, int> > *s; //stack of placed figures
+
         return 1;
    bool stackIsUsed;  //if stack is needed
+
    }
    desk(int size, bool stackIsUsed = true):x(0), y(0), size(size), a(0), f(0), stackIsUsed(stackIsUsed)
+
    else if(task) {
     {
+
        ans = max(ans, count);
        deskFigures = new char*[size];
 
        for(int i = 0; i < size; i++)
 
            deskFigures[i] = new char[size];
 
         deskOccupy = new char*[size];
 
         for(int i = 0; i < size; i++)
 
            deskOccupy[i] = new char[size];
 
        if(stackIsUsed)
 
            s = new vector<pair<int, int> >;
 
        clear();
 
 
     }
 
     }
     ~desk()
+
     for (int i = ii + jj / n; i < n; i++) {
    {
+
         for (int j = jj % n; j < n; j++) {
         for(int i = 0; i < size; i++)
+
             if (!board[i][j].first && !board[i][j].second) {
             delete deskFigures[i];
+
                switch (fig) {
        delete deskFigures;
+
                    case 1://конь
        for(int i = 0; i < size; i++)
+
                        for (int k = 0; k < 8; k++) {
            delete deskOccupy[i];
+
                            if (ok(i + d_knight[0][k], j + d_knight[1][k], n))
        delete deskOccupy;
+
                                board[i + d_knight[0][k]][j + d_knight[1][k]].second++;
        if(stackIsUsed)
+
                        }
            delete s;
+
                        break;
    }
+
                    case 2://слон
    void setKnight(int x, int y, int z) //increase all cells occupied by knight at (x, y) on z
+
                        for (int k = 0; k < n; k++) {
    {
+
                            for (int l = 0; l < 4; l++) {
        if(x + 2 < size)
+
                                if (ok(i + k * d_bish[l][0], j + k * d_bish[l][1], n))
        {
+
                                    board[i + k * d_bish[l][0]][j + k * d_bish[l][1]].second++;
            if(y - 1 >= 0)
+
                            }
                deskOccupy[x + 2][y - 1] += z;
+
                        }
            if(y + 1 < size)
+
                        break;
                deskOccupy[x + 2][y + 1] += z;
+
                    case 3: // ладья
        }
+
                        for (int k = 0; k < n; k++)
        if(y + 2 < size)
+
                            board[i][k].second++, board[k][j].second++;
        {
+
                        break;
            if(x - 1 >= 0)
+
                    case 4: // король
                deskOccupy[x - 1][y + 2] += z;
+
                        for (int k = 0; k < 8; k++)
            if(x + 1 < size)
+
                            if (ok(i + d_king[k][0], j + d_king[k][1], n))
                 deskOccupy[x + 1][y + 2] += z;
+
                                board[i + d_king[k][0]][j + d_king[k][1]].second++;
        }
+
                        break;
        if(x - 2 >= 0)
+
                    case 5: // ферзь
        {
+
                        for (int k = 0; k < 8; k++)
            if(y - 1 >= 0)
+
                            for (int l = 0; l < n; l++)
                deskOccupy[x - 2][y - 1] += z;
+
                                if (ok(i + l * d_king[k][0], j + l * d_king[k][1], n))
            if(y + 1 < size)
+
                                    board[i + l * d_king[k][0]][j + l * d_king[k][1]].second++;
                deskOccupy[x - 2][y + 1] += z;
+
                        break;
        }
+
                       
        if(y - 2 >= 0)
+
                }
        {
+
                //Рекурсия
            if(x - 1 >= 0)
+
                board[i][j].first = true;
                deskOccupy[x - 1][y - 2] += z;
+
                if (!task)
            if(x + 1 < size)
+
                    ans += func(n, k, count + 1, board, i, j + 1, fig, task);
                deskOccupy[x + 1][y - 2] += z;
+
              //обратный ход
 +
                 else
 +
                    ans = max(ans, func(n, k, count + 1, board, i, j + 1, fig, task));
 +
                board[i][j].first = false;
 +
                switch (fig) {
 +
                    case 1:
 +
                        for (int k = 0; k < 8; k++) {
 +
                            if (ok(i + d_knight[0][k], j + d_knight[1][k], n))
 +
                                board[i + d_knight[0][k]][j + d_knight[1][k]].second--;
 +
                        }
 +
                        break;
 +
                    case 2:
 +
                        for (int k = 0; k < n; k++) {
 +
                            for (int l = 0; l < 4; l++) {
 +
                                if (ok(i + k * d_bish[l][0], j + k * d_bish[l][1], n))
 +
                                    board[i + k * d_bish[l][0]][j + k * d_bish[l][1]].second--;
 +
                            }
 +
                        }
 +
                        break;
 +
                    case 3:
 +
                        for (int k = 0; k < n; k++)
 +
                            board[i][k].second--, board[k][j].second--;
 +
                        break;
 +
                    case 4:
 +
                        for (int k = 0; k < 8; k++)
 +
                            if (ok(i + d_king[k][0], j + d_king[k][1], n))
 +
                                board[i + d_king[k][0]][j + d_king[k][1]].second--;
 +
                        break;
 +
                    case 5:
 +
                        for (int k = 0; k < 8; k++)
 +
                            for (int l = 0; l < n; l++)
 +
                                if (ok(i + l * d_king[k][0], j + l * d_king[k][1], n))
 +
                                    board[i + l * d_king[k][0]][j + l * d_king[k][1]].second--;
 +
                        break;
 +
                }
 +
            }
 
         }
 
         }
 +
        jj = 0;
 
     }
 
     }
     void setBishop(int x, int y, int z) //increase all cells occupied by bishop at (x, y) on z
+
     return ans;
     {
+
}
        for(int ix = 0, iy1 = y - x, iy2 = y + x; ix < size; ix++, iy1++, iy2--)
+
//меню
            if(ix != x)
+
int main() {
            {
+
     int fig, task;
                if((iy1 >= 0)and(iy1 < size))
+
    int n, k;
                    deskOccupy[ix][iy1] += z;
+
    cout << "Please, input the task number: 1 - amount of solutions, 2 - maximum of figures\n";
                if((iy2 >= 0)and(iy2 < size))
+
    cin >> task;
                    deskOccupy[ix][iy2] += z;
+
    task--;
            }
+
    cout << "Please, input figure type: 1 - knight, 2 - bishop, 3 - castle, 4 - king, 5 - queen\n";
 +
    cin >> fig;
 +
    cout << "Please, input the size of the board\n";
 +
    cin >> n;
 +
    if (!task) {
 +
        cout << "Please, input number of figures\n";
 +
        cin >> k;
 
     }
 
     }
     void setRook(int x, int y, int z)  //increase all cells occupied by rook at (x, y) on z
+
     vector<vector<pair<bool, int> > > v = vector<vector<pair<bool, int> > >(n, vector <pair<bool, int> >(n, {false, 0}));
     {
+
     cout << func(n, k, 0, v, 0, 0, fig, task);
        for(int i = 0; i < size; i++)
+
}
        {
+
</syntaxhighlight>
            if(i != x)
+
</div>
                deskOccupy[i][y] += z;
+
 
            if(i != y)
+
'''[[Лобанов Илья]]'''
                deskOccupy[x][i] += z;
+
 
        }
+
'''Описание алгоритма''':
    }
+
 
    void setKing(int x, int y, int z)  //increase all cells occupied by king at (x, y) on z
+
Программа проверяет возможность расстановки фигур на доске M*M . При выводе на экран на экран клетки,занятые фигурами ,помечаются буквами,соответствующими первой букве типа фигуры. Также программа считает максимальное число фигур определенного типа,которые можно расставить на доске.
    {
+
 
        for(int ix = x - 1; ix <= x + 1; ix++)
+
'''Инструкция''':
            for(int iy = y - 1; iy <= y + 1; iy++)
+
 
                if((ix >= 0)and(ix < size)and(iy >= 0)and(iy < size)and((ix != 0)or(iy != 0)))
+
В окне консоли пользователю предлагается выбрать 2 типа работы программы, затем пользователь вводит размер доски(четный),тип и количество фигур,которые необходимо разместить на доске.В зависимости от режима работы программы ,будет выведено либо максимально возможное число расстановок фигур,либо максимальное число фигур.
                    deskOccupy[ix][iy] += z;
+
Скачать можно [[http://tm.spbstu.ru/File:ConsoleApplication54.rar тут]]
    }
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
    void setFigure(int x, int y, int z, char figure)    //increase all cells occupied by figure
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
                                                        //and (x, y) on z
+
#include <iostream>
    {
+
#include <windows.h>
        deskOccupy[x][y] += z;
+
using namespace std;
        switch(figure)
+
 
        {
+
enum type{peshka, king, kon, ladya, slon, queen}; // все возможные типы фигур
            case 'N':
+
const char symbols[] = "pKklsQ"; // буквенное обозначение каждой фигуры:p - пешка, K - король, k - конь, l- ладья, s - слон, Q - ферзь
                setKnight(x, y, z);
+
const int NONE = INT_MAX;//константа для обозначения пустой клетки
                break;
+
int M, **desk, *colons, *rows, *diag_1, *diag_2;
            case 'B':
+
 
                setBishop(x, y, z);
+
// структура для описания клектки доски
                break;
+
struct point
            case 'R':
+
{
                setRook(x, y, z);
+
int x, y;
                break;
+
point(int x = 0, int y = 0): x(x), y(y) {}
            case 'Q':
+
point &operator++()
                setBishop(x, y, z);
+
{
                setRook(x, y, z);
+
if (y == M - 1)
                break;
+
{
            case 'K':
+
++x;
                setKing(x, y, z);
+
y = 0;
                break;
+
}
        }
+
else
    }
+
++y;
    bool putFigure(int x, int y, char figure)   //place figure on desk and update occupied cells
+
return *this;
    {
+
}
        if(deskFigures[x][y] > 0)
+
point operator+(const point &p) const
            return false;
+
{
        deskFigures[x][y] = figure;
+
return point(x + p.x, y + p.y);
        if(stackIsUsed)
+
}
            s -> push_back(make_pair(x, y));
+
point next() const
        setFigure(x, y, 1, figure);
+
{
        f++;
+
point r = *this;
        return true;
+
return ++r;
    }
+
}
    int cellsLeft() //amount of cells after pointer
+
};
    {
+
 
        return (size - y) * size - x;
+
 
    }
+
int *new_array(int n)
    bool putNextFree(char figure)  //attempt to put figure on the next free(and not occupied) place
+
{
    {
+
int *a = new int[n];
        if(y >= size)
+
fill(a, a + n, NONE);
            return false;
+
return a;
        while(deskOccupy[x][y] > 0)
+
}
        {
+
 
            if(++x == size)
+
// Количество свободных клеток от клетки p до конца доски
            {
+
int rest(const point &p, type t)
                if(++y == size)
+
{
                    return false;
+
int r0 = (M - p.x) * M - p.y, r,
                x = 0;
+
m = M - p.x,
            }
+
s_2 = (m + 1) / 2 * M;
        }
+
switch (t)
        return putFigure(x, y, figure);
+
{
    }
+
case peshka:
    void removeFigure(int x, int y) //remove figure from (x, y)
+
case kon:
    {
+
r = s_2; break;
        if(deskFigures[x][y]!=0)
+
case king:
            setFigure(x, y, -1, deskFigures[x][y]);
+
r = s_2 / 2; break;
        deskFigures[x][y] = 0;
+
case ladya:
        f--;
+
case queen:
    }
+
return m;
    void removeBishop(int diag, bool color, bool left)  //remove bishop
+
case slon:
    {
+
r = m + M - 1;
        if(color)   //true - white, false - black
+
}
        {
+
return min(r0, r);
            if(diag > 0)   //diag - number of diagonal
+
}
            {
+
 
                int diff = left ? 0 : diag * 2;
+
// Помечает клетку доски номером i
                removeFigure(diff, diag * 2 - diff);
+
void set(const point &p, type t, int i)
                removeFigure(size - diff - 1, size - diag * 2 + diff - 1);
+
{
            }
+
if (t == peshka || t == king || t == kon)
            else
+
desk[p.x][p.y] = i;
            if(left)    //determine position of the bishop on the diagonal
+
else
                removeFigure(0, 0);
+
{
            else
+
if (t == ladya || t == queen)
                removeFigure(size - 1, size - 1);
+
colons[p.y] = rows[p.x] = i;
        }
+
if (t == slon || t == queen)
        else
+
diag_1[p.x+p.y] = diag_2[p.x-p.y+M-1] = i;
        {
+
}
            if(diag > 0)
+
}
            {
+
 
                int diff = left ? 0 : diag * 2;
+
// Можно ли поставить фигуру номер i на клетку p
                removeFigure(size - diff - 1, diag * 2 - diff);
+
bool empty(const point &p, type t, int i)
                removeFigure(diff, size - diag * 2 + diff - 1);
+
{
            }
+
const int n_attack[3] = {4, 8, 8};
            else
+
const point attack[3][8] = {{point(1, 1), point(1, -1), point(-1, 1), point(-1, -1)}, //кол-во вариантов атаки для пешки
            if(left)
+
{point(1, 1), point(1, -1), point(-1, 1), point(-1, -1), point(1, 0), point(-1, 0), point(0, 1), point(0, -1)}, // кол-во вариантов атаки для короля
                removeFigure(0, size - 1);
+
{point(1, 2),point(-1, 2),point(1, -2), point (-1,-2), point (2, 1), point (2,-1), point (-2, 1),point (-2,-1)}};  //количество вариантов атаки для коня
            else
+
switch(t)
                removeFigure(size - 1, 0);
+
{
        }
+
case peshka:
    }
+
case king:
    void putBishop(int diag, bool color, bool left) //place bishop
+
case kon:
    {
+
for (int k = 0; k < n_attack[t]; k++)
        if(color)
+
{
        {
+
point q = p + attack[t][k];
            if(diag > 0)
+
if (q.x >= 0 && q.x < M && q.y >= 0 && q.y < M && desk[q.x][q.y] < i)
            {
+
return false;
                int diff = left ? 0 : diag * 2;
+
}
                putFigure(diff, diag * 2 - diff, 'B');
+
return true;
                putFigure(size - diff - 1, size - diag * 2 + diff - 1, 'B');
+
case ladya:
            }
+
return colons[p.y] > i && rows[p.x] > i;
            else
+
case slon:
            if(left)
+
return diag_1[p.x+p.y] > i && diag_2[p.x-p.y+M-1] > i;
                putFigure(0, 0, 'B');
+
case queen:
            else
+
return colons[p.y] > i && rows[p.x] > i && diag_1[p.x+p.y] > i && diag_2[p.x-p.y+M-1] > i;
                putFigure(size - 1, size - 1, 'B');
+
}
        }
+
}
        else
+
 
        {
+
//печатает заданное количество досок на экране
            if(diag > 0)
+
void print(point **figures, int n_desks, int N, type t, ostream &out = cout)
            {
+
{
                int diff = left ? 0 : diag * 2;
+
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
                putFigure(size - diff - 1, diag * 2 - diff, 'B');
+
for (int n = 0; n < n_desks; n++)
                putFigure(diff, size - diag * 2 + diff - 1, 'B');
+
{
            }
+
out << " \xdb";
            else
+
for (int i = 0; i < M * 2 + 2; i++)
            if(left)
+
out << "\xdf";
                putFigure(0, size - 1, 'B');
+
out << "\xdb";
            else
+
}
                putFigure(size - 1, 0, 'B');
+
out << endl;
        }
+
 
    }
+
int *K = new int[n_desks];
    void swapBishops(int diag, bool color, bool left)   //move pair bishops to another borders
+
fill(K, K + n_desks, 0);
    {
+
for (int i = 0; i < M; i++)
        removeBishop(diag, color, left);
+
{
        putBishop(diag, color, not(left));
+
for (int n = 0; n < n_desks; n++)
    }
+
{
    void figureBefore() //remove one figure from stack and change pointer to the next position after figure was placed
+
int &k = K[n];
    {
+
out << " \xdb ";
        pair<int, int> c = s -> back();
+
for (int j = 0; j < M; j++)
        s -> pop_back();
+
{
        x = c.first;
+
SetConsoleTextAttribute(hConsole, (i + j) % 2 == 0 ? 0xf0 : 0xf);
        y = c.second;
+
if (k < N && i == figures[n][k].x && j == figures[n][k].y)
        removeFigure(x, y);
+
{
        if(++x == size)
+
out << ' ' << symbols[t];
        {
+
k++;
            x = 0;
+
}
            y++;
+
else
        }
+
out << "  ";
    }
+
}
    void clear()   //clear the desk
+
SetConsoleTextAttribute(hConsole, 0x70);
    {
+
out << " \xdb";
        for(int ix = 0; ix < size; ix++)
+
}
            for(int iy = 0; iy < size; iy++)
+
out << endl;
            {
+
}
                deskFigures[ix][iy] = 0;
+
delete[] K;
                deskOccupy[ix][iy] = 0;
+
 
            }
+
for (int n = 0; n < n_desks; n++)
        x = 0;
+
{
        y = 0;
+
out << " \xdb";
        if(stackIsUsed)
+
for (int i = 0; i < M * 2 + 2; i++)
            s -> empty();
+
out << "\xdc";
        f = 0;
+
out << "\xdb";
    }
+
}
    void show() //show the desk
+
out << endl << endl;
    {
+
}
        a++;
+
 
        printf("%i:\n", a);
+
// Вывести все возможные расположения на доске N фигур
        #ifdef windows
+
void all_placements(int N, type t)
        unsigned background = 4;
 
        #else
 
        printf("\x1b[31m");
 
        char background = 47;
 
        #endif  //windows
 
        for(int y = 0; y < size; y++)
 
            for(int x = 0; x < size; x++)
 
            {
 
                #ifdef windows
 
                SetConsoleTextAttribute(hCon, background);
 
                #else
 
                printf("\x1b[%dm", background);
 
                #endif  //windows
 
                if(deskFigures[x][y] == 0)
 
                    putchar(' ');
 
                else
 
                    putchar(deskFigures[x][y]);
 
                #ifdef windows
 
                if(x < size - 1)
 
                    background = background == 4 ? 116 : 4;
 
                else
 
                {
 
                    SetConsoleTextAttribute(hCon, 7);
 
                    putchar('\n');
 
                }
 
                #else
 
                if(x < size - 1)
 
                    background = background == 47 ? 40 : 47;
 
                else
 
                {
 
                    printf("\x1b[0m\n");
 
                    if(y < size - 1)
 
                        printf("\x1b[31m");
 
                }
 
                #endif // windows
 
            }
 
    }
 
};
 
 
 
int m = -1; //0 for number of arrangements, 1 for all variants
 
 
 
unsigned lookForFigure(int size, int amount, char figure, bool show = true) //brute-force
 
 
{
 
{
    desk *d  = new desk(size);
+
desk = NULL;
    unsigned ret = 0;
+
colons = rows = diag_1 = diag_2 = NULL;
    while((d -> f > 0)or(d -> cellsLeft() >= amount))
+
// создание необходимых массивов, отмечающих занятость клеток, в зависимости от вида фигуры
        if(not(d -> putNextFree(figure)))
+
if (t == peshka || t == king || t == kon)
        {
+
{
            if(d -> f == amount)
+
desk = new int*[M];
            {
+
for (int j = 0; j < M; j++)
                if(show)
+
desk[j] = new_array(M);
                    d -> show();
+
}
                ret++;
+
else
            }
+
{
            d -> figureBefore();
+
if (t == ladya || t == queen)
        }
+
{
    delete d;
+
colons = new_array(M);
    return ret;
+
rows = new_array(M);
}
+
}
 +
if (t == slon || t == queen)
 +
{
 +
diag_1 = new_array(2*M-1);
 +
diag_2 = new_array(2*M-1);
 +
}
 +
}
 +
 +
const int W = 80 / (2 * M + 5);//количество досок,помещающихся на экране
 +
point **figures = new point*[W];//массив фигур
 +
for (int j = 0; j < W; j++)
 +
figures[j] = new point[N];
  
void lookForKnight(int size, int amount)    //arrangements of knights
+
int i = 0, // номер фигуры
{
+
k = 0; //номер комбинации
    if(m == 0)
+
while (true)
    {
+
{
        printf("Amount of arrangements: ");
+
if (rest(figures[k%W][i], t) < N - i) // если оставшиеся фигуры не помещаются на доске
        if(size == 2)
+
{
            printf("1\n");
+
if (i == 0) // если все комбинации закончились
        else
+
{
        if(size == 4)
+
// вывод оставшихся досок
            printf("6\n");
+
if (k % W)
        else
+
print(figures, k % W, N, t);
            printf("2\n");
+
cout << "Amount of combinations: " << k << endl;
    }
+
break;
    else
+
}
    {
+
// переходим к предыдущей фигуре и помечаем клетку пустой
        desk *d = new desk(size);
+
set(figures[k%W][--i], t, NONE);
        if(size == 2)
+
// сдвигаем фигуру на шаг вперёд
        {
+
++figures[k%W][i];
            d -> putFigure(0, 0, 'N');
+
}
            d -> putFigure(0, 1, 'N');
+
else if (!empty(figures[k%W][i], t, i)) // если фигуры помещаются, но текущая клетка под ударом
            d -> putFigure(1, 0, 'N');
+
// сдвигаем текущую фигуру на шаг вперёд
            d -> putFigure(1, 1, 'N');
+
++figures[k%W][i];
            d -> show();
+
else if (i == N - 1) // если ставим последнюю фигуру
        }
+
{
        else
+
// если текущая доска - последняя на строке экрана, выводим W досок
        if(size==4)
+
if ((k + 1) % W == 0)
            lookForFigure(size, amount, 'N');
+
print(figures, W, N, t);
        else
+
// копирование комбинаций фигур на следующую доску
        {
+
for (int j = 0; j < N; j++)
            for(int x = 0; x < size; x++)
+
figures[(k+1)%W][j] = figures[k%W][j];
                for(int y = 0;y < size; y++)
+
// переход к следующей доске
                    if(x + y % 2 == 0)
+
k++;
                        d -> putFigure(x, y, 'N');
+
//сдвигаем текущую фигуру на шаг вперёд
            d -> show();
+
++figures[k%W][i];
            d -> clear();
+
}
            for(int x = 0; x < size; x++)
+
else // если ставим не последнюю фигуру
                for(int y = 0;y < size; y++)
+
{
                    if(x + y % 2 == 1)
+
// помечаем текущую клетку номером i
                        d -> putFigure(x, y, 'N');
+
set(figures[k%W][i], t, i);
            d -> show();
+
//ставим следующую фигуру на клетку после текущей
        }
+
figures[k%W][i+1] = figures[k%W][i].next();
    }
+
// переходим к следующей фигуре
}
+
i++;
 +
}
 +
}
  
void lookForBishop(int size, int amount)    //arrangements of bishops
+
//освобождение памяти
{
+
for (int j = 0; j < W; j++)
    if(m == 0)
+
delete[] figures[j];
        printf("Amount of arrangements: %u", (unsigned) 1 << size);
+
delete[] figures;
    else
+
if (desk)
    {
+
{
        desk *d = new desk(size, false);
+
for (int j = 0; j < M; j++)
        bool *b = new bool[size];
+
delete[] desk[j];
        for(int dw = 0; dw < size/2; dw++)
+
delete[] desk;
        {
+
}
            d -> putBishop(dw, true, false);
+
if (colons)
            d -> putBishop(dw, false, false);
+
{
        }
+
delete[] colons;
        int p = size - 1;
+
delete[] rows;
        for(;;)
+
}
        {
+
if (diag_1)
            d -> show();
+
{
            while(b[p])
+
delete[] diag_1;
            {
+
delete[] diag_2;
                d -> swapBishops(p % (size / 2), p < size / 2, true);
+
}
                b[p--] = false;
 
                if(p < 0)
 
                    return;
 
            }
 
            b[p] = true;
 
            d -> swapBishops(p % (size / 2), p < size / 2, false);
 
            p = size - 1;
 
        }
 
    }
 
 
}
 
}
  
void lookForRook(int size, int amount) //arrangements of rooks
+
 
 +
int main()
 
{
 
{
    if(m == 0)
+
system("color 70"); // Установка серого фона и чёрного текста
        printf("Amount of arrangements: %u", fact(size));
+
while (true)
    else
+
{
        lookForFigure(size, amount, 'R');
+
cout << "Choose the mode:\n1 - all possible variants of figures' placement\n2 - maximum number of figures which can be placed on the desk\nq - quit\n\n";
}
+
char c;
 
+
cin >> c;
void lookForQueen(int size, int amount) //arrangements of queens
+
cin.ignore(100, '\n');
{
+
switch (c)
    if(m == 0)
+
{
        printf("Amount of arrangements: %u", lookForFigure(size, amount, 'Q', false));
+
case '1':
    else
+
case '2':
        lookForFigure(size, amount, 'Q');
+
cout << "Enter the desk size please. (The number must be even and not more than 37.)\n";
}
+
cin >> M;
 
+
while (!cin || M % 2 != 0 || M > 37 || M <= 0)
void lookForKing(int size, int amount) //arrangements of kings
+
{
{
+
cout << "Error: wrong desk size. Try again please.\n";
    if(m == 0)
+
cin.clear();
        printf("Amount of arrangements: %u", lookForFigure(size, amount, 'K', false));
+
cin.ignore(100, '\n');
    else
+
cin >> M;
        lookForFigure(size, amount, 'K');
+
}
}
+
cin.ignore(100, '\n');
 
+
cout << "Choose a figure, please.\n p - peshka, k - kon, l - ladya, s - slon, Q - Queen, K - King\n";
int main()
+
char f;
{
+
cin >> f;
    int s = -1, f = -1; //s - size, f - figure
+
cin.ignore(100, '\n');
    #ifdef windows
+
type t;
    hCon = GetStdHandle(STD_OUTPUT_HANDLE);
+
int i;
    #endif // windows
+
do
    sizeInput:
+
{
    printf("Enter size of the desk:\n");
+
for (i = 0; i < 6; i++)
    scanf("%i", &s);
+
{
    if((s<=0)or(s%2!=0))
+
if (symbols[i] == f)
    {
+
{
        printf("Size must be above 0 and even\n");
+
t = type(i);
        goto sizeInput;
+
break;
    }
+
}
    modeInput:
+
}
    printf("Enter mode:\n\t0: Print amount of results\n\t1: Print all results\n");
+
if (i == 6)
    scanf("%i", &m);
+
{
    if((m<0)or(m>1))
+
cout << "Enter the right letter, you've chosen the wrong one.\n";
    {
+
cin >> f;
        printf("Mode can be 0 or 1\n");
+
cin.ignore(100, '\n');
        goto modeInput;
+
}
    }
+
} while (i == 6);
    figureInput:
+
if (c == '1')
    printf("Enter figures to be placed\n\t0: Knight (N)\n\t1: Bishop (B)\n\t2: Rook (R)\n\t3: Queen (Q)\n\t4: King (K)\n");
+
{
    scanf("%i", &f);
+
cout << "Enter the number of figures please.\n";
    if((f<0)or(f>4))
+
int N;
    {
+
cin >> N;
        printf("Figure number ranges from 0 to 4\n");
+
while (!cin || N <= 0)
        goto figureInput;
+
{
    }
+
cout << "Error: wrong argument. Try again please.\n";
    switch(f)
+
cin.clear();
    {
+
cin.ignore(100, '\n');
        case 0:
+
cin >> N;
            if(s==2)
+
}
                lookForKnight(s, 4);
+
cin.ignore(100, '\n');
            else
+
all_placements(N, t);
                lookForKnight(s, s *s / 2);
+
}
            break;
+
else
        case 1:
+
{
            lookForBishop(s, 2 * s - 2);
+
cout << "The maximal number of figures is ";
            break;
+
switch (t)
        case 2:
+
{
            lookForRook(s, s);
+
case peshka:
            break;
+
cout << M*M/2; break;
        case 3:
+
case king:
            if(s==2)
+
cout << M*M/4; break;
                lookForQueen(s, 1);
+
case kon:  
            else
+
cout << (M == 2 ? 4 : M*M/2); break;
                lookForQueen(s, s);
+
case ladya:
            break;
+
cout << M; break;
        case 4:
+
case slon:
            lookForKing(s, (s / 2) * (s / 2));
+
cout << 2*M - 2; break;
            break;
+
case queen:
    }
+
cout << (M == 2 ? 1 : M);
    return 0;
+
}
 +
cout << ".\n";
 +
}
 +
break;
 +
case 'q':
 +
cout << endl;
 +
return 0;
 +
default:
 +
cout << "You've chosen the wrong command, try again please.\n";
 +
}
 +
cout << endl << endl;
 +
}
 
}
 
}
 
 
 
 
</syntaxhighlight>
 
</syntaxhighlight>
 
</div>
 
</div>
  
 +
'''[[Савельева Ольга]]'''
  
'''[[Сенников Иван]]'''
 
  
'''Суть программы:''' Программа позволяет на шахматной доске MxM расставить N фигур K типа всевозможными способами, причем при этом производится расчет максимального количества фигур K типа, которые можно расставить на данной доске MxM.
+
'''Инструкция''': В меню указывается два варианта развития событий. Пользователь должен выбрать один из путей: либо максимальное число вариантов, либо посмотреть наглядно на варианты. Человек вводит размер доски и тип фигуры.
  
'''Идея:''' Шахматная доска представляет собой двумерный динамический массив. С помощью рекурсивного метода программа пробегает по массиву, проверяя клетки доски по всем направлениям на то, атакованы ли они другими фигурами этого типа. В зависимости от количества поставленных фигур изменяется количество итераций. В новую клетку ставиться новая фигура и так до тех пор, пока не выполнится написанное выше условие, после чего начнется обратный ход.
+
Скачать программу можно  [http://tm.spbstu.ru/:File:Шахматы0001.zip    ]
  
'''Инструкция:''' Программа написана в виде меню на английском языке: пользователю будет предоставлена возможность сначала обозначить размер доски, а после выбрать тип фигур и их количество для дальнейшей работы с ними. Комментарии к программе написаны также на английском языке.
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
  
Ссылка для скачиваний: [http://tm.spbstu.ru/Файлы:Chess_v2.0.zip здесь].
+
#define windows
  
'''[[Степанянц Степан]]'''
+
#include <stdio.h>
 +
#include <vector>
  
'''Программа''': 1)Программа получает все возможные варианты расстановок одинаковых фигур на поле боя(шахматной доске) так, чтобы они не смогли бить друг друга.2)Программа выводит максимальное число фигур, которые можно поставить на шахматную доску nxn так, чтобы они не смогли бить друг друга.
+
#ifdef windows
 
+
#include <windows.h>
'''Идея алгоритма''': Функция вызывает саму себя(рекурсия) в рекурсии фигура ставится на небьющуюся клетку и помечаются клетки, которые бьются этой фигурой.Если дальше ставить нельзя, то начинается обратный ход:фигура убирается, и запоминается место, где она стояла, и вновь вызывается функция.
+
#endif  // windows
 
 
Скачать можно  [http://tm.spbstu.ru/Файл:Шахматы.rar тут].
 
 
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
#include <iostream>
 
#include <vector>
 
  
 
using namespace std;
 
using namespace std;
  
 +
#ifdef windows
 +
HANDLE hCon;
 +
#endif // windows
  
 
+
unsigned fact(int n)  //factorial of a number
//задаю массивы в которых изображены все ходы определенных фигур
+
{
int d = 0;
+
     unsigned long long ret = 1;
int d_knight[2][8] = {{1, 1, -1, -1, 2, 2, -2, -2},
+
    for(int i = 2; i <= n; i++)
     {2, -2, 2, -2, 1, -1, 1, -1}};
+
         ret *= i;
int d_bish[4][2] = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
+
     return ret;
int d_king[8][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
 
//Проверяем, не выходим ли мы за поле
 
bool ok(int x, int y, int n) {
 
    if (x < 0 || y < 0 || x >= n || y >= n)
 
         return false;
 
     return true;
 
 
}
 
}
  
void print(int n, vector<vector<pair<bool, int> > > board) {
+
struct desk
    for (int i = 0; i < n; i++) {
+
{
         for (int j = 0; j < n; j++) {
+
    char **deskFigures, **deskOccupy;  //desk with figures, desk with occupation counter for each cell
             cout << ((board[i][j].first) ? " X " : " 0 ");
+
    int x, y, size, a, f;  //pointer position(x, y), size of the desk, amount of prints, amount of figures
         }
+
    vector<pair<int, int> > *s; //stack of placed figures
        cout << '\n';
+
    bool stackIsUsed;  //if stack is needed
    }
+
    desk(int size, bool stackIsUsed = true):x(0), y(0), size(size), a(0), f(0), stackIsUsed(stackIsUsed)
    cout << "-------------------------------------\n";
+
    {
}
+
        deskFigures = new char*[size];
//Рекурсивная функция
+
        for(int i = 0; i < size; i++)
int func(int n, int k, int count, vector<vector<pair<bool, int> > > board, int ii, int jj, int fig, int task) {
+
            deskFigures[i] = new char[size];
    int ans = 0;
+
        deskOccupy = new char*[size];
    if (count == k && !task) {
+
         for(int i = 0; i < size; i++)
         print(n, board);
+
             deskOccupy[i] = new char[size];
        return 1;
+
         if(stackIsUsed)
 +
            s = new vector<pair<int, int> >;
 +
         clear();
 
     }
 
     }
     else if(task) {
+
     ~desk()
         ans = max(ans, count);
+
    {
 +
         for(int i = 0; i < size; i++)
 +
            delete deskFigures[i];
 +
        delete deskFigures;
 +
        for(int i = 0; i < size; i++)
 +
            delete deskOccupy[i];
 +
        delete deskOccupy;
 +
        if(stackIsUsed)
 +
            delete s;
 
     }
 
     }
     for (int i = ii + jj / n; i < n; i++) {
+
     void setKnight(int x, int y, int z) //increase all cells occupied by knight at (x, y) on z
         for (int j = jj % n; j < n; j++) {
+
    {
             if (!board[i][j].first && !board[i][j].second) {
+
         if(x + 2 < size)
                switch (fig) {
+
        {
                    case 1://конь
+
             if(y - 1 >= 0)
                        for (int k = 0; k < 8; k++) {
+
                deskOccupy[x + 2][y - 1] += z;
                            if (ok(i + d_knight[0][k], j + d_knight[1][k], n))
+
            if(y + 1 < size)
                                board[i + d_knight[0][k]][j + d_knight[1][k]].second++;
+
                deskOccupy[x + 2][y + 1] += z;
                        }
+
        }
                        break;
+
        if(y + 2 < size)
                    case 2://слон
+
        {
                        for (int k = 0; k < n; k++) {
+
            if(x - 1 >= 0)
                            for (int l = 0; l < 4; l++) {
+
                deskOccupy[x - 1][y + 2] += z;
                                if (ok(i + k * d_bish[l][0], j + k * d_bish[l][1], n))
+
            if(x + 1 < size)
                                    board[i + k * d_bish[l][0]][j + k * d_bish[l][1]].second++;
+
                deskOccupy[x + 1][y + 2] += z;
                            }
+
        }
                        }
+
        if(x - 2 >= 0)
                        break;
+
        {
                    case 3: // ладья
+
            if(y - 1 >= 0)
                        for (int k = 0; k < n; k++)
+
                deskOccupy[x - 2][y - 1] += z;
                            board[i][k].second++, board[k][j].second++;
+
            if(y + 1 < size)
                        break;
+
                deskOccupy[x - 2][y + 1] += z;
                    case 4: // король
+
        }
                        for (int k = 0; k < 8; k++)
+
        if(y - 2 >= 0)
                            if (ok(i + d_king[k][0], j + d_king[k][1], n))
+
        {
                                board[i + d_king[k][0]][j + d_king[k][1]].second++;
+
            if(x - 1 >= 0)
                        break;
+
                deskOccupy[x - 1][y - 2] += z;
                    case 5: // ферзь
+
            if(x + 1 < size)
                        for (int k = 0; k < 8; k++)
+
                deskOccupy[x + 1][y - 2] += z;
                            for (int l = 0; l < n; l++)
+
        }
                                if (ok(i + l * d_king[k][0], j + l * d_king[k][1], n))
+
    }
                                    board[i + l * d_king[k][0]][j + l * d_king[k][1]].second++;
+
    void setBishop(int x, int y, int z) //increase all cells occupied by bishop at (x, y) on z
                        break;
+
    {
                       
+
        for(int ix = 0, iy1 = y - x, iy2 = y + x; ix < size; ix++, iy1++, iy2--)
                }
+
            if(ix != x)
                //Рекурсия
+
            {
                board[i][j].first = true;
+
                 if((iy1 >= 0)and(iy1 < size))
                if (!task)
+
                    deskOccupy[ix][iy1] += z;
                    ans += func(n, k, count + 1, board, i, j + 1, fig, task);
+
                 if((iy2 >= 0)and(iy2 < size))
              //обратный ход
+
                    deskOccupy[ix][iy2] += z;
                 else
+
            }
                    ans = max(ans, func(n, k, count + 1, board, i, j + 1, fig, task));
+
    }
                board[i][j].first = false;
+
    void setRook(int x, int y, int z)  //increase all cells occupied by rook at (x, y) on z
                 switch (fig) {
+
    {
                    case 1:
+
        for(int i = 0; i < size; i++)
                        for (int k = 0; k < 8; k++) {
+
        {
                            if (ok(i + d_knight[0][k], j + d_knight[1][k], n))
+
            if(i != x)
                                board[i + d_knight[0][k]][j + d_knight[1][k]].second--;
+
                deskOccupy[i][y] += z;
                        }
+
            if(i != y)
                        break;
+
                deskOccupy[x][i] += z;
                    case 2:
+
        }
                        for (int k = 0; k < n; k++) {
+
    }
                            for (int l = 0; l < 4; l++) {
+
    void setKing(int x, int y, int z)  //increase all cells occupied by king at (x, y) on z
                                if (ok(i + k * d_bish[l][0], j + k * d_bish[l][1], n))
+
    {
                                    board[i + k * d_bish[l][0]][j + k * d_bish[l][1]].second--;
+
        for(int ix = x - 1; ix <= x + 1; ix++)
                            }
+
            for(int iy = y - 1; iy <= y + 1; iy++)
                        }
+
                if((ix >= 0)and(ix < size)and(iy >= 0)and(iy < size)and((ix != 0)or(iy != 0)))
                        break;
+
                    deskOccupy[ix][iy] += z;
                    case 3:
 
                        for (int k = 0; k < n; k++)
 
                            board[i][k].second--, board[k][j].second--;
 
                        break;
 
                    case 4:
 
                        for (int k = 0; k < 8; k++)
 
                            if (ok(i + d_king[k][0], j + d_king[k][1], n))
 
                                board[i + d_king[k][0]][j + d_king[k][1]].second--;
 
                        break;
 
                    case 5:
 
                        for (int k = 0; k < 8; k++)
 
                            for (int l = 0; l < n; l++)
 
                                if (ok(i + l * d_king[k][0], j + l * d_king[k][1], n))
 
                                    board[i + l * d_king[k][0]][j + l * d_king[k][1]].second--;
 
                        break;
 
                }
 
            }
 
        }
 
        jj = 0;
 
 
     }
 
     }
     return ans;
+
     void setFigure(int x, int y, int z, char figure)    //increase all cells occupied by figure
}
+
                                                        //and (x, y) on z
//меню
+
    {
int main() {
+
        deskOccupy[x][y] += z;
    int fig, task;
+
        switch(figure)
    int n, k;
+
        {
    cout << "Please, input the task number: 1 - amount of solutions, 2 - maximum of figures\n";
+
            case 'N':
    cin >> task;
+
                setKnight(x, y, z);
    task--;
+
                break;
    cout << "Please, input figure type: 1 - knight, 2 - bishop, 3 - castle, 4 - king, 5 - queen\n";
+
            case 'B':
     cin >> fig;
+
                setBishop(x, y, z);
     cout << "Please, input the size of the board\n";
+
                break;
     cin >> n;
+
            case 'R':
    if (!task) {
+
                setRook(x, y, z);
         cout << "Please, input number of figures\n";
+
                break;
         cin >> k;
+
            case 'Q':
 +
                setBishop(x, y, z);
 +
                setRook(x, y, z);
 +
                break;
 +
            case 'K':
 +
                setKing(x, y, z);
 +
                break;
 +
        }
 +
     }
 +
     bool putFigure(int x, int y, char figure)  //place figure on desk and update occupied cells
 +
     {
 +
        if(deskFigures[x][y] > 0)
 +
            return false;
 +
        deskFigures[x][y] = figure;
 +
        if(stackIsUsed)
 +
            s -> push_back(make_pair(x, y));
 +
         setFigure(x, y, 1, figure);
 +
         f++;
 +
        return true;
 
     }
 
     }
     vector<vector<pair<bool, int> > > v = vector<vector<pair<bool, int> > >(n, vector <pair<bool, int> >(n, {false, 0}));
+
     int cellsLeft() //amount of cells after pointer
    cout << func(n, k, 0, v, 0, 0, fig, task);
+
    {
}
+
        return (size - y) * size - x;
</syntaxhighlight>
+
    }
</div>
+
    bool putNextFree(char figure)   //attempt to put figure on the next free(and not occupied) place
 
+
     {
'''[[Александр Сюрис]]'''
+
         if(y >= size)
 
 
Программа работает в двух режимах: поиск максимального числа фигур для заданного поля и количество возможных расстановок заданного числа фигур для заданного поля.
 
 
 
'''Алгоритм:''' 
 
 
 
#Для поиска количества возможных расстановок заданного числа фигур для заданного поля – Проверяется, возможно ли поставить фигуру в данную клетку, рекурсивно перебирает для каждой клетки поля, как начальной клетки, все варианты расстановки заданного количества  фигур относительно нее и выводит на экран все расстановки, которые подходят условиям.
 
#Для поиска максимального числа фигур для заданного поля –  Проверяется, можно ли поставить одну фигуру, две, три и так далее, пока фигур больше поставить будет нельзя.
 
 
 
Скачать можно  [http://mech.spbstu.ru/File:%D0%A8%D0%B0%D1%85%D0%BC%D0%B0%D1%82%D1%8B(%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%A1%D1%8E%D1%80%D0%B8%D1%81).zip  тут].
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
#include <vector>
 
#include <iostream>
 
#include <algorithm>
 
 
 
 
 
using namespace std;
 
 
 
int n,k, o, m, l, g, maxi, a, sum=0,y, mozno=1;//mozno=1 если можно поставить n фигур
 
vector<vector<int> > matrix;// двухмерный вектор
 
 
 
bool ladia(int x, int y) {      //проверка, можно ли в эту клетку поставить ладью
 
     for(int i = 0; i<n; i++)
 
         if(matrix[x][i] == 1)
 
 
             return false;
 
             return false;
    for(int j=0; j<n; j++)
+
        while(deskOccupy[x][y] > 0)
        if(matrix[j][y]==1)
+
        {
            return false;
+
            if(++x == size)
    return true;
+
            {
}
+
                if(++y == size)
 
+
                    return false;
bool slon(int x, int y) //   --//-- слона
+
                x = 0;
 
+
            }
  for (int i=x, j=y;i<n && j>=0; i++, j--)
+
        }
      if(matrix[i][j] == 1)
+
        return putFigure(x, y, figure);
             return false;
+
    }
  for (int i=x, j=y;i>=0 && j>=0; i--, j--)
+
    void removeFigure(int x, int y) //remove figure from (x, y)
      if(matrix[i][j] == 1)
+
    {
            return false;
+
        if(deskFigures[x][y]!=0)
  for (int i=x, j=y;i>=0 && j<n; i--, j++)
+
             setFigure(x, y, -1, deskFigures[x][y]);
      if(matrix[i][j] == 1)
+
        deskFigures[x][y] = 0;
            return false;
+
        f--;
  for (int i=x, j=y;i<n && j<n; i++, j++)
+
    }
      if(matrix[i][j] == 1)
+
    void removeBishop(int diag, bool color, bool left) //remove bishop
            return false;
+
    {
 
+
        if(color)   //true - white, false - black
    return true;
+
        {
 
+
            if(diag > 0)    //diag - number of diagonal
}
+
            {
 
+
                int diff = left ? 0 : diag * 2;
bool fruz(int x, int y){      //   --//-- ферзя
+
                removeFigure(diff, diag * 2 - diff);
    if(slon(x,y) && ladia(x,y))
+
                removeFigure(size - diff - 1, size - diag * 2 + diff - 1);
        return true;
+
            }
 
+
            else
    return false;
+
            if(left)   //determine position of the bishop on the diagonal
 
+
                removeFigure(0, 0);
 
+
            else
}
+
                removeFigure(size - 1, size - 1);
 
+
        }
bool kon(int x, int y) {  // --//-- коня
+
        else
 
+
         {
  if (x-1>=0 && y-2>=0 && matrix[x-1][y-2]==1)
+
            if(diag > 0)
        return false;
+
            {
  if (y-2>=0 && x+1<n && matrix[x+1][y-2]==1)
+
                int diff = left ? 0 : diag * 2;
         return false;
+
                removeFigure(size - diff - 1, diag * 2 - diff);
  if (x-2>=0 && y-1>=0 && matrix[x-2][y-1]==1)
+
                removeFigure(diff, size - diag * 2 + diff - 1);
        return false;
+
            }
  if (x+2<n && y-1>=0 && matrix[x+2][y-1]==1)
+
            else
        return false;
+
            if(left)
  if (x-2>=0 && y+1<n && matrix[x-2][y+1]==1)
+
                removeFigure(0, size - 1);
        return false;
+
            else
  if (x+2<n && y+1<n && matrix[x+2][y+1]==1)
+
                removeFigure(size - 1, 0);
        return false;
+
         }
  if (x-1>=0 && y+2<n && matrix[x-1][y+2]==1)
+
    }
        return false;
+
    void putBishop(int diag, bool color, bool left) //place bishop
  if (x+1<n && y+2<n && matrix[x+1][y+2]==1)
+
    {
         return false;
+
        if(color)
return true;
+
         {
}
+
            if(diag > 0)
 
+
            {
bool king(int x, int y) // --//--  короля
+
                int diff = left ? 0 : diag * 2;
 
+
                putFigure(diff, diag * 2 - diff, 'B');
    if (x-1>=0 && y-1>=0 && matrix[x-1][y-1]==1)
+
                putFigure(size - diff - 1, size - diag * 2 + diff - 1, 'B');
         return false;
+
            }
    if (x-1>=0 && matrix[x-1][y]==1)
+
            else
        return false;
+
            if(left)
    if (y+1<n && x-1>=0 && matrix[x-1][y+1]==1)
+
                putFigure(0, 0, 'B');
        return false;
+
            else
    if (y+1<n && matrix[x][y+1]==1)
+
                putFigure(size - 1, size - 1, 'B');
        return false;
+
        }
    if (y+1<n && x+1>n && matrix[x+1][y+1]==1)
+
        else
         return false;
+
         {
    if (x+1<n && matrix[x+1][y]==1)
+
            if(diag > 0)
        return false;
+
            {
    if (x+1<n && y-1>=0 && matrix[x+1][y-1]==1)
+
                int diff = left ? 0 : diag * 2;
        return false;
+
                putFigure(size - diff - 1, diag * 2 - diff, 'B');
    if (y-1>=0 && matrix[x][y-1]==1)
+
                putFigure(diff, size - diag * 2 + diff - 1, 'B');
        return false;
+
            }
    return true;
+
            else
 
+
            if(left)
}
+
                putFigure(0, size - 1, 'B');
 
+
            else
int mass() {  // вывод доски на экран
+
                putFigure(size - 1, 0, 'B');
 
+
        }
for(int i = 0; i<n; i++)
+
    }
  {
+
     void swapBishops(int diag, bool color, bool left)   //move pair bishops to another borders
 
+
    {
     for(int j = 0; j<n; j++)
+
         removeBishop(diag, color, left);
         cout<<matrix[i][j]<<" ";
+
         putBishop(diag, color, not(left));
 
 
         cout<<endl;
 
 
     }
 
     }
 
+
    void figureBefore() //remove one figure from stack and change pointer to the next position after figure was placed
}
+
    {
 
+
        pair<int, int> c = s -> back();
int del() // очистка доски(все нули)
+
        s -> pop_back();
 
+
        x = c.first;
for (int i=0; i<n; i++) {
+
         y = c.second;
 
+
        removeFigure(x, y);
    for (int j=0; j<n; j++)
+
        if(++x == size)
         matrix[i][j]=0;
+
         {
}
+
             x = 0;
 
+
             y++;
}
 
 
 
 
 
 
 
void vsevarintyrasstavitnfigur(int x,int y){  // рекурсивный поиск всех вараинтов расстановок заданнного количества фигур (x - номер фигуры в доске, если ее растянуть в линию, y - кол-во фигур)
 
    if(y==0) {
 
         if (a==1){
 
             mass();
 
             cout<<'\n';
 
 
         }
 
         }
        if(a==2) {
 
                mozno = 1;  //mozno=1 если можно поставить n фигур
 
 
        }
 
 
        return;
 
 
     }
 
     }
 
+
    void clear()    //clear the desk
     for(int i=x;i<n*n;i++){
+
     {
 
+
        for(int ix = 0; ix < size; ix++)
        if (o==1)
+
            for(int iy = 0; iy < size; iy++)
        if(fruz(i/n,i%n) && y>0) {matrix[i/n][i%n]=1; y--;}
+
            {
 
+
                deskFigures[ix][iy] = 0;
        if (o==2)
+
                deskOccupy[ix][iy] = 0;
        if(ladia(i/n,i%n) && y>0) {matrix[i/n][i%n]=1; y--;}
+
            }
 
+
         x = 0;
        if (o==3)
+
         y = 0;
        if(slon(i/n,i%n) && y>0) {matrix[i/n][i%n]=1; y--;}
+
         if(stackIsUsed)
 
+
            s -> empty();
         if (o==4)
+
         f = 0;
         if(kon(i/n,i%n) && y>0) {matrix[i/n][i%n]=1; y--;}
 
 
 
         if (o==5)
 
        if(king(i/n,i%n) && y>0) {matrix[i/n][i%n]=1; y--;}
 
 
 
 
 
        vsevarintyrasstavitnfigur(i+1, y);
 
         matrix[i/n][i%n]=0;//удаление фигуры из прошлой клетки для проверки других вариантов
 
        y++;
 
 
 
 
     }
 
     }
 
+
    void show() //show the desk
}
+
    {
 
+
        a++;
void maxfig(){ //поиск максимального количества фигур
+
        printf("%i:\n", a);
    int i=0;
+
        #ifdef windows
while(mozno==1){ //проверяет для данной доски возможность расставить 1,2... фигуры, пока не доходит до количества, которое расставить невозхможно. Тогда это количество фигур -1 - искомая величина
+
        unsigned background = 4;
        i++;
+
        #else
        mozno=0;
+
        printf("\x1b[31m");
        vsevarintyrasstavitnfigur(0,i);
+
        char background = 47;
 +
        #endif //windows
 +
        for(int y = 0; y < size; y++)
 +
            for(int x = 0; x < size; x++)
 +
            {
 +
                #ifdef windows
 +
                SetConsoleTextAttribute(hCon, background);
 +
                #else
 +
                printf("\x1b[%dm", background);
 +
                #endif  //windows
 +
                if(deskFigures[x][y] == 0)
 +
                    putchar(' ');
 +
                else
 +
                    putchar(deskFigures[x][y]);
 +
                #ifdef windows
 +
                if(x < size - 1)
 +
                    background = background == 4 ? 116 : 4;
 +
                else
 +
                {
 +
                    SetConsoleTextAttribute(hCon, 7);
 +
                    putchar('\n');
 +
                }
 +
                #else
 +
                if(x < size - 1)
 +
                    background = background == 47 ? 40 : 47;
 +
                else
 +
                {
 +
                    printf("\x1b[0m\n");
 +
                    if(y < size - 1)
 +
                        printf("\x1b[31m");
 +
                }
 +
                #endif // windows
 +
            }
 
     }
 
     }
    setlocale(LC_ALL, "Russian");
+
};
    cout<<"Максимальное количество фигур = "<<i-1<<endl;
 
}
 
  
 +
int m = -1; //0 for number of arrangements, 1 for all variants
  
int main() {
+
unsigned lookForFigure(int size, int amount, char figure, bool show = true) //brute-force
setlocale(LC_ALL, "Russian");
+
{
     g=0;
+
    desk *d  = new desk(size);
     cout<<"Введите размер доски:"<<endl;
+
     unsigned ret = 0;
    cin >>n;
+
     while((d -> f > 0)or(d -> cellsLeft() >= amount))
         for(int i=0; i<n; i++) {
+
         if(not(d -> putNextFree(figure)))
             vector<int> z;
+
        {
             for(int j=0; j<n; j++){
+
             if(d -> f == amount)
                     z.push_back(0);   //создание вектора z  из n нулей и добавление его к двухмерному вектору
+
             {
 +
                if(show)
 +
                     d -> show();
 +
                ret++;
 
             }
 
             }
             matrix.push_back(z);
+
             d -> figureBefore();
 
         }
 
         }
 +
    delete d;
 +
    return ret;
 +
}
  
         cout<<"1 - расстановки фигур на доске n*n"<<endl<<"2 - максимум фигур на доске n*n"<<endl;
+
void lookForKnight(int size, int amount)    //arrangements of knights
          cin>>a;
+
{
 
+
    if(m == 0)
         while(2>1){
+
    {
             cout<<" 1 - ферзь"<<endl;
+
        printf("Amount of arrangements: ");
             cout<<" 2 - ладья"<<endl;
+
         if(size == 2)
             cout<<" 3 - слон"<<endl;
+
            printf("1\n");
             cout<<" 4 - конь"<<endl;
+
        else
             cout<<" 5 - король"<<endl;
+
        if(size == 4)
             cout<<" 6 - выход"<<endl;
+
            printf("6\n");
 
+
        else
          cout<<"Введите число от 1 до 6:"<<endl;
+
            printf("2\n");
          cin>>o;
+
    }
             mozno=1;
+
    else
            if(o==6) break;
+
    {
 +
        desk *d = new desk(size);
 +
         if(size == 2)
 +
        {
 +
             d -> putFigure(0, 0, 'N');
 +
             d -> putFigure(0, 1, 'N');
 +
             d -> putFigure(1, 0, 'N');
 +
             d -> putFigure(1, 1, 'N');
 +
             d -> show();
 +
        }
 +
        else
 +
        if(size==4)
 +
            lookForFigure(size, amount, 'N');
 +
        else
 +
        {
 +
             for(int x = 0; x < size; x++)
 +
                for(int y = 0;y < size; y++)
 +
                    if(x + y % 2 == 0)
 +
                        d -> putFigure(x, y, 'N');
 +
            d -> show();
 +
            d -> clear();
 +
             for(int x = 0; x < size; x++)
 +
                for(int y = 0;y < size; y++)
 +
                    if(x + y % 2 == 1)
 +
                        d -> putFigure(x, y, 'N');
 +
            d -> show();
 +
        }
 +
    }
 +
}
  
 +
void lookForBishop(int size, int amount)    //arrangements of bishops
 +
{
 +
    if(m == 0)
 +
        printf("Amount of arrangements: %u", (unsigned) 1 << size);
 +
    else
 +
    {
 +
        desk *d = new desk(size, false);
 +
        bool *b = new bool[size];
 +
        for(int dw = 0; dw < size/2; dw++)
 +
        {
 +
            d -> putBishop(dw, true, false);
 +
            d -> putBishop(dw, false, false);
 +
        }
 +
        int p = size - 1;
 +
        for(;;)
 +
        {
 +
            d -> show();
 +
            while(b[p])
 +
            {
 +
                d -> swapBishops(p % (size / 2), p < size / 2, true);
 +
                b[p--] = false;
 +
                if(p < 0)
 +
                    return;
 +
            }
 +
            b[p] = true;
 +
            d -> swapBishops(p % (size / 2), p < size / 2, false);
 +
            p = size - 1;
 +
        }
 +
    }
 +
}
  
 +
void lookForRook(int size, int amount)  //arrangements of rooks
 +
{
 +
    if(m == 0)
 +
        printf("Amount of arrangements: %u", fact(size));
 +
    else
 +
        lookForFigure(size, amount, 'R');
 +
}
  
 +
void lookForQueen(int size, int amount) //arrangements of queens
 +
{
 +
    if(m == 0)
 +
        printf("Amount of arrangements: %u", lookForFigure(size, amount, 'Q', false));
 +
    else
 +
        lookForFigure(size, amount, 'Q');
 +
}
  
 +
void lookForKing(int size, int amount)  //arrangements of kings
 +
{
 +
    if(m == 0)
 +
        printf("Amount of arrangements: %u", lookForFigure(size, amount, 'K', false));
 +
    else
 +
        lookForFigure(size, amount, 'K');
 +
}
  
 +
int main()
 +
{
 +
    int s = -1, f = -1; //s - size, f - figure
 +
    #ifdef windows
 +
    hCon = GetStdHandle(STD_OUTPUT_HANDLE);
 +
    #endif // windows
 +
    sizeInput:
 +
    printf("Enter size of the desk:\n");
 +
    scanf("%i", &s);
 +
    if((s<=0)or(s%2!=0))
 +
    {
 +
        printf("Size must be above 0 and even\n");
 +
        goto sizeInput;
 +
    }
 +
    modeInput:
 +
    printf("Enter mode:\n\t0: Print amount of results\n\t1: Print all results\n");
 +
    scanf("%i", &m);
 +
    if((m<0)or(m>1))
 +
    {
 +
        printf("Mode can be 0 or 1\n");
 +
        goto modeInput;
 +
    }
 +
    figureInput:
 +
    printf("Enter figures to be placed\n\t0: Knight (N)\n\t1: Bishop (B)\n\t2: Rook (R)\n\t3: Queen (Q)\n\t4: King (K)\n");
 +
    scanf("%i", &f);
 +
    if((f<0)or(f>4))
 +
    {
 +
        printf("Figure number ranges from 0 to 4\n");
 +
        goto figureInput;
 +
    }
 +
    switch(f)
 +
    {
 +
        case 0:
 +
            if(s==2)
 +
                lookForKnight(s, 4);
 +
            else
 +
                lookForKnight(s, s *s / 2);
 +
            break;
 +
        case 1:
 +
            lookForBishop(s, 2 * s - 2);
 +
            break;
 +
        case 2:
 +
            lookForRook(s, s);
 +
            break;
 +
        case 3:
 +
            if(s==2)
 +
                lookForQueen(s, 1);
 +
            else
 +
                lookForQueen(s, s);
 +
            break;
 +
        case 4:
 +
            lookForKing(s, (s / 2) * (s / 2));
 +
            break;
 +
    }
 +
    return 0;
 +
}
  
    if (o==1)  {
 
                cout<<"Ферзь"<<endl;
 
 
            if(a==1)
 
                {
 
                    cin>>y;
 
                    vsevarintyrasstavitnfigur(0,y);
 
                }
 
 
 
            if (a==2)
 
                maxfig();
 
 
                }
 
 
 
 
 
 
 
    if (o==2)  {
 
                cout<<endl<<"Ладья"<<endl;
 
 
                    if(a==1)
 
                    {
 
 
                        cin>>y;
 
                        vsevarintyrasstavitnfigur(0,y);
 
                    }
 
 
                    if (a==2)
 
                        maxfig();
 
 
                }
 
  
  
    if (o==3)  {
+
</syntaxhighlight>
                cout<<endl<<"Слон"<<endl;
+
</div>
 +
 
  
                if(a==1)
+
'''[[Сенников Иван]]'''
                    {
 
                    cin>>y;
 
                    vsevarintyrasstavitnfigur(0,y);
 
                    }
 
  
                    if (a==2)
+
'''Суть программы:''' Программа позволяет на шахматной доске MxM расставить N фигур K типа всевозможными способами, причем при этом производится расчет максимального количества фигур K типа, которые можно расставить на данной доске MxM.
                    maxfig();
 
  
                }
+
'''Идея:''' Шахматная доска представляет собой двумерный динамический массив. С помощью рекурсивного метода программа пробегает по массиву, проверяя клетки доски по всем направлениям на то, атакованы ли они другими фигурами этого типа. В зависимости от количества поставленных фигур изменяется количество итераций. В новую клетку ставиться новая фигура и так до тех пор, пока не выполнится написанное выше условие, после чего начнется обратный ход.
  
 +
'''Инструкция:''' Программа написана в виде меню на английском языке: пользователю будет предоставлена возможность сначала обозначить размер доски, а после выбрать тип фигур и их количество для дальнейшей работы с ними. Комментарии к программе написаны также на английском языке.
  
    if (o==4)  {
+
Ссылка для скачиваний: [http://tm.spbstu.ru/Файлы:Chess_v2.0.zip здесь].
                cout<<endl<<"Конь"<<endl;
 
  
                if(a==1)
 
                    {
 
                    cin>>y;
 
                    vsevarintyrasstavitnfigur(0,y);
 
                    }
 
                    if (a==2)
 
                    maxfig();
 
  
              }
+
'''[[Козловская Анна]]'''
  
    if (o==5)   {
+
'''Краткое описание алгоритма:''' Доска представлена в виде динамического массива[m;m], при выводе на экран пустые клетки обозначаются звездочками,а клетки, заполненные фигурами-буквами(каждая буква соответствует первой букве названия фигуры на английском языке). Для всех фигур написаны алгоритмы проверки на возможность расстановки фигуры. После выбора типа фигуры,используется рекурсивная функция,которая проверяет возможные расстановки через данную функцию проверки ,для данного типа фигуры. Во втором варианте работы программы,она аналитически высчитывает максимально возможное количество заданных фигур на доске.В программу встроена функция,проверяющая доску на повторные и симметричные относительно всех осей симметрии способы расстановки фигур.
                cout<<"Король"<<endl;
 
  
                if(a==1)
+
'''Инструкция:''' В меню указывается два варианта развития событий. Пользователь должен выбрать один из путей. Он вводит размер доски и тип фигуры и кол-во фигур(для первого типа работы программы).Если он выбирает первый вариант работы программы  - вывод всех различных расстановок N фигур.Другой вариант работы программы максимальное число расстановок- программа выводит их количество.
                {
 
                    cin>>y;
 
                    vsevarintyrasstavitnfigur(0,y);
 
  
                }
+
Скачать можно  [http://tm.spbstu.ru/File:Chess3.rar тут].
                if (a==2)
 
  
                      maxfig();
 
  
                }
+
'''[[Абрамов Игорь]]'''
  
            }
+
'''Алгоритм''': в зависимости от выбранного режима работы, после ввода пользователем необходимой информации о размере поля а также типе расставляемых фигур, запускается основная рекурсивная функция, которая либо подсчитывает все возможные расстановки для заданного числа фигур и выводит их в файл, либо рассчитывает максимально возможное расставляемое число фигур. В первом режиме это происходит путём установки фигуры в свободную клетку и отметки клеток, которые бьются данной фигурой, затем запускается эта же функция для оставшихся клеток и т.д., пока число поставленных фигур не дойдёт до числа, заданного пользователем. Тогда эта расстановка выводится в файл и счётчик числа расстановок увеличивается на единицу. Во втором режиме как только находится расстановка для данного количества фигур, функция завершает свою работу, увеличивается счётчик количества фигур и функция вызывается уже для большего количества фигур, пока не будет найдено максимально возможное расставляемое на данной доске число фигур. 
}
 
  
 +
'''Инструкция''': В меню пользователю предлагается указать размеры доски, тип расставляемых фигур и режим работы программы. После этого, если был выбран режим вывода всех расстановок, необходимо ввести количество расставляемых фигур, после чего программа выведет на экран количество расстановок, а в файле "output.txt" появятся изображения всех расстановок. При выборе второго режима, на экран будет выведено максимальное число фигур заданного типа, которые можно расставить на данной доске.
  
</syntaxhighlight>
+
Ссылка для скачивания:[http://tm.spbstu.ru/File:Chess_Abramov.rar]
</div>
 
  
'''[[Тимошенко Валентина]]'''
+
<br>'''[[Нарядчиков Александр]]'''<br>
 +
'''Инструкция:''' Запустить программу, следовать указаниям, полученным в меню программы.<br>
 +
'''Описание программы:''' Шахматное поле представлено в виде двумерного массив N на M, значения N и M пользователь вводит самостоятельно, память выделяется динамически. Также пользователь выбирает тип и количество фигур на поле. В меню можно выбрать между поиском максимально возможного числа фигур на столе и поиском всех расстановок с дальнейшей записью полей в файл.<br>
 +
'''Описание алгоритма:''' При поиске всех расстановок происходит установка выбранной фигуры в свободную клетку, далее происходит маркирование тех клеток, в которые уже невозможно поставить фигуру данного типа, затем процесс происходит снова(рекурсия) пока на поле не окажется выбранное пользователем число фигур. Под конец данное поле записывается в файл и происходит поиск других возможных расстановок данного типа. В конце получаем файл со всеми вариантами расстановок и их количеством. При поиске наибольшего числа фигур на доске программа ищет расстановку для одной фигуры, затем для двух, если это возможно и т.д. С каждым разом происходит увеличение счетчика количества фигур на поле, тем самым в конце данного алгоритма мы получаем максимально возможное число данного типа фигур на доске данного размера.<br>
 +
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
"'''T04CHESS.CPP'''"
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
/* FILENAME: T04CHESS.CPP
 +
* LAST UPDATE: 17.01.2016
 +
*/
  
'''Краткое описание алгоритма''': доска представлена в виде динамического массива, при выводе на экран пустые клетки обозначаются точками, а клетки, заполненные фигурами, обозначаются буквами (каждая буква соответствует первой букве названия фигуры на английском языке). Для каждой фигуры написаны функции проверки на возможность установки фигуры и функции расстановки. Кроме того, программа аналитически считает максимальное количество фигур для доски заданного пользователем размера и, при наличии команды пользователя, выводит все возможные расстановки рассчитанного максимального количества фигур на экран.
+
#include "CHESS.h"
  
'''Инструкция''': при запуске программа предлагает пользователю ввести размер доски, при этом число должно быть четным (если же пользователь вводит нечетное число, программа предлагает ввести размер еще раз, и так до тех пор, пока не будет введено четное число). Далее пользователь выбирает режим работы программы - либо расстановка фигур, либо расчет максимального количества фигур. В режиме расстановки фигур программа предлагает выбрать тип фигуры, выводит максимальное число фигур для доски заданного размера и предлагает ввести желаемое число фигур для расстановки (если оно больше максимального, предлагается повторная попытка ввода). В режиме расчета максимального числа программа предлагает выбрать тип фигуры, выводит рассчитанное число и задает вопрос о необходимости вывода всех возможных расстановок максимального количества для данной фигуры. Оба режима работают (т.е. все запросы повторяются) до тех пор, пока пользователь не даст команду на завершение цикла. Кроме того, в программе есть возможность изменения размера доски после выхода из всех циклов. При положительном ответе пользователя и изменении размера доступны оба режима работы.
+
/* Main function */
 +
int main( void )
 +
{
 +
// Переменная, отвечающая за выход из меню
 +
int IsReady = 1;
 +
// Количество строк поля; количество столбцов поля
 +
int N, M;
 +
// Если идет поиск всех расстановок - 0; если идет поиск максимального числа фигур на доске - 1
 +
int IsCount;
 +
// Количество фигур на поле
 +
int Number;
 +
// Тип фигуры; количество разных расстановок; максимальное число фигур на доске
 +
int tmp, count, max_value = 1;
 +
// Создание указателя на тип FILE
 +
FILE *F;
  
Скачать можно  [http://tm.spbstu.ru/Файл:Chessboard.zip здесь].
+
// Консольное меню
 +
while (IsReady == 1)
 +
{
 +
cout << "Input figure type:\n1 - castle\n2 - bishop\n3 - knight\n4 - queen\n5 - king\n";
 +
cin >> tmp;
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
cout << "Input number of rows on the field:\n";
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
cin >> N;
  
#include <iostream> ///расстановка одинаковых шахматных фигур одного цвета на доске произвольного размера так, чтобы они друг друга не били
+
cout << "Input number of columns on the field:\n";
#include <cstring>
+
cin >> M;
#include <cstdlib>
 
#include <ctime>
 
  
using namespace std;
+
// Поле шахмат
int result_count = 0; ///переменная, в которую закладывается номер варианта расстановки фигур
+
chess desk(N, M);
int N; ///то количество фигур для расстановки, которое задает пользователь
 
int **Board; ///двумерный массив для отображения шахматной доски
 
int M; /// размер шахматной доски
 
  
///Функция вывода доски
+
// Обнуление поля
void showBoard(string F) ///данная функция отображает доску
+
desk.Clear();
{
 
    for(int i = 0; i < M; ++i) /// цикл, прогоняющий значения по строкам
 
    {
 
        for(int j = 0; j < M; ++j)  /// цикл, прогоняющий значения по столбцам
 
            cout << ((Board[i][j]) ? F : "."); ///заполнение как строки, так и столбца символом, который обозначает позицию на шахматной доске
 
        cout << endl;                          ///точка - если данная клетка пустая, буква - если в клетке стоит соответствующая фигура
 
    }
 
    cout << "Result # " << ++result_count << "\n\n"; ///вывод номера варианта расположения с последующим переходом на новую строку
 
    return;
 
}
 
  
///Функции проверки и установки для ферзя
+
cout << "Input in what mode do you want to work:\n0 - Searching for all fields variants\n1 - Searching for the maximum number of chessmen\n";
 +
cin >> IsCount;
  
bool tryQueen(int a, int b) /// проверка на возможность поставить фигуру в данную клетку, a- очередная строка, b- очередной столбец
+
// Если идет поиск всех расстановок
{
+
if (IsCount == 0)
    for (int i = 0; i < M; ++i) ///проверка единственности ферзя в строке
+
{
    {
+
cout << "Input number of chessmen on the field:\n";
        if(Board[a][i])
+
cin >> Number;
            return false;
 
    }
 
  
    for(int i = 0; i < M; ++i) ///проверка единственности ферзя в столбце
+
// Создание файла и его открытие
    {
+
fopen_s(&F, "chess.txt", "wt");
        if(Board[i][b])
+
if ((type)(tmp + 1) == 2)
            return false;
+
fputs("Castles' fields:\n", F);
    }
+
else if ((type)(tmp + 1) == 3)
 
+
fputs("Bishops' fields:\n", F);
    for(int i = 1; a-i >= 0 && b-i >= 0; ++i)///проверка единственности ферзя по диагонали влево-вверх
+
else if ((type)(tmp + 1) == 4)
    {
+
fputs("Knights' fields:\n", F);
        if(Board[a-i][b-i])
+
else if ((type)(tmp + 1) == 5)
            return false;
+
fputs("Quenns' fields:\n", F);
    }
+
else if ((type)(tmp + 1) == 6)
 +
fputs("Kings' fields:\n", F);
 +
else
 +
{
 +
fputs("Error\n", F);
 +
return 0;
 +
}
 +
// Закрытие файла
 +
fclose(F);
  
    for(int i = 1; a+i < M && b+i < M; ++i)///проверка единственности ферзя по диагонали вправо-вниз
+
// Количество разных расстановок
    {
+
count = desk.FillField(IsCount, (type)(tmp + 1), 0, 0, Number, 0);
        if(Board[a+i][b+i])
 
            return false;
 
    }
 
  
    for(int i = 1; a+i < M && b-i >= 0; ++i)///проверка единственности ферзя по диагонали влево-вниз
+
// Открытие файла в режиме повторной записи
    {
+
fopen_s(&F, "chess.txt", "at");
        if(Board[a+i][b-i])
+
fprintf(F, "\nNumber of fields: %i", count);
            return false;
+
// Закрытие файла
    }
+
fclose(F);
  
    for(int i = 1; a-i >= 0 && b+i < M; ++i)///проверка единственности ферзя по диагонали вправо-вверх
+
cout << "Done!\nCheck 'chess.txt' to see results\n";
    {
+
}
        if(Board[a-i][b+i])
 
            return false;
 
    }
 
  
    return true; ///если в ходе проверки ферзей и угроз не обнаружилось, в данную клетку можно поставить фигуру
+
// Если идет поиск максимального числа фигур на доске
}
+
else if (IsCount == 1)
 
+
{
void setQueen(int a, int count) ///функция расстановки ферзей; a - очередная строка, count - счетчик количества фигур, которое необходимо расставить
+
while (desk.FillField(IsCount, (type)(tmp + 1), 0, 0, max_value, 0))
{
+
max_value++;
    for(int b = 0; b < M; ++b) ///b - очередной столбец, расстановка идет по строкам
+
cout << "The maximum number of chessmen on the board is " << (max_value - 1) << endl;
    {
+
max_value = 1;
        if(tryQueen(a, b)) ///проверка данной клетки на возможность установки фигуры
+
}
        {
 
            Board[a][b] = 1; ///установка ферзя в первую клетку поля, присваивание ей значения 1 (true)
 
  
            for(int i = a + 1; i < M; ++i) ///расстановка указанного пользователем количества фигур
+
// Если было введено некорректное значение для IsCount
                setQueen(i,count+1);
+
else
 +
cout << "Error\n";
  
            if(count+1 == N) /// если нужное количество фигур поставлено, то
+
// Продолжение работы с программой
                showBoard("Q"); /// вызов функции вывода шахматной доски на экран
+
cout << "Press '1' if you want to continue\nPress another number if you want to exit\n";
 +
cin >> IsReady;
  
            Board[a][b]=0; ///обнуление переменной для установки следующей фигуры в следующую клетку
+
if (IsReady == 1)
        }
+
continue;
    }
+
else
}
+
exit(0);
 +
}
  
///Функции проверки и установки для ладьи
+
return 0;
 +
} // End of 'main' function
  
bool tryRook(int a, int b) /// проверка на возможность поставить фигуру в данную клетку, a- очередная строка, b- очередной столбец
+
// END OF 'T04CHESS.CPP' FILE
{
+
</syntaxhighlight>
    for (int i = 0; i < M; ++i) ///проверка единственности ладьи в строке
+
"'''CHESS.CPP'''"
    {
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
        if(Board[a][i])
+
/* FILENAME: CHESS.CPP
            return false;
+
* LAST UPDATE: 17.01.2016
    }
+
*/
  
    for(int i = 0; i < M; ++i) ///проверка единственности ладьи в столбце
+
#include "CHESS.H"
    {
 
        if(Board[i][b])
 
            return false;
 
    }
 
  
    return true; ///если в ходе проверки ладей и угроз не обнаружилось, в данную клетку можно поставить фигуру
+
// Количество расстановок
}
+
int Result_count = 0;
  
void setRook(int a, int count) ///функция расстановки ладей; a - очередная строка, count - счетчик количества фигур, которое необходимо расставить
+
/* Clear field function */
 +
// Обнуление поля
 +
void chess::Clear( void )
 
{
 
{
    for(int b = 0; b < M; ++b) ///b - очередной столбец, расстановка идет по строкам
+
// Все клетки свободны
    {
+
for (int i = 0; i < N; i++)
        if(tryRook(a, b)) ///проверка данной клетки на возможность установки фигуры
+
for (int j = 0; j < M; j++)
        {
+
Field[i][j] = Free;
            Board[a][b] = 1; ///установка ладьи в первую клетку, присваивание ей значения 1 (true)
+
} // End of 'Clear' function
  
            for(int i = a + 1; i < M; ++i) ///расстановка указанного пользователем количества фигур
+
/* Check if the cell is available that function */
                setRook(i,count+1);
+
// Проверка, свободна и существует ли данная клетка
 +
int chess::IsAvailable( int x, int y )
 +
{
 +
if (x >= 0 && y >= 0 && x < M && y < N)
 +
if (Field[y][x] == Free)
 +
  return 1;
 +
 +
return 0;
 +
} // End of 'IsAvailable' function
  
            if(count+1 == N) /// если нужное количество фигур поставлено, то
+
/* Output field in file function */
                showBoard("R"); /// вызов функции вывода шахматной доски на экран
+
// Запись одного поля в файл
 +
void chess::OutputInFile( void )
 +
{
 +
// Создание указателя на тип FILE
 +
FILE *F;
  
            Board[a][b]=0; ///обнуление переменной для установки следующей фигуры в следующую клетку
+
// Открытие файла в режиме повторной записи
        }
+
fopen_s(&F, "chess.txt", "at");
    }
 
}
 
  
///Функции проверки и установки для слона
+
// Переход на следующую строку файла
 +
fputc('\n', F);
  
bool tryEl(int a, int b) /// проверка на возможность поставить фигуру в данную клетку, a- очередная строка, b- очередной столбец
+
// Заполнение файла текущем полем
{
+
for (int i = 0; i < N; ++i)
    for(int i = 1; a-i >= 0 && b-i >= 0; ++i)///проверка единственности слона по диагонали влево-вверх
+
{
    {
+
// '*' - свободная клетка; '#' - клетка, которая уже занята
        if(Board[a-i][b-i])
+
for (int j = 0; j < M; ++j)
            return false;
+
(Field[i][j] == Free || Field[i][j] == busy) ? fputc('*', F) : fputc('#', F);
    }
+
// Переход на следующую строку файла
 +
fputc('\n', F);
 +
}
  
    for(int i = 1; a+i < M && b+i < M; ++i)///проверка единственности слона по диагонали вправо-вниз
+
// Закрытие файла
    {
+
fclose(F);
        if(Board[a+i][b+i])
+
} /* End of 'OutputInFile' function */
            return false;
 
    }
 
  
    for(int i = 1; a+i < M && b-i >= 0; ++i)///проверка единственности слона по диагонали влево-вниз
+
/* Copy desks function */
    {
+
// Копирование поля
        if(Board[a+i][b-i])
+
void chess::Copy( chess &desk2 )
            return false;
+
{
    }
+
  for (int i = 0; i < N; i++)
 +
for (int j = 0; j < M; j++)
 +
desk2.Field[i][j] = Field[i][j];
 +
} // End of 'Copy' function
  
    for(int i = 1; a-i >= 0 && b+i < M; ++i)///проверка единственности слона по диагонали вправо-вверх
+
/* Fill field function */
    {
+
// Заполнение полей и поиск максимального числа расстановок
        if(Board[a-i][b+i])
+
// Chessmen_num - количество фигур, которое нужно поставить; Already_stood - количество, которое уже стоит
            return false;
+
int chess::FillField( int IsCount, type set, int x, int y, int Chessmen_num, int Already_stood )
    }
 
 
 
    return true; ///если в ходе проверки слонов и угроз не обнаружилось, в данную клетку можно поставить фигуру
 
}
 
void setEl(int dia, int count) ///функция расстановки слонов; line - очередная строка, count - счетчик количества фигур, которое необходимо расставить
 
 
{
 
{
    ///dia - очередная диагональ, которую нужно исследовать на наличие фигуры и угрозы
+
int i, j, k, l;
    int a, b; ///клетка, с которой начинается расстановка, a- очередная строка, b- очередной столбец
+
chess desk2(N, M);
  
    if (dia < M) ///условие, что клеткa данной диагонали лежат на доске
+
// Обнуление поля
    {
+
desk2.Clear();
        a = dia; ///начало отсчёта диагоналей, цикл движется по строке
 
        b = 0; ///обнуление переменной для столбца, цикл движется по столбцу
 
    }
 
  else ///если клеткa данной диагонали выходит за размер доски (когда цикл по строке доберется до конца
 
    {
 
        a = M-1; ///самая последняя диагональ
 
        b =(dia % M)+1; ///соответственно расчёт переменной для столбца этой диагонали
 
    }
 
  
    for(int i=0; a-i>=0 && b+i < M; ++i)/// цикл движется по строкам и столбцам снизу слева вправо вверх
+
// Пробег по всем оставшимся клеткам поля, начиная с той, на которой мы закончили предыдущую итерацию
    {
+
for (i = y; i < N; i++)
        int line = a-i; ///строковая координата данной клетки диагонали
+
for (j = ((i == y) ? x : 0); j < M; j++)
        int column = b+i; ///столбцовая координата данной клетки диагонали
+
{
 
+
// Если клетка свободна
        if(tryEl(line, column))/// проверка на единственность слона по диагоналям
+
if (Field[i][j] == Free)
        {
+
{
            Board[line][column]=1; ///установка слона в первую клетку, присваивание ей значения 1 (true)
+
// Копируем доску
 
+
Copy(desk2);
            for(int i = dia + 1; i<2*M-1; ++i) ///расстановка указанного пользователем количества фигур
+
                setEl(i,count+1);
+
// Множественный выбор типа фигуры
 
+
switch (set)
            if(count+1 == N) /// если нужное количество фигур поставлено, то
+
{
                showBoard("E"); /// вызов функции вывода шахматной доски на экран
+
// Ладья
 
+
case castle:
            Board[line][column]=0; ///обнуление переменной для установки следующей фигуры в следующую клетку
+
for (k = 0; k < N; k++)
        }
+
{
    }
+
// Движение по столбцу
}
+
if (desk2.Field[k][j] == Free)
 
+
  desk2.Field[k][j] = busy;
///Функции проверки и установки для коня
+
// Движение по строке
 
+
if (desk2.Field[i][k] == Free)
bool tryHorse(int a, int b) /// проверка на возможность поставить фигуру в данную клетку, a- очередная строка, b- очередной столбец
+
  desk2.Field[i][k] = busy;
{
+
}
    ///проверка на наличие фигур и угроз во всех 8 точках, которые могут быть под ударом в квадрате 5х5 вокруг установленной фигуры
+
break;
 
+
// Слон
    if ((a-1) >=0 && (b-2)>=0 && Board[a-1][b-2])
+
case bishop:
        return false;
+
// Выбор и поиск наибольшей существующей на поле диагонали
 
+
for (k = 1 - (N < M ? N : M); k < (N < M ? N : M); k++)
    if ((a-1)>=0 && (b+2) < M && Board[a-1][b+2])
+
{
        return false;
+
// Проход из левого верхнего угла до правого нижнего
 
+
if (IsAvailable(j + k, i + k))
    if ((a+1) < M && (b-2) >=0 && Board[a+1][b-2])
+
desk2.Field[i + k][j + k] = busy;
        return false;
+
// Проход из левого нижнего до правого верхнего
 
+
if (IsAvailable(j + k, i - k))
    if ((a+1) < M && (b+2) < M && Board[a+1][b+2])
+
desk2.Field[i - k][j + k] = busy;
        return false;
+
}
 
+
break;
    if ((a-2) >=0 && (b-1) >=0 && Board[a-2][b-1])
+
// Конь
        return false;
+
case knight:
 
+
// Ходы коня, k - приращение по X, l - по Y
    if ((a-2) >=0 && (b+1) < M && Board[a-2][b+1])
+
k = -2, l = 1;
        return false;
+
// Проверка возможности хода в данную клетку
 
+
if (IsAvailable(j + k, i + l))
    if ((a+2) < M && (b-1) >= 0 && Board[a+2][b-1])
+
desk2.Field[i + l][j + k] = busy;
        return false;
+
 
+
k = -2, l = -1;  
    if ((a+2) < M && (b+1) < M && Board[a+2][b+1])
+
// Проверка возможности хода в данную клетку
        return false;
+
if (IsAvailable(j + k, i + l))
 
+
desk2.Field[i + l][j + k] = busy;
    return true; ///если в ходе проверки коней и угроз не обнаружилось, в данную клетку можно поставить фигуру
+
}
+
k = -1, l = 2;  
 
+
// Проверка возможности хода в данную клетку
void setHorse(int count, int a, int b) ///функция расстановки коней; a - очередная строка, b - очередной столбец, count - счетчик количества фигур, которое необходимо расставить
+
if (IsAvailable(j + k, i + l))
{
+
desk2.Field[i + l][j + k] = busy;
    if(count==N) /// если нужное количество фигур поставлено, то
+
    {
+
k = -1, l = -2;  
        showBoard("H"); /// вызов функции вывода шахматной доски на экран
+
// Проверка возможности хода в данную клетку
    }
+
if (IsAvailable(j + k, i + l))
 
+
desk2.Field[i + l][j + k] = busy;
    if (a == M) ///условие необходимо; прогоняет алгоритм по всем строкам
+
        return;
+
k = 1, l = 2;  
 
+
// Проверка возможности хода в данную клетку
    for (int j=b; j<M; ++j) ///установка коней в первой строке
+
if (IsAvailable(j + k, i + l))
    {
+
desk2.Field[i + l][j + k] = busy;
        if(tryHorse(a, j)) ///проверка данной клетки на возможность установки фигуры
+
        {
+
k = 1, l = -2;  
            Board[a][j]=1; ///установка коня в первую клетку, присваивание ей значения 1 (true)
+
// Проверка возможности хода в данную клетку
            int line = a, b = j+1; ///смещение в строке на одну позицию вправо, переобозначение строки на line
+
if (IsAvailable(j + k, i + l))
 
+
desk2.Field[i + l][j + k] = busy;
            if (b == M) ///если данный столбец - самый крайний
+
            {
+
k = 2, l = 1;  
                b = 0; ///обнуление переменной, чтобы использовать ее при заполнении следующей строки
+
// Проверка возможности хода в данную клетку
                line++;     ///то переход на следующую строку и дальнейшее ее заполнение
+
if (IsAvailable(j + k, i + l))
            }
+
desk2.Field[i + l][j + k] = busy;
            setHorse(count+1,line,b); ///установка фигуры, увеличение счетчика
+
            Board[a][j]=0; ///обнуление переменной для установки следующей фигуры в следующую клетку
+
k = 2, l = -1;
        }
+
// Проверка возможности хода в данную клетку
    }
+
if (IsAvailable(j + k, i + l))
 
+
desk2.Field[i + l][j + k] = busy;
    for(int i=a+1; i<M; ++i) ///дальнейшее заполнение оставшихся строк
+
break;
    {
+
// Ферзь
        for (int j=0; j<M; ++j)
+
case queen:
        {
+
for (k = 0; k < N; k++)
            if(tryHorse(i, j)) ///проверка данной клетки на возможность установки фигуры
+
{
            {
+
// Движение по столбцу
                Board[i][j]=1; ///установка коня в первую клетку, присваивание ей значения 1 (true)
+
if (desk2.Field[k][j] == Free)
                int line = i, b = j+1; ///смещение в строке на одну позицию вправо
+
desk2.Field[k][j] = busy;
 
+
// Движение по строке
                if (b == M) ///если данный столбец - самый крайний
+
if (desk2.Field[i][k] == Free)
                {
+
desk2.Field[i][k] = busy;
                    b = 0;
+
}
                    line++; ///то переход на следующую строку и дальнейшее ее заполнение
+
                }
+
// Выбор и поиск наибольшей существующей на поле диагонали
                setHorse(count+1,line,b); ///установка фигуры, увеличение счетчика
+
for (k = 1 - (N < M ? N : M); k < (N < M ? N : M); k++)
                Board[i][j]=0; ///обнуление переменной для установки следующей фигуры в следующую клетку
+
{
            }
+
// Проход из левого верхнего угла до правого нижнего
        }
+
if (IsAvailable(j + k, i + k))
    }
+
desk2.Field[i + k][j + k] = busy;
}
+
// Проход из левого нижнего до правого верхнего
 +
if (IsAvailable(j + k, i - k))
 +
desk2.Field[i - k][j + k] = busy;
 +
}
 +
break;
 +
// Король
 +
case king:
 +
  // Проход по квадрату 3 на 3, построенному центром на клетке, в которой стоит король
 +
for (k = -1; k < 2; k++)
 +
for (l = -1; l < 2; l++)
 +
if (IsAvailable(j + k, i + l))
 +
desk2.Field[i + l][j + k] = busy;
 +
break;
 +
}
 +
// Установка фигуры в данную клетку
 +
desk2.Field[i][j] = set;
 +
       
 +
// Проверяем, что количество поставленных фигур, которое равно номеру итерации, меньше чем необходимое число фигур
 +
if ((Already_stood + 1) < Chessmen_num)
 +
{
 +
// Если идет поиск всех расстановок, то запускаем следующий шаг
 +
if (IsCount == 0)
 +
desk2.FillField(IsCount, set, j, i, Chessmen_num, Already_stood + 1);
 +
// Если идет поиск максимального числа фигур на доске и была найдена хотя бы одна расстоновка, то возвращаем 1
 +
else if ((IsCount == 1) && desk2.FillField(IsCount, set, j, i, Chessmen_num, Already_stood + 1))
 +
return 1;
 +
}
  
///для короля
+
// Если количество поставленных фигур равно необходимому числу фигур
 
+
else if ((Already_stood + 1) == Chessmen_num)
bool tryKing(int a, int b) /// проверка на возможность поставить фигуру в квадрате 3х3, a- очередная строка, b- очередной столбец
+
{
{
+
// Если идет поиск всех расстановок, то увеличиваем количество расстоновок на одну и записываем поле в файл 
///проверка на наличие фигур и угроз во всех 8 точках, которые могут быть под ударом в квадрате 3х3 вокруг установленной фигуры
+
if (IsCount == 0)
 
+
{
    for(int i = a-1; i <= a+1; ++i) ///проверка по строкам
+
Result_count++;
    {
+
  desk2.OutputInFile();
        for(int j = b-1; j <= b+1; ++j) ///проверка по столбцам
+
}
        {
+
// Если идет поиск максимального числа фигур на доске, значит расстановка существует, возвращаем 1
            if (a>=0 && a < M && b>=0 && b < M && Board[a][b]) ///условие наличия клетки в пределах доски
+
else if (IsCount == 1)
                return false;
+
return 1;
 +
  }
 +
}
 +
}
 +
// Если идет поиск всех расстановок, то возвращаем количество расстановок
 +
if (IsCount == 0)
 +
  return Result_count;
 +
// Если идет поиск максимального числа фигур на доске, то возвращаем 0
 +
else if (IsCount == 1)
 +
  return 0;
 +
} // End of 'FillField' function
  
            if ((a+1) < M && (b-1) >=0 && Board[a+1][b-1])
+
// END OF 'CHESS.CPP' FILE
                return false;
+
</syntaxhighlight>
 +
"'''CHESS.H'''"
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
/* FILENAME: CHESS.H
 +
* LAST UPDATE: 17.01.2016
 +
*/
  
            if ((a+1) < M && Board[a+1][b])
+
#ifndef __CHESS_H_
                return false;
+
#define __CHESS_H_
  
            if ((a+1) < M && (b+1) < M && Board[a+1][b+1])
+
#include <iostream>
                return false;
+
#include <conio.h>
  
            if ((b+1) < M && Board[a][b+1])
+
using namespace std;
                return false;
 
  
            if ((a-1)>=0 && (b+1) < M && Board[a-1][b+1])
+
// свободен, занят, ладья, слон, конь, ферзь, король
                return false;
+
enum type { Free, busy, castle, bishop, knight, queen, king };
  
            if ((a-1) >=0 && Board[a-1][b])
+
/* Chess class */
                return false;
+
class chess
 
+
{
            if ((a-1) >=0 && (b-1)>=0 && Board[a-1][b-1])
+
private:
                return false;
+
// Поле данных фигур
 +
type **Field;
 +
// Количество строк поля; количество столбцов поля
 +
int N, M;
 +
public:
 +
/* Default constructor */
 +
chess( void )
 +
{
 +
N = 8, M = 8;
 +
 +
// Выделение памяти под массив поля
 +
Field = new type*[N];
 +
for (int i = 0; i < N; i++)
 +
Field[i] = new type[M];
 +
}
 +
 +
/* Class constructor */
 +
chess( int _N, int _M ) : N(_N), M(_M)
 +
{
 +
// Выделение памяти под массив поля
 +
Field = new type* [N];
 +
for (int i = 0; i < N; i++)
 +
Field[i] = new type [M];
 +
}
  
            if ((b-1) >= 0 && Board[a][b-1])
+
/* Class destructor */
                return false;
+
~chess( void )
        }
+
{
    }
+
// Чистка памяти
 +
for (int i = 0; i < N; i++)
 +
delete[] Field[i];
 +
delete[] Field;
 +
}
  
    return true; ///если в ходе проверки королей и угроз не обнаружилось, в данную клетку можно поставить фигуру
+
/* Clear field function */
}
+
void Clear( void );
 
+
void setKing (int count, int a, int b) ///функция расстановки коней; a - очередная строка, b - очередной столбец, count -  счетчик количества фигур, которое необходимо расставить
+
/* Check if the cell is available that function */
{
+
int IsAvailable( int x, int y );
    for (int j=b; j<M; ++j)  ///установка королей в первой строке
+
    {
+
/* Output field in file function */
        if(tryKing(a, j)) ///проверка данной клетки на возможность установки фигуры
+
void OutputInFile( void );
        {
+
            Board[a][j]=1; ///проверка данной клетки на возможность установки фигуры
+
/* Copy desks function */
            setKing(count+1,a,j); ///расстановка фигур в первой строке
+
void Copy( chess& desk2 );
            Board[a][j]=0; ///обнуление переменной для установки следующей фигуры в следующую клетку
+
        }
+
/* Fill field function */
    }
+
int FillField ( int IsCount, type set, int x, int y, int Chessmen_num, int Already_stood);
 +
}; // end of 'chess' class
 +
 
 +
#endif /*__CHESS_H_ */
  
    for(int i=a+1; i<M; ++i) ///установка фигур в оставшуюся часть шахматной доски по строкам
+
// END OF 'CHESS.H' FILE
    {
+
</syntaxhighlight>
        for (int j=0; j<M; ++j)
+
</div>
        {
+
[http://tm.spbstu.ru/File:T04CHESS.7z Скачать архив]
            if(tryKing(i, j)) ///проверка данной клетки на возможность установки фигуры
+
<br>
            {
 
                Board[i][j]=1; ///проверка данной клетки на возможность установки фигуры
 
                setKing(count+1,i,j); ///расстановка фигур
 
                Board[i][j]=0;  ///обнуление переменной для установки следующей фигуры в следующую клетку
 
            }
 
        }
 
    }
 
  
    if(count==N) /// если нужное количество фигур поставлено, то
 
    {
 
        showBoard("K");/// вызов функции вывода шахматной доски на экран
 
        return;
 
    }
 
}
 
  
int main()
+
'''[[Рубинова Раиса]]'''
{
 
    char s; ///переменная, будет использована в цикле
 
    do      /// цикл, выводящий на экран данные в зависимости от введенных пользователем значений переменных
 
    {
 
        do ///цикл для считывания введенного пользователем размера доски
 
        {
 
            cout << "Input the size of the board: " << endl; ///ввод размера доски
 
            cin >> M;
 
  
            if ( (M%2) == 1) ///цикл, работающий только в том случае, если пользователь введет нечетное число
+
'''Основная идея программы''': программа позволяет выводить на экран всевозможные расстановки n однотипных фигур на шахматной доске размером n*n так, чтобы ни одна из фигур не била другую.
            {
 
                cout << '\n' << "The number must be even, so try to input the size again" << '\n' << endl;
 
            }
 
  
        }
+
Скачать можно [http://tm.spbstu.ru/File:nmk.rar тут.]
        while (M%2 !=0); ///пока пользователь не введет допуcтимое число, цикл не прерывается
 
  
        Board = new int*[M];  ///создание двумерного массива для отображения шахматной доски
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
        for (int i = 0; i<M; i++)
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
            Board[i] = new int[M]; ///создание первую строку доски
+
#include <iostream>
        for (int i = 0; i<M; i++)
+
#include <cstring>
            for (int j = 0; j<M; j++)
+
#include <cstdlib>
                Board[i][j] = 0;  ///зануление массива
+
#include <ctime>
  
        int V; ///пользователь выбирает один из двух вариантов работы программы
+
using namespace std;
        cout << '\n' << "Input your choice: 1=placing of figures, 2=for max amount of figures" << endl;
+
int R = 0; ///переменная, отвечающая за количество вариантов расстановок
        cin >> V;
+
int N; ///количество фигур для расстановки, которое задает пользователь
 +
int **B; ///двумерный массив, отображающий шахматную доску
 +
int M; /// размер шахматной доски
  
        if (V==1) ///цикл, расставляющий фигуры по введенным пользователем данным
 
        {
 
            char k; ///переменная, будет использована в цикле
 
            do      /// цикл, выводящий на экран данные в зависимости от введенных пользователем значений переменных
 
            {
 
                int T; ///пользователь выбирает фигуру
 
                cout << '\n' << "Input type of figure: 1-queen, 2-king, 3-horse, 4-rook, 5-elephant"<< endl;
 
                cin >> T;
 
  
                int maximum; ///переменная, хранящая максимальное количество фигур, которое можно расставить на заданной доске
+
void showBoard() ///функция, выводящая доску на экран
                if (T==1) ///максимальное количество фигур на заданной доске для ферзя
+
{
                {
+
    for(int i=0; i<M; ++i) /// строки
                    maximum=M;
+
    {
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
+
        for(int j=0; j<M; ++j) /// столбцы
                }
+
            {cout << B[i][j] << " ";} ///заполнение клетки с координатами i;j
                if (T==2) ///максимальное количество фигур на заданной доске для короля
+
        cout << endl;
                {
+
    }
                    maximum=0.25*M*M;
+
    cout << "Variant " << ++R << "\n\n"; ///вывод номера варианта расположения с последующим переходом на новую строку
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
+
    return;
                }
+
}
                if (T==3) ///максимальное количество фигур на заданной доске для коня
 
                {
 
                    maximum=0.5*M*M;
 
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
 
                }
 
                if (T==4) ///максимальное количество фигур на заданной доске для ладьи
 
                {
 
                    maximum=M;
 
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
 
                }
 
                if (T==5) ///максимальное количество фигур на заданной доске для слона
 
                {
 
                    maximum=2*M-2;
 
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
 
                }
 
  
                do ///цикл, считывающий количество фигур, заданное пользователем
+
bool checkQueen(int a, int b) /// функция, проверяющая, не бьется ли ферзь другим ферзем
                {
+
{
                    cout << "Input the amount of figures, it must be less than max amount or equals that" << endl;
+
    for (int i = 0; i < M; ++i) ///проверка строки
                    cin >> N;
+
    {
                }
+
        if(B[a][i])
                while (N>maximum);   ///пока пользователь не введет допуcтимое число, цикл не прерывается
+
            return false;
 +
    }
  
                cout << '\n' << "All possible variants for this amount of figures on this board:" << '\n' << endl;
+
    for(int i = 0; i < M; ++i) ///проверка столбца
 +
    {
 +
        if(B[i][b])
 +
            return false;
 +
    }
  
                if (T==1) ///цикл, вызывающий на экран все варианты расстановки заданного пользователем числа фигур для ферзя
+
    for(int i = 1; a-i >= 0 && b-i >= 0; ++i)///по диагонали влево-вверх
                {
+
    {
                    result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
+
        if(B[a-i][b-i])
                    for (int i=0; i <M; ++i)
+
            return false;
                        setQueen(i,0);
+
    }
                }
 
                if (T==2) ///цикл, вызывающий на экран все варианты расстановки заданного пользователем числа фигур для короля
 
                {
 
                    result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 
                    setKing(0,0,0);
 
                }
 
                if (T==3) ///цикл, вызывающий на экран все варианты расстановки заданного пользователем числа фигур для коня
 
                {
 
                    result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 
                    setHorse(0,0,0);
 
                }
 
                if (T==4) ///цикл, вызывающий на экран все варианты расстановки заданного пользователем числа фигур для ладьи
 
                {
 
                    result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 
                    for (int i=0; i <M; ++i)
 
                        setRook(i,0);
 
                }
 
                if (T==5) ///цикл, вызывающий на экран все варианты расстановки заданного пользователем числа фигур для слона
 
                {
 
                    result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 
                    for(int i = 0; i<2*M-1; ++i)
 
                        setEl(i,0);
 
                }
 
  
                cout << '\n' << "If you want continue placing figures, input +, if not, input -" << endl;
+
    for(int i = 1; a+i < M && b+i < M; ++i)///по диагонали вправо-вниз
                cin >> k;
+
    {
             }
+
        if(B[a+i][b+i])
            while (k != '-'); ///цикл работает до тех пор, пока пользователь не даст команду на его завершение
+
            return false;
         }
+
    }
 +
 
 +
    for(int i = 1; a+i < M && b-i >= 0; ++i)///по диагонали влево-вниз
 +
    {
 +
        if(B[a+i][b-i])
 +
             return false;
 +
    }
 +
 
 +
    for(int i = 1; a-i >= 0 && b+i < M; ++i)///по диагонали вправо-вверх
 +
    {
 +
         if(B[a-i][b+i])
 +
            return false;
 +
    }
 +
 
 +
    return true;
 +
}
  
         else if (V==2) ///цикл, вычисляющий максимальное количество фигур по введенным пользователем данным
+
void Queen(int a, int count) ///функция, расстанавливающая ферзи
 +
{
 +
    for(int b = 0; b < M; ++b) /// расстановка по изменению номера столбца
 +
    {
 +
         if(checkQueen(a, b)) ///проверка, бьется ли данная клетка ферзем
 
         {
 
         {
             char z; ///переменная, будет использована в цикле
+
             B[a][b] = 1; ///заполнение первой клетки
             do      /// цикл, выводящий на экран данные в зависимости от введенных пользователем значений переменных
+
             for(int i = a+1; i < M; ++i) ///расстановка указанного пользователем количества фигур
            {
+
                 Queen(i,count+1);
                int T; ///переменная для выбора фигуры пользователем
+
            if(count+1==N) /// проверка, расставили ли мы нужное количество фигур
                 cout << '\n' << "Input type of figure: 1-queen, 2-king, 3-horse, 4-rook, 5-elephant"<< endl;
+
                 showBoard();
                cin >> T;
+
            B[a][b]=0; ///обнуление переменной
                char d;  ///переменная, будет использована в циклах
+
        }
                int maximum; ///переменная, хранящая максимальное количество фигур, которое можно расставить на заданной доске
+
    }
                if (T==1) ///максимальное количество фигур на заданной доске для ферзя
+
}
                 {
+
 
                    maximum=M; ///формула расчёта максимального количества фигур для заданной доски
+
bool checkRook(int a, int b) /// функция, проверяющая ли данную клетку ладья
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
+
{
                    cout << "If you want to see all locations of max amount, input +, if not, input -" << endl;
+
    for (int i = 0; i < M; ++i) ///проверка строки
                    cin >> d;
+
    {
                    cout << '\n' << "All possible variants for this amount of figures on this board:" << '\n' << endl;
+
        if(B[a][i])
                    if (d=='+') ///по выбору пользователя вывод всех возможных расстановок для максимального количества для данной фигуры
+
            return false;
                    {
+
    }
                        result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
+
 
                        N=maximum; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
+
    for(int i = 0; i < M; ++i) ///проверка столбца
                        for (int i=0; i < M; ++i)
+
    {
                            setQueen(i,0);
+
        if(B[i][b])
                    }
+
            return false;
 +
    }
 +
 
 +
    return true;
 +
}
  
                }
+
void Rook(int a, int count) ///функция, расстанавливающая ладьи
                if (T==2) ///максимальное количество фигур на заданной доске для короля
+
{
                {
+
    for(int b = 0; b < M; ++b) /// расстановка по строкам с изменением номера столбца
                    maximum=0.25*M*M; ///формула расчёта максимального количества фигур для заданной доски
+
    {
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
+
        if(checkRook(a, b)) ///проверка, бьется ли данная клетка ладьей
                    cout << "If you want to see all locations of max amount, input +, if not, input -" << endl;
+
        {
                    cin >> d;
+
            B[a][b] = 1; ///установка ладьи
                    cout << '\n' << "All possible variants for this amount of figures on this board:" << '\n' << endl;
+
            for(int i =a+1; i<M; ++i)
                    if (d=='+') ///по выбору пользователя вывод всех возможных расстановок для максимального количества для данной фигуры
+
                Rook(i,count+1);
                    {
+
            if(count+1 == N) /// проверка, расставили ли мы нужное количество элементов
                        result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
+
                 showBoard();
                        N=maximum; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
+
 
                        setKing(0,0,0);
+
            B[a][b]=0; ///обнуление переменной
                    }
+
        }
                }
+
    }
                if (T==3) ///максимальное количество фигур на заданной доске для коня
+
}
                {
+
 
                    maximum=0.5*M*M; ///формула расчёта максимального количества фигур для заданной доски
+
bool checkElephant(int a, int b) /// функция, проверяющая, бьется ли данная клетка слоном
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
+
{
                    cout << "If you want to see all locations of max amount, input +, if not, input -" << endl;
+
    for(int i = 1; a-i >= 0 && b-i >= 0; ++i)///проверка по диагонали влево-вверх
                    cin >> d;
+
    {
                    cout << '\n' << "All possible variants for this amount of figures on this board:" << '\n' << endl;
+
        if(B[a-i][b-i])
                    if (d=='+') ///по выбору пользователя вывод всех возможных расстановок для максимального количества для данной фигуры
+
            return false;
                    {
+
    }
                        result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 
                        N=maximum; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 
                        setHorse(0,0,0);
 
                    }
 
                }
 
                if (T==4) ///максимальное количество фигур на заданной доске для ладьи
 
                 {
 
                    maximum=M; ///формула расчёта максимального количества фигур для заданной доски
 
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
 
                    cout << "If you want to see all locations of max amount, input +, if not, input -" << endl;
 
                    cin >> d;
 
                    cout << '\n' << "All possible variants for this amount of figures on this board:" << '\n' << endl;
 
                    if (d=='+') ///по выбору пользователя вывод всех возможных расстановок для максимального количества для данной фигуры
 
                    {
 
                        result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 
                        N=maximum; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 
                        for (int i=0; i <M; ++i)
 
                            setRook(i,0);
 
                    }
 
                }
 
                if (T==5) ///максимальное количество фигур на заданной доске для слона
 
                {
 
                    maximum=2*M-2; ///формула расчёта максимального количества фигур для заданной доски
 
                    cout << '\n' << "Max amount of figures for this board = " << maximum << '\n' << endl;
 
                    cout << "If you want to see all locations of max amount, input +, if not, input -" << endl;
 
                    cin >> d;
 
                    cout << '\n' << "All possible variants for this amount of figures on this board:" << '\n' << endl;
 
                    if (d=='+') ///по выбору пользователя вывод всех возможных расстановок для максимального количества для данной фигуры
 
                    {
 
                        result_count=0; ///обнуление переменной, выводящей номер решения; необходимо при повторной работе цикла
 
                        N=maximum; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 
                        for(int i = 0; i<2*M-1; ++i)
 
                            setEl(i,0);
 
                    }
 
                }
 
  
                cout << '\n' << "If you want continue counting, input +, if not, input -" << '\n' << endl;
+
    for(int i = 1; a+i < M && b+i < M; ++i)///проверка по диагонали вправо-вниз
                cin >> z;
+
    {
            }
+
         if(B[a+i][b+i])
            while (z != '-'); ///цикл работает до тех пор, пока пользователь не даст команду на его завершение
+
             return false;
        }
 
        cout << '\n' << "If you want to change the size of board, input +, if not, input -" << endl;
 
        cin >> s;
 
         if (s=='-')
 
        {
 
             cout << '\n' << "The program is finished." << '\n' << endl; ///вывод на экран сообщения о завершении работы программы
 
        }
 
 
     }
 
     }
    while (s != '-'); ///цикл работает до тех пор, пока пользователь не даст команду на его завершение, а также на завершение всей программы
 
}
 
  
</syntaxhighlight>
+
    for(int i = 1; a+i < M && b-i >= 0; ++i)///проверка по диагонали влево-вниз
</div>
+
    {
 +
        if(B[a+i][b-i])
 +
            return false;
 +
    }
  
'''[[Уманский Александр]]'''
+
    for(int i = 1; a-i >= 0 && b+i < M; ++i) ///проверка по диагонали вправо-вверх
 +
    {
 +
        if(B[a-i][b+i])
 +
            return false;
 +
    }
 +
 
 +
    return true;
 +
}
 +
void Elephant(int dia, int count) ///функция, расстанавливающая слоны
 +
{
 +
    int a, b; /// задача клетки, соответствующекй данной диагонали
 +
    if (dia < M) /// проверка диагонали
 +
    {
 +
        a = dia; /// номер строки - номер диагонали
 +
        b = 0; ///обнуление переменной для столбца, цикл движется по столбцу
 +
    }
 +
  else ///если все диагонали рассмотрены
 +
    {
 +
        a = M-1; /// рассматриваем самую последнюю диагональ
 +
        b =(dia % M)+1; ///рассчитываем координату столбца для данной диагонали
 +
    }
 +
 
 +
    for(int i=0; a-i>=0 && b+i < M; ++i)/// цикл движется по строкам и столбцам из нижнего левого угла в правый верхний
 +
    {
 +
        int line=a-i; ///координата строки (мы уменьшаем координату строки)
 +
        int column=b+i; ///координата столбца  (но увеличиваем координату столбца)
 +
 
 +
        if(checkElephant(line, column))/// проверка, бьется ли слон по диагонали
 +
        {
 +
            B[line][column]=1; ///установка слона
 +
 
 +
            for(int i=dia+1; i<2*M-1; ++i) ///расстановка фигур, основанная на изменении параметров (номера диагонали и количества рсставленных фигур)
 +
                Elephant(i,count+1);
 +
 
 +
            if(count+1 == N) /// проверка количества расставленных фигур
 +
                showBoard();
  
'''Работа программы''': Программа предлагает 2 режима работы 1 режим это нахождение для 1 из 5 фигур таких расстановок L фигур, на доске M*N, что они не бьют друг друга, второй режим возможно найти максимальное число фигур, которое можно расставить на этом поле, чтобы они не били друг друга.
+
            B[line][column]=0; ///обнуление переменной
 +
        }
 +
    }
 +
}
  
'''Идея алгоритма''': Основная идея заключается в присваиванию клетке 1 из 3 значений, пустая клетка, битая клетка или клетка, в которой стоит фигура.
+
bool checkHorse(int a, int b) /// функция, проверяющая, бьется ли данная клетка конями
В точку ставится фигура, дальше маркируются поля, в которые уже невозможно поставить фигуру, затем мы ставим следующую фигуру и снова маркируем поля, в которые не можем ничего поставить и так далее до нужного пользователю числа фигур. Поиск максимального числа это попытка поставить на доску как можно больше фигур, он пользуется алгоритмами первого пункта.
+
{
 +
    if ((a-1) >=0 && (b-2)>=0 && B[a-1][b-2])
 +
        return false;
 +
 
 +
    if ((a-1)>=0 && (b+2) < M && B[a-1][b+2])
 +
        return false;
 +
 
 +
    if ((a+1) < M && (b-2) >=0 && B[a+1][b-2])
 +
        return false;
 +
 
 +
    if ((a+1) < M && (b+2) < M && B[a+1][b+2])
 +
        return false;
 +
 
 +
    if ((a-2) >=0 && (b-1) >=0 && B[a-2][b-1])
 +
        return false;
 +
 
 +
    if ((a-2) >=0 && (b+1) < M && B[a-2][b+1])
 +
        return false;
 +
 
 +
    if ((a+2) < M && (b-1) >= 0 && B[a+2][b-1])
 +
        return false;
 +
 
 +
    if ((a+2) < M && (b+1) < M && B[a+2][b+1])
 +
        return false;
 +
 
 +
    return true;
 +
}
 +
 
 +
void Horse(int count, int a, int b) ///функция расстановки коней; a - очередная строка, b - очередной столбец, count - счетчик количества фигур, которое необходимо расставить
 +
{
 +
    if(count==N) /// проверка количества расставленных фигур
 +
    {
 +
        showBoard();
 +
    }
 +
    if (a == M) /// не выходит ли за предел доски
 +
        return;
 +
    for (int j=b; j<M; ++j) ///рассматриваем первую строку
 +
    {
 +
        if(checkHorse(a, j)) ///проверка
 +
        {
 +
            B[a][j]=1; ///установка коня
 +
            int l = a, b = j+1; ///смещение в другой столбец
 +
 
 +
            if (b == M) ///проверка, не крайний ли это столбец, так как тогда мы не можем продолжать расстановку (мы ее завершили)
 +
            {
 +
                b=0; ///обнуление переменной
 +
                l++;    ///переход на следующую
 +
            }
 +
            Horse(count+1,l,b); ///установка фигуры, увеличение счетчика
 +
            B[a][j]=0; ///обнуление переменной для установки следующей фигуры в следующую клетку
 +
        }
 +
    }
 +
    for(int i=a+1; i<M; ++i) ///заполнение строк
 +
    {
 +
        for (int j=0; j<M; ++j)
 +
        {
 +
            if(checkHorse(i, j)) ///проверка клетки, не бьется ли она другими конями
 +
            {
 +
                B[i][j]=1; ///установка коня
 +
                int l = i, b = j+1; ///смещаемся на другой столбец
 +
                if (b == M)
 +
                {
 +
                    b = 0;
 +
                    l++;
 +
                }
 +
                Horse(count+1,l,b); ///установка фигуры с увеличением счетчика
 +
                B[i][j]=0;  ///обнуление переменной
 +
            }
 +
        }
 +
    }
 +
}
 +
 
 +
bool checkKing(int a, int b) /// функция, проверяющая, бьет ли данную клетку король
 +
{
 +
    for(int i = a-1; i <= a+1; ++i)
 +
    {
 +
        for(int j = b-1; j <= b+1; ++j)
 +
        {
 +
            if (a>=0 && a < M && b>=0 && b < M && B[a][b])
 +
                return false;
 +
 
 +
            if ((a+1) < M && (b-1) >=0 && B[a+1][b-1])
 +
                return false;
 +
 
 +
            if ((a+1) < M && B[a+1][b])
 +
                return false;
 +
 
 +
            if ((a+1) < M && (b+1) < M && B[a+1][b+1])
 +
                return false;
 +
 
 +
            if ((b+1) < M && B[a][b+1])
 +
                return false;
 +
 
 +
            if ((a-1)>=0 && (b+1) < M && B[a-1][b+1])
 +
                return false;
 +
 
 +
            if ((a-1) >=0 && B[a-1][b])
 +
                return false;
 +
 
 +
            if ((a-1) >=0 && (b-1)>=0 && B[a-1][b-1])
 +
                return false;
 +
 
 +
            if ((b-1) >= 0 && B[a][b-1])
 +
                return false;
 +
        }
 +
    }
 +
 
 +
    return true;
 +
}
 +
 
 +
void King (int count, int a, int b) ///функция, расставляющая коней
 +
{
 +
    for (int j=b; j<M; ++j)  ///установка королей в первой строке
 +
    {
 +
        if(checkKing(a, j)) ///проверка данной клетки на возможность установки фигуры
 +
        {
 +
            B[a][j]=1; ///если по результатам проверки можно поставить фигуру, то мы ее ставим
 +
            King(count+1,a,j); ///расстановка фигур для первой доски
 +
            B[a][j]=0;  ///обнуление переменной
 +
        }
 +
    }
 +
 
 +
    for(int i=a+1; i<M; ++i) ///расстановка фигур
 +
    {
 +
        for (int j=0; j<M; ++j)
 +
        {
 +
            if(checkKing(i, j)) ///проверка данной клетки на возможность установки фигуры
 +
            {
 +
                B[i][j]=1;  /// если короля можно поставить, то ставим его в данную клетку
 +
                King(count+1,i,j);
 +
                B[i][j]=0;  ///обнуление переменной
 +
            }
 +
        }
 +
    }
 +
 
 +
    if(count==N)
 +
    {
 +
        showBoard();/// вывод шахмат на экран
 +
        return;
 +
    }
 +
}
 +
 
 +
int main()
 +
{
 +
        cout << "Enter the size of the board: " << endl; ///ввод размера доски
 +
        cin >> M;
 +
        B = new int*[M];
 +
        for (int i=0; i<M; i++)
 +
            B[i] = new int[M];
 +
        for (int i = 0; i<M; i++)
 +
            for (int j = 0; j<M; j++)
 +
                B[i][j] = 0;
 +
        int Var;
 +
        cout << '\n' << "1=your number of figures, 2=max number of figures" << endl;
 +
        cin >> Var;
 +
        int F;
 +
                cout << '\n' << "Input type of figure: 1-queen, 2-king, 3-horse, 4-rook, 5-elephant"<< endl;
 +
                cin >> F;
 +
        if (Var==1) /// если пользователь выбрал свое количество фигур, то мы выполняем следующие действия:
 +
        {
 +
                int mn;
 +
                    cout << "Input the number of figures" << endl;
 +
                    cin >> N;
 +
                if (F==1)
 +
                {
 +
                    for (int i=0; i <M; ++i)
 +
                        Queen(i,0);
 +
                }
 +
                if (F==2)
 +
                {
 +
                    King(0,0,0);
 +
                }
 +
                if (F==3)
 +
                {
 +
                    Horse(0,0,0);
 +
                }
 +
                if (F==4)
 +
                {
 +
                    for (int i=0; i <M; ++i)
 +
                        Rook(i,0);
 +
                }
 +
                if (F==5)
 +
                {
 +
                    for(int i = 0; i<2*M-1; ++i)
 +
                        Elephant(i,0);
 +
                }
 +
            }
 +
        else if (Var==2)      /// если пользователь выбрал максимальное количество фигур
 +
        {
 +
                int mn;
 +
                if (F==1)
 +
                {
 +
                    mn=M;
 +
                    cout <<  "Max number " << mn  << endl;  /// выводим максимальное количество фигур
 +
                    N=mn; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 +
                        for (int i=0; i < M; ++i)
 +
                            Queen(i,0);
 +
                    }
 +
 
 +
                if (F==2)
 +
                {
 +
                    mn=0.25*M*M;
 +
                    cout << '\n' << "Max number " << mn <<  endl;
 +
                    N=mn; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 +
                    King(0,0,0);
 +
                    }
 +
                if (F==3)
 +
                {
 +
                    mn=0.5*M*M;
 +
                    cout <<  "Max number " << mn  << endl;
 +
                    N=mn; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 +
                    Horse(0,0,0);
 +
                    }
 +
                if (F==4)
 +
                {
 +
                    mn=M;
 +
                    cout <<  "Max number " << mn  << endl;
 +
                    N=mn; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 +
                        for (int i=0; i <M; ++i)
 +
                            Rook(i,0);
 +
                    }
 +
                if (F==5)
 +
                {
 +
                    mn=2*M-2;
 +
                    cout <<  "Max number " << mn  << endl;
 +
                    N=mn; ///приравниваем количество фигур для установки максимально возможному, рассчитанному по формуле выше
 +
                        for(int i = 0; i<2*M-1; ++i)
 +
                            Elephant(i,0);
 +
                    }
 +
                }
 +
    }
 +
 
 +
 
 +
 
 +
</syntaxhighlight>
 +
</div>
 +
 
 +
 
 +
'''[[Уманский Александр]]'''
 +
 
 +
'''Работа программы''': Программа предлагает 2 режима работы 1 режим это нахождение для 1 из 5 фигур таких расстановок L фигур, на доске M*N, что они не бьют друг друга, второй режим возможно найти максимальное число фигур, которое можно расставить на этом поле, чтобы они не били друг друга.
 +
 
 +
'''Идея алгоритма''': Основная идея заключается в присваиванию клетке 1 из 3 значений, пустая клетка, битая клетка или клетка, в которой стоит фигура.
 +
В точку ставится фигура, дальше маркируются поля, в которые уже невозможно поставить фигуру, затем мы ставим следующую фигуру и снова маркируем поля, в которые не можем ничего поставить и так далее до нужного пользователю числа фигур. Поиск максимального числа это попытка поставить на доску как можно больше фигур, он пользуется алгоритмами первого пункта.
  
 
Скачать можно  [http://mech.spbstu.ru/File:Ch.rar тут].
 
Скачать можно  [http://mech.spbstu.ru/File:Ch.rar тут].
 +
 +
 +
 +
'''[[Капитанюк Светлана]]'''
 +
 +
'''Краткое описание алгоритма''': Доска представлена в виде динамического массива. Если в клетке присутствует фигура, то тогада она обозначается '+', если же клетка осталась путсая, то тогда '0'.
 +
 +
'''Инструкция''': пользователь вводит размер доски, далее он выбирает то действие, которое он хотел бы выполнить: посчитать максимальное число возможных фигур на данной доске, или же расставить фигуры так, чтобы они не били друг друга.
 +
 +
Скачать можно  [http://tm.spbstu.ru/File:Chess_03.zip тут].
 +
 +
'''[[Демченко Артём]]'''
 +
 +
'''Основная идея программы''': Программа подсчитывает и выводит расстановку указанного кол-ва фигур на указанном поле и второй опицей выводит максимальную расстановку на поле размером size*size.
 +
 +
'''Инструкция''': Запустите программу и следуйте инструкциям. Сначала идет выбор алгоритма, после чего идет выбор фигуры и размер доски для подсчета максимальной расстановки на поле size*size. Результат будет выведен на экран.
 +
 +
Скачать можно [http://tm.spbstu.ru/File:Chessss.zip тут].
 +
 +
'''[[Гильманов Илья]]'''
 +
 +
'''Основная идея программы''': пользователь вводит размер доски MxM , тип фигур, их количество. Программа рассчитывает максимально возможное количество фигур , которые можно расположить на доске, чтобы они не били друг друга.
 +
 +
'''Инструкция к программе''': Пользователь вводит размер доски M(size*size).А затем предоставляется выбор между нахождением максимально возможного числа фигур , и их расстановкой.Также пользователь выбирает тип фигуры , и количество(если интересует расстановка).
 +
 +
Скачать можно [http://mech.spbstu.ru/File:CheEeeSss.rar здесь]
 +
 +
'''[[Киселёв Лев]]'''
 +
 +
'''Основная идея программы''': реализация задачи о расстановке фигур одинакового типа на произвольной доске MxM
 +
Скачать можно [http://mech.spbstu.ru/File:main.rar здесь]
 +
 +
'''[[Сергей Ляжков]]'''
 +
Инструкция:
 +
Вводите необходимые данные(кол-во строк, столбцов, фигуры, тип расстановки) согласно последовательности выполнения программы
 +
Краткое описание алгоритма:
 +
1)Выделяет память под доску(динамическая матрица)
 +
2)Устанавливает каждую следующую фигуру на n-е свободное место которое он нашел после последней установленной фигуры, где n изменяется от 1 до бесконечности(установка заканчивается тогда, когда программа не может установить очередную фигуру).
 +
3)Счетчик количества фигур, которые необходимо установить, уменьшается на 1 после каждой установки.
 +
4)После того, как фигура установлена, программа рекурсивно вызывает функцию установки очередной фигуры(возвращается в пункт 2)
 +
5)В рекурсивную функцию отправляется только копия доски. Таким образом, возвращаясь из рекурсии, мы получаем доску без последующих установленных фигур. Когда счетчик фигур, которые необходимо установить, уменьшается до нуля, данное поле сохраняется в списке.
 +
6)Вывод списка.
 +
Скачать можно [http://tm.spbstu.ru/File:Шахматы.zip тут]
Вам запрещено изменять защиту статьи. Edit Создать редактором

Обратите внимание, что все добавления и изменения текста статьи рассматриваются как выпущенные на условиях лицензии Public Domain (см. Department of Theoretical and Applied Mechanics:Авторские права). Если вы не хотите, чтобы ваши тексты свободно распространялись и редактировались любым желающим, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого.
НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ МАТЕРИАЛЫ, ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ!

To protect the wiki against automated edit spam, we kindly ask you to solve the following CAPTCHA:

Отменить | Справка по редактированию  (в новом окне)