#include "stdafx.h"
#include "time.h"
#include "windows.h"
#include<iomanip>
using std::cout;
using std::endl;
using std::setw;
using std::cin;
char*rus(char *s){
char *t = new char[strlen(s)+1];
CharToOem(s, t);
return t;
}
void move(int board[][8], int vertical[], int horizontal[],
int ¤tRow, int ¤tColumn, int Numb, int cnt);//передвижение по доске
void DecAccessibility(int accessibility[][8],int horizontal[], // изменение массива
int vertical[], int crRow, int crColumn);//доступности
int FindMove (int board[][8], int accessibility[][8],
int vertical[], int horizontal[], int crRow, int crColumn);
void print(int board[8][8],int r,int c);// вывод доски на экран
int _tmain(int argc, _TCHAR* argv[])
{
int currentRow = 0;
int currentColumn = 0;
//установка начальных значений элементов массивов
int board[][8] = {{0},{0},{0},{0},{0},{0},{0},{0}};
int horizontal[] = {2, 1, -1, -2, -2, -1, 1, 2};
int vertical[] = {-1, -2, -2, -1, 1, 2, 2, 1};
int accessibility[][8] = {{2,3,4,4,4,4,3,2},// массив доступностей
{3,4,6,6,6,6,4,3},
{4,6,8,8,8,8,6,4},
{4,6,8,8,8,8,6,4},
{4,6,8,8,8,8,6,4},
{4,6,8,8,8,8,6,4},
{3,4,6,6,6,6,4,3},
{2,3,4,4,4,4,3,2}};
srand(time(NULL));
cout<<rus("\n\t *** Путешествие коня ***");
bool Go = true; //признак того, что можно начинать ходить
try
{
//установка начальных значений
cout<<rus("\n\nВведите номер строки и столбца - первоначальную позицию коня \n");
cin>>currentRow;
cin>>currentColumn;
//проверка допустимости начальных значений
if(currentRow>7 || currentRow<0 || currentColumn>7 ||
currentColumn<0)
{
cout<<rus("\nВы должны ввести цифру от 0 до 7\n");
Go = false;
}
}
catch(...)
{
cout<<rus("\nВы должны ввести цифру от 0 до 7\n");
Go = false;
}
//начинаем искать решение
if(Go)
{
//устанавливаем коня на заданную клетку
DecAccessibility(accessibility, horizontal, vertical,
currentRow, currentColumn);
board[currentRow][currentColumn] = 1;
print(board,currentRow,currentColumn);
cout<<rus("\n\n **** Правильная расстановка ****\n\n");
int MoveNumber; //код хода
int count = 1; //счетчик ходов
bool exit = true; //нужна для выхода из цикла
//перемещаем коня пока это возможно
do
{
MoveNumber = FindMove(board, accessibility, vertical,
horizontal, currentRow, currentColumn);
if (MoveNumber !=-1)
{
count++;
move(board, vertical, horizontal, currentRow,
currentColumn, MoveNumber, count);
DecAccessibility(accessibility, vertical, horizontal,
currentRow, currentColumn);
}
else exit = false;
}
while(exit);
cout<<"\n";
print(board,currentRow,currentColumn);
}
return 0;
}
//---------------------------------------------------------------------------
void move(int board[][8], int vertical[], int horizontal[],
int ¤tRow, int ¤tColumn, int Numb, int cnt)
{
//изменяем текущие координаты
currentRow += vertical[Numb];
currentColumn += horizontal[Numb];
//запоминаем, что на этой клетке мы уже были
board[currentRow][currentColumn] = cnt++;
}
//---------------------------------------------------------------------------
void DecAccessibility(int accessibility[][8],int horizontal[],
int vertical[], int crRow, int crColumn)
{
int Hmove, Vmove; //координаты клеток, лежащих в одном ходу от текущей
//перебираем все возможные варианты ходов и уменьшаем на 1 значения
//соответствующих элементов массива accessibility
for(int i=0; i<8; i++)
{
Hmove = crRow + vertical;
Vmove = crColumn + horizontal;
//проверка выхода за границу массива
if((Hmove<8)&&(Hmove>=0)&&(Vmove<8)&&(Vmove>=0))
accessibility[Hmove][Vmove] -= 1;
}
}
//---------------------------------------------------------------------------
int FindMove(int board[][8], int accessibility[][8],
int vertical[], int horizontal[], int crRow, int crColumn)
{
//Индексы элементов этого массива соответствуют кодам возможных ходов.
//Элементы массива будут содержать "-1" если ход невозможен или
//число равное значению соответствующего элемента массива accessibility
int PossibleMoves[8] = {-1,-1,-1,-1,-1,-1,-1,-1};
int tRow, tColumn; //временные координаты
//проверяем все возможные варианты ходов
for(int i=0; i<8; i++)
{
tRow = crRow + vertical;
tColumn = crColumn + horizontal;
//проверка выхода за границу массива и того, ходили ли мы на
//эту клетку раньше
if(tRow<8 && tRow>=0 && tColumn<8 &&tColumn>=0 &&
board[tRow][tColumn]==0)
PossibleMoves = accessibility[tRow][tColumn];
}
//анализ массива PossibleMoves
int count = 0;
int min = 8;
int Pos = 0;
//находим минимальный элемент массива не равный "-1", если таких
//элементов несколько - запоминаем их количество
for(int j=0; j<8; j++)
if(PossibleMoves[j]!=-1 && PossibleMoves[j]<=min)
{
min = PossibleMoves[j];
count++;
Pos = j;
}
//возможных ходов нет
if(count==0) return -1;
//возможен только 1 ход (или он оптимальный)
if(count==1) return Pos;
//Возможно несколько ходов, но мы не можем определить какой из
//них лучше. Поэтому выбираем ход случайным образом. При выборе
//учитываем только лучшие ходы.
int Ind = rand()%count;
for(int k=0; k<8; k++)
if(PossibleMoves[k]==min && Ind==0)
{
Pos = k;
break;
}
else Ind--;
return Pos;
}
//---------------------------------------------------------------------------
void print(int board[8][8],int r,int c)
{
for(int i=0;i<8;i++){
for(int j=0;j<8;j++){
cout<<setw(4)<<board[j];
}
cout<<endl<<"\n";
}
}
Шахматная задача в C++
добрый день. столкнулся с такой задачей- нужно пройти шахматное поле ходами коня так,чтобы в каждой клетке он побывал только одни раз. у кого нибудь есть предложения по алгоритму реализации или может быть исходный код?:D
Двумерный массив 8x8. С произвольного места (или как там в задаче), по правилам хода коня, обошел бы всю доску, отмечая клетки, в которых уже был. Можно дерево строить...
ну там проблема будет в куче проверок(выход за пределы доски, и попадание в ту же точку)...
Цитата: razer
ну там проблема будет в куче проверок(выход за пределы доски, и попадание в ту же точку)...
не будет. могу поднакидать примерный алгоритмик... давай в личку...
и внешние 2 ряда клеток заполни как там уже были
как один из способов
http://algolist.manual.ru/maths/combinat/knight.php
Все точно и с комментами:)
Все точно и с комментами:)
Visual Studio2003,консоль.