• Как правильно сделать панель приборов автомобиля на arduino (или другой платформе)?

    @kalapanga
    Сразу говорю, что я не автомобилист, поэтому ничего конкретного не подскажу. Но Вы бы добавили в вопрос, о каком автомобиле идёт речь! Ответ вон уже есть и формально правильный, но он подразумевает наличие в автомобиле всех необходимых цифровых датчиков общающихся по стандартной шине по стандартным протоколам, показания от которых нужно только поймать и отобразить. А оно у Вас точно есть? Просто желание сделать свою панель, наводит на мысли о какой-то старой или нестандартной технике.
    И ещё, фраза
    Сейчас эти данные отображаются на аналоговых датчиках
    некорректна. Датчики только измеряют/контролируют что-то, отображают индикаторы.
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso, С буквами прикол в том, что у меня они нормально, сглаженными рисуются. Я рисую буквы в TfrmMain.grdChessBoardDrawCell вот так:
    grdChessBoard.Font.Size:= 20+trunc(grdChessBoard.DefaultRowHeight/QueensCount)-1;
      grdChessBoard.Font.Style:=[fsBold];
      grdChessBoard.Font.Name:='Times New Roman';
    
      if ACol = 0 then
        grdChessBoard.Canvas.TextRect(grdChessBoard.CellRect(ACol, ARow), grdChessBoard.CellRect(ACol, ARow).Left, grdChessBoard.CellRect(ACol, ARow).Top, IntToStr(QueensCount - ARow))
      else if ARow = QueensCount then
        grdChessBoard.Canvas.TextRect(grdChessBoard.CellRect(ACol, ARow), grdChessBoard.CellRect(ACol, ARow).Left, grdChessBoard.CellRect(ACol, ARow).Top, char(96+ACol))
      else
       // а тут уже отрисовка клеточек собственно доски

    У меня фиксированные колонки убраны, просто сетка на 1 больше в обе стороны. Цифры слева, буквы снизу. Ну и соответственно в DrawSolution коэффициенты настроены.
    И красивые буковки. Я поэтому никаких "фокусов" и не пробовал.
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso, чего-то мы проигнорировали, что рекурсивный вызов внутри цикла for осуществляется, и после возврата цикл продолжаться должен. Ну значит сложнее будет! Надо тщательнее представить алгоритм на бумажке, пройтись пошагово отладчиком, тогда будет понятно, что ещё добавить нужно.
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso, Саму процедуру Solve я примерно так и представлял. А вот этот кусочек совсем странный получился, скорее всего в нём и дело. В самой процедуре RecursiveSolution вот это совсем не так:
    if RestoreLastSolution then
      begin
        For i := 1 to QueensCount do
          x[i] := TmpArr[i];
          a[Cout1] := True;
          b[Cout2 + Cout1] := True;
          c[Cout2 - Cout1] := True;
          i:=Cout2;
          Solve(i);
      end;

    Массивы a, b, c должны заполняться так же, как мы это делали для прошлого случая. Сначала все значения True (это есть), а потом нужные элементы в False. А здесь сейчас что-то странное написано. В каждом массиве какому-то одному элементу присваивается опять же True. Тут не надо ничего придумывать - всё как для другого метода делали - здесь так же.
    Эти две строчки просто выкинуть.
    i:=Cout2;
    Solve(i);
    И получится вроде как я и имел ввиду.
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso, А что массивы? С ними-то всё правильно. А остальное всё не так. Перечитайте, что я писал ещё раз.
    Во-первых, прошлый раз не стал писать, но сильно уж глаза режет - два IF подряд:
    if not RestoreLastSolution then...
    if RestoreLastSolution then...
    надо:
    if RestoreLastSolution then
    begin ... end
    else
    begin...end;
    Во-вторых, никакой процедуры Solve1 не должно быть. Процедура RecursiveSolution делает по-разному инициализацию, а в конце в любом случае вызывает Solve(1).
    В-третьих, нужно модифицировать саму процедуру Solve. В начале она должна проверять - это восстановление или нет? Ну а дальше прошлое моё сообщение перечитайте.
  • Почему не получается сохранить запись?

    @kalapanga
    Влад Гапанович, Вы пытаетесь в таблицу с именем Const.USER_TABLE в колонку с именем Const.USER_USERNAME записать значение username.
    Но в этой таблице нет колонки с таким именем. А уж что это за таблица и какие колонки в ней должны быть тоже только Вы знаете! Сопоставьте структуру этой самой таблицы, в которую данные пытаетесь добавить, и получившееся значение переменной insert. Думаю сами увидите несоответствие.
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso, Так проверили бы и убедились, что не работает так.
    Я ошибся, когда где-то выше писал, что если решение найдено, то нет вложенных рекурсивных вызовов - это не так! Решение находится в момент когда процедура вызвана восьмой раз, т.е. Solve(8)
    Логично - ищется и находится положение последнего 8 ферзя.
    Как правильно запустить - думать надо!
    1) Инициализация вспомогательных массивов нужна. Только там скорее всего вот здесь
    For i := 1 to QueensCount-1 do
    без -1 должно быть.
    2) Решение нужно положить в рабочий массив x.
    3) Нужно вызвать процедуру так же как есть Solve(1); а она (процедура) должна понимать, если идёт восстановление решения, то нужно ничего не делая вызывать себя ещё раз с увеличением параметра Solve(i + 1), но если параметр i уже = 8 (точнее QueensCount), то нужно забыть, что идёт восстановление (сбросить флаг) и просто выйти из процедуры (Exit;).
    В результате программа вернётся на предыдущий шаг уже как бы в состоянии обычного расчёта.
    Пробуйте!
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso,
    procedure StackSolution(RestoreLastSolution: boolean = false);
    var
      i, j, Y, X: integer;
      a: array [1..MaxQueensCount] of boolean;
      b: array [2..2*MaxQueensCount] of boolean;
      c: array [1-MaxQueensCount..MaxQueensCount-1] of boolean;
      Stack: TStack<integer>;
    
      Function Uspeh: Boolean;
      Var
        usp: Boolean;
      Begin
        usp := false;
        While (Y < QueensCount) And Not usp do
        Begin
          Y := Y + 1;
          usp := a[Y] and b[X + Y] and c[Y - X];
        End;
        Result := usp;
      End;
    
    begin
      Stack := TStack<integer>.Create;
      try
        // Сначала в любом случае заполняем массив True - все горизонтали и диагонали свободны
        For i := 1 to QueensCount do
          a[i] := True;
        For i := 2 to 2*QueensCount do
          b[i] := True;
        For i := 1-QueensCount to QueensCount-1 do
          c[i] := True;
        if RestoreLastSolution then
        begin
          // Если восстанавливаем решение
          // Отмечаем занятыми линии соответственно последнему решению (без последнего ферзя)
          For i := 1 to QueensCount-1 do
          begin
            a[TmpArr[i]] := False;
            b[i + TmpArr[i]] := False;
            c[TmpArr[i] - i] := False;
          end;
          // В X и Y положение последнего ферзя в решении
          X := QueensCount;
          Y := TmpArr[QueensCount];
          // Решение запихиваем в стек (без последнего ферзя)
          For i := 1 to QueensCount-1 do
            Stack.Push(TmpArr[i]);
        end
        else
        begin
          X := 1;
          Y := 0;
        end;
        // Далее не меняется ничего
        Repeat
          if StopPressed then
            Exit;
          If Uspeh Then
          Begin
            Stack.Push(Y);
            If X < QueensCount Then
            Begin
              a[Y] := False;
              b[X + Y] := False;
              c[Y - X] := False;
              X := X + 1;
              Y := 0;
            End
            Else
            begin
              frmMain.DrawSolution(Stack);
              Stack.Pop;
            end;
          End
          Else
          Begin
            X := X - 1;
            If X > 0 Then
            Begin
              Y := Stack.Pop;
              a[Y] := True;
              b[X + Y] := True;
              c[Y - X] := True;
            End;
          End;
        Until X = 0;
      finally
        Stack.Free;
      end;
    end;


    Вот процедура и она вроде работает - проверяйте! Здесь TmpArr - это последнее найденное решение, QueensCount целых чисел. Его Вы должны при необходимости получить из файла.
    Как я и говорил, в процедуре изменилась только инициализация, а сам цикл с собственно расчётом не меняется. У Вас уже есть запись решений в файл. Вот и проверьте, чтобы что без паузы, что с паузой их было нужное количество.
    Но если какого-то не хватает - ищите куда оно делось сами! :))
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso, Чего-то в расчёте намудрили. Не вижу, где последнее решение кладётся в стек? Внимательнее вечерком гляну.
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso, по пунктам.
    1) На счёт того, какой из способов легче модифицировать - пофиг! С рекурсией всё то же самое будет. Тут главное не перестараться. Строго говоря остановка может быть осуществлена в процессе поиска очередного решения. Т.е. сколько-то решений найдено, и сделано сколько-то шагов в поисках следующего. Вот если запомнить это состояние - это конечно высший пилотаж будет, но сложность не оправдана абсолютно. Не надо! Нужно считать, что восстанавливаем ситуацию, когда очередное решение найдено, а следующее ещё не начинали искать. Вот это реализовать вполне реально и, как я сказал, по трудозатратам должно быть примерно одинаково для всех способов решения. Для стека в этом случае на стеке лежат все 8 значений, а для рекурсии в этот момент нет никаких вложенных вызовов.
    2) С флагом запуска процедуры расчёта чего-то намудрили. Я имел ввиду следующее. Процедуру объявляете как-то так:
    procedure StackSolution(RestoreLastSolution: boolean);
    И вызываете допустим из обработчика нажатия кнопки "Старт" так:
    StackSolution(False);
    а из обработчика нажатия кнопки "Продолжить" так:
    StackSolution(True);
    Внутри процедуры StackSolution этот параметр анализируется и делается либо то, либо другое.
    3) В процедуре расчёта используются три вспомогательных массива - a, b, c. По которым определяются свободные и битые поля. Если расчёт начинается с начала (RestoreLastSolution=false), то они инициализируются как написано - все значения true. А если мы восстанавливаем работу (RestoreLastSolution=true), то они уже какие-то значения должны иметь! Тут два варианта возможны:
    a) Их тоже сохранять в файл и считывать из файла
    б) рассчитывать их по последнему найденному решению
    4) А вот уж как цикл с нужного места стартануть - подумать надо, сейчас уже плохо соображается.
    Что-то возможно будет вместо:
    x := 1;
    Y := 0;
    А в стек надо последнее решение, наверное запихнуть. И дальше цикл while пойдёт как есть.
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso, С одной стороны, жажда деятельности конечно похвальна. Но про гемморой я предупреждал! :)
    Главное, что всё это к работе с файлами никакого отношения не имеет.
    Есть процедура собственно расчёта - допустим, как в последнем сообщении StackSolution. Вот её нужно научить работать двумя способами (допустим, в зависимости от переданного параметра) - начиная с самого начала, когда ни одного решения нет, или начиная с какого-то решения. Это самое главное и самое сложное.
    Ещё нужно смотреть - хватит ли для продолжения рассчёта только самогО предыдущего решения, как Вы сейчас предполагаете. В некоторых способах однозначно потребуется сохранение вспомогательных данных. Так что файл со списком решений и файл для восстановления состояния расчёта - это может быть совсем не одно и то же.
    Кнопок для наглядности сделайте две: 1-я - та, что есть сейчас, старт с начала, 2-я - старт с запомненной позиции. И вызывайте этот самый StackSolution по одной кнопке с одним значением параметра, по другой с другим.
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso,
    согласен, но, по крайней мере, я сделаль и получил удовольствие)

    Тоже хорошо - не поспоришь! :)
    Разбор заданных строкой выражений - это классическая задача. В ней кстати стеки часто применяются.
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso, На счёт приоритетов операций. С другими действиями кроме + и - выражение не будет соответствовать определению из задания 7. Зря в это полезли - это совсем другая задача.
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso, если честно, я бы подумал, а не прокатит ли для сдачи задания, если работу с файлом не для сохранения/возобновления расчёта использовать, а для чего-нибудь ещё, что попроще. Правда, не знаю для чего :) Хуже нет - встраивать в готовый код функционал, который не был предусмотрен на этапе проектирования. Будет собственно работы с файлом пара строчек, а расчётные методы вырастут вдвое каждый, причём в каждом будет что-то своё, неуниверсальное - сплошной гемморой!
    Может на самом деле какие-нибудь три-четыре числа, типа "настройки программы", при выходе сохранять, при входе считывать? Мало ли, что так не делается - зато покажете, что вот мол есть работа с файлом!
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso, ну это может примерно так выглядеть. Для способа без рекурсии текущее решение хранится в массиве из 8 целых чисел. Объявляем file of integer. При нажатии кнопки "стоп" записываем наши 8 целых чисел в файл. Ещё более по уму будет писать первым числом количество ферзей, а потом уж и соответствующее количество элементов массива. Будет универсально для расчета с любым количеством. По кнопке "продолжить" читаете количество ферзей, потом считываете в массив собственно последнее решение. Как там дальше цикл расчета стартовать - смотреть надо. Возможно, что-то ещё надо сохранять или по считанному определять, чтобы расчёт не с начала стартовал.
    Вот рекурсию я так сразу даже и не знаю получится или нет. То что нужно не один, а ещё и вспомогательные массивы сохранить это ерунда. А вот продолжить расчёт с нужного места - не знаю.
    Возможно ещё число стоит первым записать - способ расчета. Это если будете реализовывать сохранение позиции для разных способов решения.
    А может всё и не так сложно. Надо пробовать.
    Но всё-таки опять за уши притянутое решение. Разве что на максимальное количество ферзей расчет запустить и прерываться на перерыв! :)
    Можно кстати и начать с того, что просто научить программу останавливаться и потом возобновлять расчёт с этого же места. Ничего не записывая и не считывая. Ну то есть Вы не собираетесь закрывать программу, что-то там с ней делать - просто пауза, посмотрели на текущее решение, поехали дальше!
    По-моему это более сложная часть, возможно что-то в логике, в способе останова поменять придётся. Может и нет. Пристегнуть потом запись и чтение файла - уже ерунда.
  • Как можно оптимизировать код?

    @kalapanga
    Не очень понял задачу. Типизированный файл - это файл содержащий записи определённого типа, файловая переменная объявляется как file of чего-нибудь.
    Вам его что, по заданию что ли как-то "пришить" нужно?
    Если какие-то настройки нужно хранить в файле, то никакого смысла нет использовать для этого что-то кроме класса TIniFile. Который именно для этого и предназначен.
    Результаты расчётов выдавать (например, все найденные комбинации) - тут обычный текстовый файл годится. Не знаю, формально он наверное тоже может считаться типизированным...
    Можно конечно решения сохранять в каком-нибудь File of SolutionArray. Где SolutionArray это ваш массив с текущим решением array [1..QueensCount]. Но совсем не понимаю зачем. Решения же для человека выводятся, а тут файл не человекочитаемый будет.
    Короче. Если просто работу с файлами показать нужно, то я бы сделал настройки в ini-файле и сохранение решения в текстовый файл. Если стоит задача поработать именно с типизированным файлом, то только довольно искусственные, притянутые за уши решения на ум приходят.
  • Почему батник генерирует ошибку если во всех источниках команда из него работает?

    @kalapanga
    Deiwan, Установленная - не установленная, но написано здесь максимально однозначно:
    "java" не является внутренней или внешней
    командой, исполняемой программой или пакетным файлом.
    Не находится именно java.
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso, Как всегда забываешь пояснять о чём речь, что за клетки такие и подсказки?
    Хрустальный шар говорит, что это наверное какие-то помеченные клетки куда уже нельзя ставить?
    Здесь 2 варианта с типичной альтернативой. Первый - после убирания одного ферзя пересчитывать всю картинку по оставшимся. Требует больше вычислений. Второй - иметь массив клеток и в клетке хранить число ферзей, которые её бьют. Убрали ферзя - значения для клеток которые он бил уменьшаем на 1. Если ноль - красим как свободную. Тут меньше ненужных рассчетов, но более сложная структура данных.
    Понятно, что для этой задачи, что то, что другое - мизерные затраты. Для более сложных задач и выбор должен быть более обоснованным.
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso, а зачем? Чем это будет лучше?
    Но если очень хочется один TImage, то нужно иметь 9 картинок с разным количеством ферзей, включая пустую и менять их.
  • Как можно оптимизировать код?

    @kalapanga
    Alertoso, Нее, Label то тут как уж? Если это делается для фиксированного числа ферзей (8) то положить 8 штук TImage. Сделать их нужного размера. Через свойство Picture в дизайнтайме загрузить в них картинку. Красивее будет если картинка заранее в нужном размере нарисована. Если картинка большего размера, то поставить у TImage свойство Stretch = True. А дальше у них при необходимости менять Visible. Лучше сделать отдельную процедурку с параметром, которая будет делать видимым нужное количество фигурок. Параметр как для общей логики удобнее. Либо число видимых фигур, либо команда добавить/убавить фигурку.