Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Шахматная задача в C++

19K
20 декабря 2006 года
razer
7 / / 07.11.2006
добрый день. столкнулся с такой задачей- нужно пройти шахматное поле ходами коня так,чтобы в каждой клетке он побывал только одни раз. у кого нибудь есть предложения по алгоритму реализации или может быть исходный код?:D
9
20 декабря 2006 года
Lerkin
3.0K / / 25.03.2003
Двумерный массив 8x8. С произвольного места (или как там в задаче), по правилам хода коня, обошел бы всю доску, отмечая клетки, в которых уже был. Можно дерево строить...
19K
20 декабря 2006 года
razer
7 / / 07.11.2006
ну там проблема будет в куче проверок(выход за пределы доски, и попадание в ту же точку)...
9
20 декабря 2006 года
Lerkin
3.0K / / 25.03.2003
Цитата: razer
ну там проблема будет в куче проверок(выход за пределы доски, и попадание в ту же точку)...



не будет. могу поднакидать примерный алгоритмик... давай в личку...

622
20 декабря 2006 года
nilbog
507 / / 19.12.2006
сделай доску большего размера
и внешние 2 ряда клеток заполни как там уже были
как один из способов
63
20 декабря 2006 года
Zorkus
2.6K / / 04.11.2006
http://algolist.manual.ru/maths/combinat/knight.php
Все точно и с комментами:)
320
11 января 2007 года
m_Valery
1.0K / / 08.01.2007
Visual Studio2003,консоль.
Та еще задачка :) Просто головоломка
( предложенная Эйлером ) .

Код:
#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 &currentRow, int &currentColumn, 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 &currentRow, int &currentColumn, 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";
    }
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог