Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.06.2015, 20:05   #1
Ovenvan
Пользователь
 
Регистрация: 09.06.2015
Сообщений: 21
По умолчанию Delphi (Lazarus). Обход шахматной доски конём

Добрый день. Возникла задача обойти доску конём. Есть код, который запускается, но не то, чтобы правильно работает. Проставляется первый ход и всё, остальные поля оставляет заполненными нулями, а должны номерами ходов. Помогите, пожалуйста, разобраться.
Код:
unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Grids,
  StdCtrls;
 
const
  n = 8;
  dx : array [1..8] of integer = (2,1,-1,-2,-2,-1,1,2); {изменение координат коня при возможных ходах}
  dy : array [1..8] of integer = (1,2,2,1,-1,-2,-2,-1);
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    StringGrid1: TStringGrid;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
  Board : array [1..n, 1..n] of integer; {номеру хода, когда посещена клетка или 0, если конь еще не заходил}
  Okey : boolean; {обход удался}
  x0, y0: integer;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure Clear; {очистка доски}
var
  i, j: integer;
begin
  for i:= 1 to n do
    for j:= 1 to n do
      Board[i,j]:= 0;
end;
 
procedure Draw; {отрисовка доски}
var
  i, j: integer;
begin
  for i:= 1 to n do
    for j:= 1 to n do
       form1.StringGrid1.Cells[i-1,j-1]:= inttostr(Board[i,j]);
  Form1.Refresh;
end;
 
function SetBeginXY: boolean; {начальные координаты}
begin
    x0:= strtoint(form1.Edit1.Text);
    y0:= strtoint(form1.Edit2.Text);
    Board[x0,y0]:= 1;
  end;
 
procedure Trying(step, x, y: integer; var OK: boolean); {OK успешность хода, step текущий номер хода}
var
  xnext, ynext: integer;
  k: integer; {возможный ход}
  OK1: boolean;
begin
  k:= 0;
  repeat
    inc(k);
    OK1:= false; {пока не найден подходящий ход}
    xnext:= x + dx[k];
    ynext:= y + dy[k];
    if ((1 <= xnext) and (xnext <= n) and (1 <= ynext) and (ynext <= n) and (Board[xnext,ynext] = 0)) then
      begin
        Board[xnext,ynext]:= step; {свободная клетка}
        if step < n*n then
          begin
            Trying(step + 1, xnext, ynext, OK1);
            if (not OK1) then Board [xnext,ynext]:= 0; {неудачный ход не получился следующий}
          end;
      end
    else OK1:=TRUE; {последний ход}
  until OK1 or (k = 8);
  OK:= OK1;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  form1.StringGrid1.RowCount:= n;
  form1.StringGrid1.ColCount:= n;
  Clear;
  Draw;
  if (SetBeginXY) then Trying(2,x0,y0,Okey);
  Draw;
end;
 
end.
Ovenvan вне форума Ответить с цитированием
Старый 10.06.2015, 16:31   #2
Ovenvan
Пользователь
 
Регистрация: 09.06.2015
Сообщений: 21
По умолчанию

Задание заключается в рекурсивной проверке возможности обойти конём (фигурой с соответствующим ходом) шахматную доску. В каждой клетке должен отображаться номер хода, на котором конь попал в эту клетку (до 64). В Edit'ы записываю первоначальное положение коня (по координатам). На выходе StringGrid с заполненными полями. В этом и проблема: на StringGrid'е только первоначальное положение коня, дальше не отображается.
Ovenvan вне форума Ответить с цитированием
Старый 10.06.2015, 18:06   #3
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

написано в Delphi
бегает, меняет цифирки.
окончания работы таки не дождался (~10 мин.) не так уж там мало вариантов для тотального перебора.
Вложения
Тип файла: zip 000.zip (3.9 Кб, 21 просмотров)
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 10.06.2015 в 18:08.
evg_m вне форума Ответить с цитированием
Старый 10.06.2015, 18:30   #4
Ovenvan
Пользователь
 
Регистрация: 09.06.2015
Сообщений: 21
По умолчанию

У меня всё за границы выходит с ошибкой
Ovenvan вне форума Ответить с цитированием
Старый 10.06.2015, 22:45   #5
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

полет нормальный. ждем-с.

Цитата:
написано в Delphi
работает Lazarus. Импорт проекта в режиме совместимости с Delphi.
Изображения
Тип файла: jpg 1.jpg (83.2 Кб, 152 просмотров)
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 10.06.2015 в 22:54.
evg_m вне форума Ответить с цитированием
Старый 10.06.2015, 23:13   #6
Ovenvan
Пользователь
 
Регистрация: 09.06.2015
Сообщений: 21
По умолчанию

Проверьте, пожалуйста, нету ли ошибки.

Код:
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Grids;

const
dx: array[1..8] of integer = (2, 1, -1, -2, -2, -1, 1, 2);
dy: array[1..8] of integer = (1 ,2, 2, 1, -1, -2, -2, -1);

type

  { TForm1 }

  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

function Trying(x, y, step: integer): boolean;
var k: integer;
begin
  result:= false;
  if not ((x in [1..8]) and (y in [1..8])) and (form1.StringGrid1.Cells[x,y] <> '') then exit;
  form1.StringGrid1.Cells[x,y]:= inttostr(step + 1);
  Form1.StringGrid1.RowCount:= y;
  form1.StringGrid1.ColCount:= x;
  form1.StringGrid1.Refresh;
  result:= true;
  if step = 64 then Exit;
  for k:= 1 to 8 do
  begin
    result:= Trying(x + dx[k], y + dy[k], step + 1);
    if result then Break;
  end;
  if not result then Form1.StringGrid1.Cells[x,y]:= '';
  form1.StringGrid1.Refresh;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  x, y: integer;
begin
x:= 1; //strtoint(edit1.text);
y:= 1; //strtoint(edit2.text);
Trying(x,y, 0);
end;

end.
Ovenvan вне форума Ответить с цитированием
Старый 11.06.2015, 07:06   #7
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Вот это
Код:
  result:= true;
  if step = 64 then Exit;
ДОЛЖНО быть в самом начале процедуры, сразу после begin

иначе мы так и не получим успеха из-за
Код:
 if not ((x in [1..8]) and (y in [1..8])) and (form1.StringGrid1.Cells[x,y] <> '') then exit;
а все клетки уже заняты.
что делать "писалось в блокноте" за пять минут и никак не тестировалось.

чтобы проверить работоспособность своей версии программы
возьмите поле 3х3 (то есть задайте проверку ... in [1..3])
начальная позиция в углу (1,1)
и максимальное число шагов 8 ( if step=8 then exit; ) (мы никак не сможем попасть в центральную клетку, но должны обойти все остальные).
Изображения
Тип файла: jpg 1.jpg (48.4 Кб, 127 просмотров)
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 11.06.2015 в 07:19.
evg_m вне форума Ответить с цитированием
Старый 11.06.2015, 10:59   #8
Ovenvan
Пользователь
 
Регистрация: 09.06.2015
Сообщений: 21
По умолчанию

У меня срабатывает ошибка выхода за границы StringGrid'а.
Какая часть ответственна за задания размеров StringGrid, эта?
Код:
  Form1.StringGrid1.RowCount:= y;
  form1.StringGrid1.ColCount:= x;
Может её надо в цикле изменять?
Ovenvan вне форума Ответить с цитированием
Старый 11.06.2015, 11:35   #9
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Цитата:
Какая часть ответственна за задания размеров StringGrid, эта?
Размеры таблицы заданы ЗАРАНЕЕ и нигде не меняются. 9x9

Цитата:
Может её надо в цикле изменять?
Зачем?! Доска есть и меняться ПРИ выполнении ходов не должна!!
Исключительно для "анимации" (изменения картинки) (для работы программы это не нужно) была сделана смена ТЕКУЩЕЙ ячейки.
Код:
row:=y;
col:=x;
НО не РАЗМЕРЫ (rowcount, colcount)
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 12.06.2015, 16:35   #10
Ovenvan
Пользователь
 
Регистрация: 09.06.2015
Сообщений: 21
По умолчанию

Спасибо большое за помощь и объяснение.
Ovenvan вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Красивая реализация шахматной доски BestStrikS C# (си шарп) 5 05.06.2015 11:48
Обход "Конём" шахматной доски С++ Facktor Общие вопросы C/C++ 0 22.02.2014 13:14
Создание своего класса в Delphi 7 - фигуры для шахматной доски electric Компоненты Delphi 18 24.10.2013 15:06
Обход шахматной доски конем wazaaaup Помощь студентам 1 04.07.2011 20:54
Пролог. Обход конем шахматной доски Gambler Помощь студентам 9 08.12.2010 22:19