вставить в программу скриптовый язык
а скрипты хранить в этом же файле
будет полностью настраиваемая
Модератор: Модераторы
//Типы данных и константы
const CMatrixSide=8; //сторона квадрата}
CMatrixSize=CMatrixSide*CMatrixSide; //Размер матрицы
CSpyralLength=CMatrixSize shr 2; //Длина спирали
CMatrixCodeBytes=CSpyralLength shr 2; //Байтов в коде матрицы
type TCoordsYX=array[1..2] of byte; //две координаты ячейки спирали
TSpyralDef=array[1..CSpyralLength] of TCoordsYX; //сколько-то ячеек в одной спирали
TMatrixDef=array[1..4] of TSpyralDef; //4 спирали в матрице в одном положении
TTheMatrix=array[1..CMatrixSide,1..CMatrixSide] of char; //массив "дырочек"
//Тип данных для хранения кода матрицы, в одном байте хранятся 4 дуплета, то есть на каждые 4 ячейчки
//требуется один байт, поэтому делится на 4 сдвигом вправо два раза
TMatrixCodeByte=array[1..CMatrixCodeBytes] of byte;
//Задать значение дуплета в нужной позиции
procedure Set2Bits(var where:TMatrixCodeByte;BitDupPos,Value:byte);
//BitDupPos - позиция дуплета, отсчет СПРАВА, нумеруются с ЕДИНИЦЫ
//Value - 1..4
var BitPos, BytePos, Shifted, Mask:byte;
begin
If BitDupPos>CSpyralLength then exit;
//номер байта, в котором менять, байты нумеруются справа налево, а индексы массивов растут вправо
//функция pred используется вместо "-1"
//shl и shr побитово сдвигают свой левый аргумент на правый_аргумент раз, умножая или деля на степень двойки
shifted:=pred(BitDupPos) shr 2;
BytePos:=CMatrixCodeBytes-Shifted;
//для получения битовой позиции дуплета берем остаток от деления на 4 числа на единицу меньшего,
//чем нужное иначе возникают накладки. Например, 12 mod 4=0, и устанавливаются два младших бита,
//в то время, как надо два старших
BitPos:=(pred(BitDupPos) mod 4) shl 1;
//обнуляем всё, кроме двух младших битов: значение должно быть в диапазоне 0-3
//потом сдвигаем значение влево для получения нужной позиции в байте
value:=(pred(value) and 3) shl BitPos;
//маскируем все биты байта, кроме двух требуемых
mask:=(3 shl bitpos) xor 255;
where[BytePos]:=where[BytePos] and mask;
where[BytePos]:=where[BytePos] or value;
end;
//Получить значение дуплета в нужной позиции
function Get2Bits(where:TMatrixCodeByte;BitDupPos:byte):byte;
var BitPos, BytePos, Mask:byte;
begin
//комментарии к логике см. в Set2Bits
If BitDupPos>CSpyralLength then exit;
//номер байта, начиная СПРАВА
BytePos:=CMatrixCodeBytes-(pred(BitDupPos) shr 2);
BitPos:=(pred(BitDupPos) mod 4) shl 1;
mask:=3 shl bitpos; //) xor 255;
//обнуляем всё кроме двух нужных битов
result:=((where[BytePos] and mask)shr BitPos)+1;
end;
Troublemaker писал(а):Код, может, не самый оптимальный, но речь не об его оптимизации, а о другом способе работы с нужными данными - есть таковой или нет?
type
T2Bits = 0..3;
T2BitsArray = bitpacked array[0..x] of T2Bits;
Выглядит заманчиво, но в 2.2.0 (Lazarus-0.9.24.1-fpc-2.2.0-20080417-win32.exe) в исходниках rtl слово bitpacked встречается только единожды в имени константы - \lazarus\fpc\2.2.0\source\packages\extra\palmunits\inetmgr.pp - файл 2005 года.Sergei I. Gorelkin писал(а):Да вроде недавно появилась поддержка bitpacked массивов и записей.
Гм... по сути у меня так и сделано, но спрашивал я про штатные возможности - есть они или нет.alexs писал(а):напиши клас-обёртку
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 17