This commit is contained in:
Ivan Bondarev 2023-02-19 12:23:16 +01:00
commit 962a02099e
27 changed files with 554 additions and 125 deletions

View file

@ -113,7 +113,8 @@ namespace CodeCompletion
public void ConvertToDom(compilation_unit cu)
{
CodeCompletionController.comp.CompilerOptions.SourceFileName = cu.file_name;
if (CodeCompletionController.comp != null)
CodeCompletionController.comp.CompilerOptions.SourceFileName = cu.file_name;
visitor.Convert(cu);
is_compiled = true;
cur_used_assemblies = (Hashtable)PascalABCCompiler.NetHelper.NetHelper.cur_used_assemblies.Clone();

View file

@ -2706,7 +2706,7 @@ namespace CodeCompletion
private void add_system_unit()
{
string unit_file_name = this.converter.controller.Parser.LanguageInformation.SystemUnitName;
string unit_file_name = this.converter.controller.Parser?.LanguageInformation.SystemUnitName;
if (unit_file_name == null) return;
string unit_name = CodeCompletionNameHelper.FindSourceFileName(unit_file_name);
if (unit_name != null)

View file

@ -1291,7 +1291,7 @@ namespace CodeCompletion
public override string ToString()
{
return CodeCompletionController.CurrentParser.LanguageInformation.GetSimpleDescription(this);
return CodeCompletionController.CurrentParser?.LanguageInformation.GetSimpleDescription(this);
}
}

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "8";
public const string Build = "3";
public const string Revision = "3233";
public const string Revision = "3247";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%MINOR%=8
%REVISION%=3233
%REVISION%=3247
%COREVERSION%=3
%MAJOR%=3

View file

@ -1654,7 +1654,8 @@ namespace PascalABCCompiler.NETGenerator
// То и тут их обходить нет смысла
// А в ошибочных ситуациях (как err0303.pas) может ещё и зациклится
foreach (ITypeNode interf in t.ImplementingInterfacesOrEmpty)
if (!(interf is ICompiledTypeNode))
if (!(interf is ICompiledTypeNode) && (interf != t)) // SSM 15/02/23 (interf != t) добавил в связи с ковариантностью
// т.к. в случае IEnumerable<object> = IEnumerable<Student> возникал сбой
ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)interf);
if (t.base_type != null && !(t.base_type is ICompiledTypeNode))
{

View file

@ -1 +1 @@
3.8.3.3233
3.8.3.3247

View file

@ -1 +1 @@
!define VERSION '3.8.3.3233'
!define VERSION '3.8.3.3247'

View file

@ -1,4 +1,4 @@
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
/// <summary>
@ -59,11 +59,11 @@ function ReadKey: char;
/// </summary>
function KeyPressed: boolean;
/// <summary>
/// Возвращает высоту экрана
/// Возвращает ширину экрана
/// </summary>
function WindowWidth: integer;
/// <summary>
/// Возвращает ширину экрана
/// Возвращает высоту экрана
/// </summary>
/// <returns></returns>
function WindowHeight: integer;

View file

@ -1804,7 +1804,7 @@ function Min(a, b, c: integer): integer;
function Min(a, b, c, d: integer): integer;
///-function Max(a,b,...: T): T;
/// Возвращает максиимальное из a,b,...
/// Возвращает максимальное из a,b,...
function Max<T>(params a: array of T): T;
///--
//function Max(params a: array of real): real;
@ -2271,6 +2271,8 @@ function SeqWhile<T>(first: T; next: T->T; pred: T->boolean): sequence of T;
function SeqWhile<T>(first, second: T; next: (T,T) ->T; pred: T->boolean): sequence of T;
/// Возвращает последовательность из count элементов x
function SeqFill<T>(count: integer; x: T): sequence of T;
/// Возвращает бесконечную рекуррентную последовательность элементов, задаваемую начальным элементом first и функцией next
function Iterate<T>(first: T; next: T->T): sequence of T;
/// Возвращает последовательность из n целых, введенных с клавиатуры
function ReadSeqInteger(n: integer): sequence of integer;
@ -2438,6 +2440,10 @@ function Lst<T>(a: sequence of T): List<T>;
function Lst(a: IntRange): List<integer>;
/// Возвращает список, заполненный диапазоном значений
function Lst(a: CharRange): List<char>;
/// Возвращает список, заполненный указанными целыми значениями
function LstStr(params a: array of string): List<string>;
/// Возвращает список, заполненный указанными целыми значениями
function LstInt(params a: array of integer): List<integer>;
/// Возвращает двусвязный список, заполненный указанными значениями
function LLst<T>(params a: array of T): LinkedList<T>;
@ -2456,8 +2462,12 @@ function HSet<T>(a: sequence of T): HashSet<T>;
function HSet(a: IntRange): HashSet<integer>;
/// Возвращает множество на базе хеш таблицы, заполненное заполненный диапазоном значений
function HSet(a: CharRange): HashSet<char>;
/// Возвращает множество на базе хеш таблицы, заполненное целыми значениями
function HSetInt(params a: array of integer): HashSet<integer>;
/// Возвращает множество на базе хеш таблицы, заполненное строковыми значениями
function HSetStr(params a: array of string): HashSet<string>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное значениями из последовательности
/// Возвращает множество на базе бинарного дерева поиска, заполненное указанными значениями
function SSet<T>(params a: array of T): SortedSet<T>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное значениями из последовательности
function SSet<T>(a: sequence of T): SortedSet<T>;
@ -2465,18 +2475,26 @@ function SSet<T>(a: sequence of T): SortedSet<T>;
function SSet(a: IntRange): SortedSet<integer>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное диапазоном значений
function SSet(a: CharRange): SortedSet<char>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное целыми значениями
function SSetInt(params a: array of integer): SortedSet<integer>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное строковыми значениями
function SSetStr(params a: array of string): SortedSet<string>;
/// Возвращает словарь пар элементов (ключ, значение)
function Dict<TKey, TVal>(params pairs: array of KeyValuePair<TKey, TVal>): Dictionary<TKey, TVal>;
/// Возвращает словарь пар элементов (ключ, значение)
function Dict<TKey, TVal>(params pairs: array of (TKey, TVal)): Dictionary<TKey, TVal>;
/// Возвращает словарь пар элементов (ключ, значение), построенный на значениях последовательности
function Dict<TKey, TVal>(pairs: sequence of (TKey, TVal)): Dictionary<TKey, TVal>;
/// Возвращает пару элементов (ключ, значение)
function KV<TKey, TVal>(key: TKey; value: TVal): KeyValuePair<TKey, TVal>;
/// Возвращает словарь пар элементов (строка, строка)
function DictStr(params pairs: array of (string, string)): Dictionary<string, string>;
/// Возвращает словарь пар элементов (строка, целое)
function DictStrInt(params pairs: array of (string, integer)): Dictionary<string, integer>;
/// Возвращает словарь пар элементов (целое, целое)
function DictInt(params pairs: array of (integer, integer)): Dictionary<integer, integer>;
//{{{--doc: Конец секции интерфейса для документации }}}
@ -5176,6 +5194,11 @@ function Lst(a: IntRange): List<integer> := a.ToList;
function Lst(a: CharRange): List<char> := a.ToList;
function LstStr(params a: array of string): List<string> := a.ToList;
function LstInt(params a: array of integer): List<integer> := a.ToList;
function LLst<T>(params a: array of T): LinkedList<T> := new LinkedList<T>(a);
function LLst<T>(a: sequence of T): LinkedList<T> := new LinkedList<T>(a);
@ -5193,10 +5216,20 @@ function HSet<T>(a: sequence of T): HashSet<T> := new HashSet<T>(a);
function SSet<T>(a: sequence of T): SortedSet<T> := new SortedSet<T>(a);
function HSetInt(params a: array of integer): HashSet<integer> := a.ToHashSet;
function HSetStr(params a: array of string): HashSet<string> := a.ToHashSet;
function SSetInt(params a: array of integer): SortedSet<integer> := new SortedSet<integer>(a);
function SSetStr(params a: array of string): SortedSet<string> := new SortedSet<string>(a);
function HSet(a: IntRange): HashSet<integer> := a.ToHashSet;
function HSet(a: CharRange): HashSet<char> := a.ToHashSet;
function SSet(a: IntRange): SortedSet<integer> := a.ToSortedSet;
function SSet(a: CharRange): SortedSet<char> := a.ToSortedSet;
@ -5216,6 +5249,9 @@ begin
Result.Add(pairs[i][0], pairs[i][1]);
end;
function Dict<TKey, TVal>(pairs: sequence of (TKey, TVal)): Dictionary<TKey, TVal>
:= Dict(pairs.ToArray); // внутренняя ошибка компилятора
function KV<TKey, TVal>(key: TKey; value: TVal): KeyValuePair<TKey, TVal>;
begin
Result := new KeyValuePair<TKey, TVal>(key, value);
@ -5227,6 +5263,8 @@ function DictStr(params pairs: array of (string, string)): Dictionary<string, st
function DictStrInt(params pairs: array of (string, integer)): Dictionary<string, integer>
:= Dict&<string, integer>(pairs);
function DictInt(params pairs: array of (integer, integer)): Dictionary<integer, integer>
:= Dict&<integer, integer>(pairs);
function __TypeCheckAndAssignForIsMatch<T>(obj: object; var res: T): boolean;
begin

View file

@ -17,7 +17,7 @@ procedure Left;
procedure Up;
/// Переместить Робота вниз
procedure Down;
/// Закрасить текущую ячейку
/// Закрасить текущую клетку
procedure Paint;
/// Возвращает True, если справа от Робота - свободно, и False в противном случае
function FreeFromRight: boolean;
@ -35,9 +35,9 @@ function WallFromLeft: boolean;
function WallFromUp: boolean;
/// Возвращает True, если снизу от Робота - стена, и False в противном случае
function WallFromDown: boolean;
/// Возвращает True, если текущая ячейка не закрашена, и False в противном случае
/// Возвращает True, если текущая клетка не закрашена, и False в противном случае
function CellIsFree: boolean;
/// Возвращает True, если текущая ячейка закрашена, и False в противном случае
/// Возвращает True, если текущая клетка закрашена, и False в противном случае
function CellIsPainted: boolean;
/// Вызывать задание с именем name
procedure Task(name: string);
@ -79,10 +79,14 @@ function СлеваСтена: boolean;
function СверхуСтена: boolean;
/// Возвращает True, если снизу от Робота - стена, и False в противном случае
function СнизуСтена: boolean;
/// Возвращает True, если текущая ячейка не закрашена, и False в противном случае
/// Возвращает True, если текущая клетка не закрашена, и False в противном случае
function ЯчейкаНеЗакрашена: boolean;
/// Возвращает True, если текущая ячейка закрашена, и False в противном случае
/// Возвращает True, если текущая клетка закрашена, и False в противном случае
function ЯчейкаЗакрашена: boolean;
/// Возвращает True, если текущая клетка не закрашена, и False в противном случае
function КлеткаНеЗакрашена: boolean;
/// Возвращает True, если текущая клетка закрашена, и False в противном случае
function КлеткаЗакрашена: boolean;
/// Вызывать задание с данным именем
procedure Задание(имя: string);
/// Создать пустое поле размера 9 на 11 клеток
@ -250,6 +254,8 @@ function СверхуСтена := WallFromUp;
function СнизуСтена := WallFromDown;
function ЯчейкаНеЗакрашена := CellIsFree;
function ЯчейкаЗакрашена := CellIsPainted;
function КлеткаНеЗакрашена := CellIsFree;
function КлеткаЗакрашена := CellIsPainted;
procedure Задание(имя: string) := Task(имя);
procedure СтандартноеПоле := StandardField;
procedure Поле(n,m: integer) := Field(n,m);

View file

@ -75,8 +75,16 @@ function FirstPrimes(k: integer): List<integer>;
/// Количество простых делителей числа n
function PrimeDivisorsCount(n: integer): integer;
/// Возвращает список, содержащий цифры числа n
function Digits(n: int64): List<integer>;
/// Возвращает целочисленный список расширенного представления
/// десятичного числа n по основанию base.
/// По умолчанию base=10 и возвращается список десятичных цифр числа n.
/// Обратное действие выполняет функция Refold.
function Digits(n: int64; base: integer := 10): List<integer>;
/// Возвращает целое десятичное число на основе его расширенного представления
/// по основанию base (по умолчанию base=10).
/// Функция выполняет действие, обратное функции Digits,
function DigitsToInt64(ext: List<integer>; base: integer := 10): int64;
/// Возвращает список делителей натурального числа n
function Divisors(n: integer): List<integer>;
@ -667,32 +675,47 @@ function PrimeDivisorsCount(Self: integer): integer; extensionmethod := PrimeDiv
{$region Digits}
/// Возвращает список, содержащий цифры числа n
function Digits(n: int64): List<integer>;
/// Возвращает целочисленный список расширенного представления
/// десятичного числа n по основанию base.
/// По умолчанию base=10 и возвращается список десятичных цифр числа n.
/// Обратное действие выполняет функция Refold.
function Digits(n: int64; base: integer): List<integer>;
begin
Result := new List<integer>;
n := Abs(n);
if n = 0 then Result := |0|.ToList
if (n < 0) or (base < 2) then exit;
if n = 0 then Result := Lst(0)
else
begin
while n > 0 do
begin
Result.Add(n mod 10);
n := n div 10
var rem: integer := n mod base;
Result.Add(rem);
n := n div base
end;
Result.Reverse
end;
function Digits(Self: integer; base: integer := 10): List<integer>;
extensionmethod := Digits(Self, base);
function Digits(Self: int64; base: integer := 10): List<integer>;
extensionmethod := Digits(Self, base);
/// Возвращает целое десятичное число на основе его расширенного представления
/// по основанию base (по умолчанию base=10).
/// Функция выполняет действие, обратное функции Digits
function DigitsToInt64(ext: List<integer>; base: integer): int64;
begin
Result := 0;
var p := int64(1);
for var i := ext.Count -1 downto 0 do
begin
Result += ext[i] * p;
p *= base
end
end;
/// Возвращает список, содержащий цифры числа
function Digits(Self: integer): List<integer>;
extensionmethod :=
Digits(Self);
/// Возвращает список, содержащий цифры числа
function Digits(Self: int64): List<integer>;
extensionmethod :=
Digits(Self);
function DigitsToInt64(Self: List<integer>; base: integer := 10): int64;
extensionmethod := DigitsToInt64(Self, base);
{$endregion}

View file

@ -338,8 +338,18 @@ type
private
procedure AnimMoveByP(a,b,sec: real);
begin
var ax := new DoubleAnimation(a + transl.X, System.TimeSpan.FromSeconds(sec));
var ay := new DoubleAnimation(b + transl.Y, System.TimeSpan.FromSeconds(sec));
var (x,y) := (transl.X,transl.Y);
var ax := new DoubleAnimation(a + x, System.TimeSpan.FromSeconds(sec));
var ay := new DoubleAnimation(b + y, System.TimeSpan.FromSeconds(sec));
ax.FillBehavior := FillBehavior.Stop;
ay.FillBehavior := FillBehavior.Stop;
var transl1 := transl;
ax.Completed += (o,e) -> begin
transl1.X := x + a; // transl - ошибка с лямбдами!
end;
ay.Completed += (o,e) -> begin
transl1.Y := y + b;
end;
transl.BeginAnimation(TranslateTransform.XProperty, ax, HandoffBehavior.Compose);
transl.BeginAnimation(TranslateTransform.YProperty, ay, HandoffBehavior.Compose);
end;
@ -348,6 +358,15 @@ type
begin
var ax := new DoubleAnimation(x, System.TimeSpan.FromSeconds(sec));
var ay := new DoubleAnimation(y, System.TimeSpan.FromSeconds(sec));
ax.FillBehavior := FillBehavior.Stop;
ay.FillBehavior := FillBehavior.Stop;
var transl1 := transl;
ax.Completed += (o,e) -> begin
transl1.X := x;
end;
ay.Completed += (o,e) -> begin
transl1.Y := y;
end;
transl.BeginAnimation(TranslateTransform.XProperty, ax, HandoffBehavior.Compose);
transl.BeginAnimation(TranslateTransform.YProperty, ay, HandoffBehavior.Compose);
end;
@ -361,6 +380,10 @@ type
procedure AnimRotateP(a,sec: real);
begin
var an := new DoubleAnimation(a + rot.Angle, System.TimeSpan.FromSeconds(sec));
an.FillBehavior := FillBehavior.Stop;
an.Completed += (o,e) -> begin
rot.Angle := a + rot.Angle;
end;
rot.BeginAnimation(RotateTransform.AngleProperty, an, HandoffBehavior.Compose);
end;
procedure AnimScaleP(a,sec: real);
@ -368,6 +391,11 @@ type
var an := new DoubleAnimation(a, System.TimeSpan.FromSeconds(sec));
sca.CenterX := Width / 2;
sca.CenterY := Height / 2;
an.FillBehavior := FillBehavior.Stop;
an.Completed += (o,e) -> begin
sca.ScaleX := a;
sca.ScaleY := a;
end;
sca.BeginAnimation(ScaleTransform.ScaleXProperty, an, HandoffBehavior.Compose);
sca.BeginAnimation(ScaleTransform.ScaleYProperty, an, HandoffBehavior.Compose);
end;

View file

@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@ -568,55 +569,89 @@ namespace PascalABCCompiler.TreeRealization
//implements = tnode.ImplementingInterfaces.Contains(base_class);
implements = false;
foreach (var interf in tnode.ImplementingInterfaces)
// Цикл по всем реализуемым интерфейсам. А если tnode сам является интерфейсом?
var ImplementingInterfaces = tnode.ImplementingInterfaces.ToList();
//if (tnode.IsInterface)
// ImplementingInterfaces.Add(tnode);
foreach (var interf in ImplementingInterfaces)
{
var ctn = interf as compiled_type_node;
// if (ctn.generic_params == null || ctn.generic_params.Count == 0)
// ctn = null;
var bcctn = base_class as compiled_type_node; // мне кажется, здесь надо проверять на наличие generic-параметров
//if (bcctn.generic_params == null || bcctn.generic_params.Count == 0)
// bcctn = null;
var cgitn = interf as compiled_generic_instance_type_node;
var bcgitn = base_class as compiled_generic_instance_type_node;
// interf - IEnumerable<Student>, base_class - IEnumerable<Person>
if (interf == base_class)
{
implements = true;
break;
}
// Справка:
// IEnumerable<object> - compiled_type_node
// IEnumerable<Student>, List<Student> - compiled_generic_instance_type_node
// MyIEnumerable<Student>, MyIEnumerable<object> - common_generic_instance_type_node
// Здесь common быть не может поскольку ковариантность у нас - только для откомпилированных NET-типов
// Тут можно проверить на ковариантность
// еще где то надо проверять, что IEnumerable<Derived> -> IEnumerable<Base>, но здесь base_class предполагает,
// что это - класс, и рассматривает все его интерфейсы, упуская ситуацию, когда base_class - это и есть интерфейс
else if (interf is compiled_generic_instance_type_node cgitn && base_class is compiled_generic_instance_type_node bcgitn)
//else if ((cgitn != null || ctn != null) && (bcgitn != null || bcctn != null))
//else if ((cgitn != null || ctn != null) && bcgitn != null)
else if (cgitn != null && bcgitn != null)
{
if (cgitn.original_generic != null && cgitn.original_generic == bcgitn.original_generic)
{
var ctcgi = cgitn.original_generic as compiled_type_node;
if (ctcgi != null)
{
// теперь надо проверить параметры на ковариантность - все
var n = bcgitn.instance_params.Count;
var n1 = cgitn.instance_params.Count;
compiled_type_node interf_original_generic = cgitn != null ? cgitn.original_generic as compiled_type_node : ctn.original_generic as compiled_type_node;
compiled_type_node base_original_generic = bcgitn != null ? bcgitn.original_generic as compiled_type_node : bcctn.original_generic as compiled_type_node;
List<type_node> interf_instance_params = cgitn != null ? cgitn.instance_params : ctn.instance_params;
List<type_node> base_instance_params = bcgitn != null ? bcgitn.instance_params : bcctn.instance_params;
var impl = true;
if (n != n1)
impl = false;
else
for (int i=0; i<n; i++)
//compiled_type_node interf_original_generic = cgitn.original_generic as compiled_type_node;
//compiled_type_node base_original_generic = bcgitn.original_generic as compiled_type_node;
//List<type_node> interf_instance_params = cgitn.instance_params;
//List<type_node> base_instance_params = bcgitn.instance_params;
if (interf_original_generic != null && interf_original_generic == base_original_generic)
{
// Нам нужно два original_generic as compiled_type_node и два instance_params
//if (ctcgi != null) // по идее это всегда так! потому что cgitn - compiled - поэтому закомментировал SSM 14/02/23
// теперь надо проверить параметры на ковариантность - все
var n = base_instance_params.Count;
var n1 = interf_instance_params.Count;
// перенес сюда. cgitn точно не null
var interf_compiled_type = interf_original_generic.compiled_type; // Пр: IEnumerable<T>
var impl = true;
if (n != n1)
impl = false;
else
for (int i=0; i<n; i++)
{
// ctcgi.compiled_type - это System.Type
if ((interf_compiled_type.GetGenericArguments()[i].GenericParameterAttributes & System.Reflection.GenericParameterAttributes.Covariant) != 0)
{
if ((ctcgi.compiled_type.GetGenericArguments()[i].GenericParameterAttributes & System.Reflection.GenericParameterAttributes.Covariant) != 0)
if (is_derived(base_instance_params[i], interf_instance_params[i], false))
{
if (is_derived(bcgitn.instance_params[i], cgitn.instance_params[i], false))
{
// OK
}
}
// Почему то когда это закомментировано, то работает. А так не вызывается ??!
/*else if (bcgitn.instance_params[i] == cgitn.instance_params[i])
{
n = n;
// Тоже OK
}*/
else
{
impl = false;
break;
// OK
}
}
// то есть если все контравариантные или неважно какие, но равные то implements = true иначе false
implements = impl;
}
// Почему то когда это закомментировано, то работает. А так не вызывается ??!
/*else if (base_instance_params[i] == interf_instance_params[i])
{
n = n;
// Тоже OK
}*/
else
{
impl = false;
break;
}
}
// то есть если все контравариантные или неважно какие, но равные то implements = true иначе false
implements = impl;
if (implements)
break;
}
}
else if (interf is compiled_type_node ictn && base_class is compiled_type_node bctn)

View file

@ -167,9 +167,9 @@
this.label12.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.label12.Location = new System.Drawing.Point(3, 0);
this.label12.Name = "label12";
this.label12.Size = new System.Drawing.Size(317, 13);
this.label12.Size = new System.Drawing.Size(311, 13);
this.label12.TabIndex = 17;
this.label12.Text = "Copyright (c) 2005, 2023 Ivan Bondarev, Stanislav Mikhalkovich";
this.label12.Text = "Copyright (c) 2005, 2023 Ivan Bondarev, Stanislav Mikhalkovich";
//
// label9
//

View file

@ -25,7 +25,14 @@ namespace VisualPascalABC
}
public void AppendTextToConsoleCompiler(object text)
{
CompilerConsole.AppendText(text as string);
try
{
CompilerConsole.AppendText(text as string); // SSM !!!!!!!!!!!!!!! 18/02/23
}
catch (Exception e)
{
}
}
public void AddTextToCompilerMessages(string text)

View file

@ -103,6 +103,8 @@ namespace VisualPascalABCPlugins
key = key.OpenSubKey("Microsoft");
key = key.OpenSubKey("VisualStudio");
key = key.OpenSubKey("8.0");
if (key == null)
return null;
string s = (string)key.GetValue("InstallDir");
key.Close();
s = System.IO.Path.GetDirectoryName(s);

View file

@ -43,7 +43,9 @@
this.PluginImageAuthorized = new System.Windows.Forms.PictureBox();
this.panelUnAuthorized = new System.Windows.Forms.Panel();
this.panelAuthorized = new System.Windows.Forms.Panel();
this.labelRating = new System.Windows.Forms.Label();
this.labelUserName = new System.Windows.Forms.Label();
this.labelDetails = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.userImage)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.groupImage)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.PluginImage)).BeginInit();
@ -186,21 +188,41 @@
//
// panelAuthorized
//
this.panelAuthorized.Controls.Add(this.labelRating);
this.panelAuthorized.Controls.Add(this.labelDetails);
this.panelAuthorized.Controls.Add(this.labelUserName);
this.panelAuthorized.Location = new System.Drawing.Point(0, 0);
this.panelAuthorized.Name = "panelAuthorized";
this.panelAuthorized.Size = new System.Drawing.Size(422, 132);
this.panelAuthorized.TabIndex = 14;
//
// labelRating
//
this.labelRating.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.labelRating.Location = new System.Drawing.Point(12, 50);
this.labelRating.Name = "labelRating";
this.labelRating.Size = new System.Drawing.Size(398, 26);
this.labelRating.TabIndex = 12;
this.labelRating.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// labelUserName
//
this.labelUserName.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.labelUserName.Location = new System.Drawing.Point(25, 14);
this.labelUserName.Font = new System.Drawing.Font("Microsoft Sans Serif", 13F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.labelUserName.Location = new System.Drawing.Point(0, 14);
this.labelUserName.Name = "labelUserName";
this.labelUserName.Size = new System.Drawing.Size(372, 26);
this.labelUserName.Size = new System.Drawing.Size(419, 26);
this.labelUserName.TabIndex = 11;
this.labelUserName.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// labelDetails
//
this.labelDetails.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.labelDetails.Location = new System.Drawing.Point(12, 86);
this.labelDetails.Name = "labelDetails";
this.labelDetails.Size = new System.Drawing.Size(398, 26);
this.labelDetails.TabIndex = 13;
this.labelDetails.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// LoginForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -247,5 +269,7 @@
private System.Windows.Forms.Panel panelUnAuthorized;
private System.Windows.Forms.Label labelUserName;
private System.Windows.Forms.Panel panelAuthorized;
private System.Windows.Forms.Label labelRating;
private System.Windows.Forms.Label labelDetails;
}
}

View file

@ -238,6 +238,12 @@ namespace DBAccessPluginNamespace
}
}
public void SetRating(string rating)
{
var ss = rating.Split('|');
labelRating.Text = $"Рейтинг: {ss[0]} баллов";
labelDetails.Text = ss[1];
}
public void ChangeControlsAfterLogin(string login)
{
try
@ -260,6 +266,7 @@ namespace DBAccessPluginNamespace
closeButton.Focus();
panelUnAuthorized.SendToBack();
labelUserName.Text = login;
//labelRating.Text = "Рейтинг: ";
}
catch (Exception e)
{
@ -307,6 +314,9 @@ namespace DBAccessPluginNamespace
{
WriteLoginPassToAuthDat(usersNamesBox.Text, passwordBox.Text);
ChangeControlsAfterLogin(usersNamesBox.Text);
var Rating = await SiteProvider.GetRating("", usersNamesBox.Text, passwordBox.Text);
SetRating(Rating);
//labelRating.Text = "Рейтинг: " + Rating.ToString();
}
else MessageBox.Show(answer, "Ошибка");
}

View file

@ -213,6 +213,61 @@ namespace DBAccessPluginNamespace
return "Success";
}
async public Task<string> GetRating(string shortFIO, string fullFIO, string password)
{
var values = new Dictionary<string, string>
{
//`id`, `pupilId`, `taskName`, `lessonName`, `type`, `content`, `time`, `IP`
//{ "shortFIO", ShortFIO }, // shortFIO или FIO, и они должны совпадать с такими же в базе
{ "FIO", FullFIO },
//{ "password", Password}
};
// Отправка запроса на сервер
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync(ServAddr + "/getRating.php", content);
string responseText = await response.Content.ReadAsStringAsync();
var pieces = responseText.Split(';');
var res = "";
var ClassTasksSolved = 0;
var ControlTasksSolved = 0;
var HomeworkTasksSolved = 0;
var AdditionalTasksSolved = 0;
try
{
foreach (var s in pieces)
{
if (s.IndexOf(':') < 1) continue;
var pair = s.Split(':');
switch (pair[0])
{
case "ClassTasks":
ClassTasksSolved = int.Parse(pair[2]);
break;
case "ControlTasks":
ControlTasksSolved = int.Parse(pair[2]);
break;
case "HomeworkTasks":
HomeworkTasksSolved = int.Parse(pair[2]);
break;
case "AdditionalTasks":
AdditionalTasksSolved = int.Parse(pair[2]);
break;
}
}
// великая формула !!!
var Rating = ClassTasksSolved * 1 + ControlTasksSolved * 5 + HomeworkTasksSolved * 3 + AdditionalTasksSolved * 2;
var Details = $" (Осн: {ClassTasksSolved}×1, Доп: {AdditionalTasksSolved}×2, ДЗ: {HomeworkTasksSolved}×3, КР: {ControlTasksSolved}×5)";
res = Rating.ToString() + '|' + Details;
}
catch (Exception e)
{
res = e.Message;
}
return res;
}
// Так как мы на сервере пока ничего не запоминаем, то процесс выхода - просто стереть всё
public void Logout()
{

View file

@ -97,6 +97,8 @@ namespace VisualPascalABCPlugins
if (answer.Result == "Success")
{
loginForm.ChangeControlsAfterLogin(login);
var Rating = User.GetRating("", login, pass);
loginForm.SetRating(Rating.Result);
}
}
catch (Exception e)

View file

@ -1,4 +1,4 @@
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
/// <summary>
@ -59,11 +59,11 @@ function ReadKey: char;
/// </summary>
function KeyPressed: boolean;
/// <summary>
/// Возвращает высоту экрана
/// Возвращает ширину экрана
/// </summary>
function WindowWidth: integer;
/// <summary>
/// Возвращает ширину экрана
/// Возвращает высоту экрана
/// </summary>
/// <returns></returns>
function WindowHeight: integer;

View file

@ -1804,7 +1804,7 @@ function Min(a, b, c: integer): integer;
function Min(a, b, c, d: integer): integer;
///-function Max(a,b,...: T): T;
/// Возвращает максиимальное из a,b,...
/// Возвращает максимальное из a,b,...
function Max<T>(params a: array of T): T;
///--
//function Max(params a: array of real): real;
@ -2271,6 +2271,8 @@ function SeqWhile<T>(first: T; next: T->T; pred: T->boolean): sequence of T;
function SeqWhile<T>(first, second: T; next: (T,T) ->T; pred: T->boolean): sequence of T;
/// Возвращает последовательность из count элементов x
function SeqFill<T>(count: integer; x: T): sequence of T;
/// Возвращает бесконечную рекуррентную последовательность элементов, задаваемую начальным элементом first и функцией next
function Iterate<T>(first: T; next: T->T): sequence of T;
/// Возвращает последовательность из n целых, введенных с клавиатуры
function ReadSeqInteger(n: integer): sequence of integer;
@ -2438,6 +2440,10 @@ function Lst<T>(a: sequence of T): List<T>;
function Lst(a: IntRange): List<integer>;
/// Возвращает список, заполненный диапазоном значений
function Lst(a: CharRange): List<char>;
/// Возвращает список, заполненный указанными целыми значениями
function LstStr(params a: array of string): List<string>;
/// Возвращает список, заполненный указанными целыми значениями
function LstInt(params a: array of integer): List<integer>;
/// Возвращает двусвязный список, заполненный указанными значениями
function LLst<T>(params a: array of T): LinkedList<T>;
@ -2456,8 +2462,12 @@ function HSet<T>(a: sequence of T): HashSet<T>;
function HSet(a: IntRange): HashSet<integer>;
/// Возвращает множество на базе хеш таблицы, заполненное заполненный диапазоном значений
function HSet(a: CharRange): HashSet<char>;
/// Возвращает множество на базе хеш таблицы, заполненное целыми значениями
function HSetInt(params a: array of integer): HashSet<integer>;
/// Возвращает множество на базе хеш таблицы, заполненное строковыми значениями
function HSetStr(params a: array of string): HashSet<string>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное значениями из последовательности
/// Возвращает множество на базе бинарного дерева поиска, заполненное указанными значениями
function SSet<T>(params a: array of T): SortedSet<T>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное значениями из последовательности
function SSet<T>(a: sequence of T): SortedSet<T>;
@ -2465,18 +2475,26 @@ function SSet<T>(a: sequence of T): SortedSet<T>;
function SSet(a: IntRange): SortedSet<integer>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное диапазоном значений
function SSet(a: CharRange): SortedSet<char>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное целыми значениями
function SSetInt(params a: array of integer): SortedSet<integer>;
/// Возвращает множество на базе бинарного дерева поиска, заполненное строковыми значениями
function SSetStr(params a: array of string): SortedSet<string>;
/// Возвращает словарь пар элементов (ключ, значение)
function Dict<TKey, TVal>(params pairs: array of KeyValuePair<TKey, TVal>): Dictionary<TKey, TVal>;
/// Возвращает словарь пар элементов (ключ, значение)
function Dict<TKey, TVal>(params pairs: array of (TKey, TVal)): Dictionary<TKey, TVal>;
/// Возвращает словарь пар элементов (ключ, значение), построенный на значениях последовательности
function Dict<TKey, TVal>(pairs: sequence of (TKey, TVal)): Dictionary<TKey, TVal>;
/// Возвращает пару элементов (ключ, значение)
function KV<TKey, TVal>(key: TKey; value: TVal): KeyValuePair<TKey, TVal>;
/// Возвращает словарь пар элементов (строка, строка)
function DictStr(params pairs: array of (string, string)): Dictionary<string, string>;
/// Возвращает словарь пар элементов (строка, целое)
function DictStrInt(params pairs: array of (string, integer)): Dictionary<string, integer>;
/// Возвращает словарь пар элементов (целое, целое)
function DictInt(params pairs: array of (integer, integer)): Dictionary<integer, integer>;
//{{{--doc: Конец секции интерфейса для документации }}}
@ -5176,6 +5194,11 @@ function Lst(a: IntRange): List<integer> := a.ToList;
function Lst(a: CharRange): List<char> := a.ToList;
function LstStr(params a: array of string): List<string> := a.ToList;
function LstInt(params a: array of integer): List<integer> := a.ToList;
function LLst<T>(params a: array of T): LinkedList<T> := new LinkedList<T>(a);
function LLst<T>(a: sequence of T): LinkedList<T> := new LinkedList<T>(a);
@ -5193,10 +5216,20 @@ function HSet<T>(a: sequence of T): HashSet<T> := new HashSet<T>(a);
function SSet<T>(a: sequence of T): SortedSet<T> := new SortedSet<T>(a);
function HSetInt(params a: array of integer): HashSet<integer> := a.ToHashSet;
function HSetStr(params a: array of string): HashSet<string> := a.ToHashSet;
function SSetInt(params a: array of integer): SortedSet<integer> := new SortedSet<integer>(a);
function SSetStr(params a: array of string): SortedSet<string> := new SortedSet<string>(a);
function HSet(a: IntRange): HashSet<integer> := a.ToHashSet;
function HSet(a: CharRange): HashSet<char> := a.ToHashSet;
function SSet(a: IntRange): SortedSet<integer> := a.ToSortedSet;
function SSet(a: CharRange): SortedSet<char> := a.ToSortedSet;
@ -5216,6 +5249,9 @@ begin
Result.Add(pairs[i][0], pairs[i][1]);
end;
function Dict<TKey, TVal>(pairs: sequence of (TKey, TVal)): Dictionary<TKey, TVal>
:= Dict(pairs.ToArray); // внутренняя ошибка компилятора
function KV<TKey, TVal>(key: TKey; value: TVal): KeyValuePair<TKey, TVal>;
begin
Result := new KeyValuePair<TKey, TVal>(key, value);
@ -5227,6 +5263,8 @@ function DictStr(params pairs: array of (string, string)): Dictionary<string, st
function DictStrInt(params pairs: array of (string, integer)): Dictionary<string, integer>
:= Dict&<string, integer>(pairs);
function DictInt(params pairs: array of (integer, integer)): Dictionary<integer, integer>
:= Dict&<integer, integer>(pairs);
function __TypeCheckAndAssignForIsMatch<T>(obj: object; var res: T): boolean;
begin

View file

@ -17,7 +17,7 @@ procedure Left;
procedure Up;
/// Переместить Робота вниз
procedure Down;
/// Закрасить текущую ячейку
/// Закрасить текущую клетку
procedure Paint;
/// Возвращает True, если справа от Робота - свободно, и False в противном случае
function FreeFromRight: boolean;
@ -35,9 +35,9 @@ function WallFromLeft: boolean;
function WallFromUp: boolean;
/// Возвращает True, если снизу от Робота - стена, и False в противном случае
function WallFromDown: boolean;
/// Возвращает True, если текущая ячейка не закрашена, и False в противном случае
/// Возвращает True, если текущая клетка не закрашена, и False в противном случае
function CellIsFree: boolean;
/// Возвращает True, если текущая ячейка закрашена, и False в противном случае
/// Возвращает True, если текущая клетка закрашена, и False в противном случае
function CellIsPainted: boolean;
/// Вызывать задание с именем name
procedure Task(name: string);
@ -79,10 +79,14 @@ function СлеваСтена: boolean;
function СверхуСтена: boolean;
/// Возвращает True, если снизу от Робота - стена, и False в противном случае
function СнизуСтена: boolean;
/// Возвращает True, если текущая ячейка не закрашена, и False в противном случае
/// Возвращает True, если текущая клетка не закрашена, и False в противном случае
function ЯчейкаНеЗакрашена: boolean;
/// Возвращает True, если текущая ячейка закрашена, и False в противном случае
/// Возвращает True, если текущая клетка закрашена, и False в противном случае
function ЯчейкаЗакрашена: boolean;
/// Возвращает True, если текущая клетка не закрашена, и False в противном случае
function КлеткаНеЗакрашена: boolean;
/// Возвращает True, если текущая клетка закрашена, и False в противном случае
function КлеткаЗакрашена: boolean;
/// Вызывать задание с данным именем
procedure Задание(имя: string);
/// Создать пустое поле размера 9 на 11 клеток
@ -250,6 +254,8 @@ function СверхуСтена := WallFromUp;
function СнизуСтена := WallFromDown;
function ЯчейкаНеЗакрашена := CellIsFree;
function ЯчейкаЗакрашена := CellIsPainted;
function КлеткаНеЗакрашена := CellIsFree;
function КлеткаЗакрашена := CellIsPainted;
procedure Задание(имя: string) := Task(имя);
procedure СтандартноеПоле := StandardField;
procedure Поле(n,m: integer) := Field(n,m);

View file

@ -75,8 +75,16 @@ function FirstPrimes(k: integer): List<integer>;
/// Количество простых делителей числа n
function PrimeDivisorsCount(n: integer): integer;
/// Возвращает список, содержащий цифры числа n
function Digits(n: int64): List<integer>;
/// Возвращает целочисленный список расширенного представления
/// десятичного числа n по основанию base.
/// По умолчанию base=10 и возвращается список десятичных цифр числа n.
/// Обратное действие выполняет функция Refold.
function Digits(n: int64; base: integer := 10): List<integer>;
/// Возвращает целое десятичное число на основе его расширенного представления
/// по основанию base (по умолчанию base=10).
/// Функция выполняет действие, обратное функции Digits,
function DigitsToInt64(ext: List<integer>; base: integer := 10): int64;
/// Возвращает список делителей натурального числа n
function Divisors(n: integer): List<integer>;
@ -667,32 +675,47 @@ function PrimeDivisorsCount(Self: integer): integer; extensionmethod := PrimeDiv
{$region Digits}
/// Возвращает список, содержащий цифры числа n
function Digits(n: int64): List<integer>;
/// Возвращает целочисленный список расширенного представления
/// десятичного числа n по основанию base.
/// По умолчанию base=10 и возвращается список десятичных цифр числа n.
/// Обратное действие выполняет функция Refold.
function Digits(n: int64; base: integer): List<integer>;
begin
Result := new List<integer>;
n := Abs(n);
if n = 0 then Result := |0|.ToList
if (n < 0) or (base < 2) then exit;
if n = 0 then Result := Lst(0)
else
begin
while n > 0 do
begin
Result.Add(n mod 10);
n := n div 10
var rem: integer := n mod base;
Result.Add(rem);
n := n div base
end;
Result.Reverse
end;
function Digits(Self: integer; base: integer := 10): List<integer>;
extensionmethod := Digits(Self, base);
function Digits(Self: int64; base: integer := 10): List<integer>;
extensionmethod := Digits(Self, base);
/// Возвращает целое десятичное число на основе его расширенного представления
/// по основанию base (по умолчанию base=10).
/// Функция выполняет действие, обратное функции Digits
function DigitsToInt64(ext: List<integer>; base: integer): int64;
begin
Result := 0;
var p := int64(1);
for var i := ext.Count -1 downto 0 do
begin
Result += ext[i] * p;
p *= base
end
end;
/// Возвращает список, содержащий цифры числа
function Digits(Self: integer): List<integer>;
extensionmethod :=
Digits(Self);
/// Возвращает список, содержащий цифры числа
function Digits(Self: int64): List<integer>;
extensionmethod :=
Digits(Self);
function DigitsToInt64(Self: List<integer>; base: integer := 10): int64;
extensionmethod := DigitsToInt64(Self, base);
{$endregion}

View file

@ -1,8 +1,93 @@
unit TurtleWPF;
interface
uses GraphWPF;
/// Передвигает Черепаху вперёд на расстояние r
procedure Forw(r: real);
/// Передвигает Черепаху назад на расстояние r
procedure Back(r: real);
/// Поворачивает Черепаху на угол da по часовой стрелке
procedure Turn(da: real);
/// Поворачивает Черепаху на угол da по часовой стрелке
procedure TurnLeft(da: real);
/// Поворачивает Черепаху на угол da против часовой стрелке
procedure TurnRight(da: real);
/// Возвращает случайный цвет
function RandomColor: Color;
/// Возвращает цвет по красной, зеленой и синей составляющей (в диапазоне 0..255)
function RGB(r,g,b: byte): Color;
/// Устанавливает скорость черепашки (от 1 до 10)
procedure SetSpeed(sp: integer);
/// Прячет Черепаху
procedure Hide;
/// Показывает Черепаху
procedure Show;
/// Опускает перо Черепахи
procedure Down;
/// Поднимает перо Черепахи
procedure Up;
/// Устанавливает ширину линии
procedure SetWidth(w: real);
/// Устанавливает цвет линии
procedure SetColor(c: GColor);
/// Перемещает Черепаху в точку (x,y)
procedure MoveTo(x,y: real);
/// Сохраняет изображение, нарисованное Черепахой, в файл fname (например, 'a.png')
procedure Save(fname: string);
type Colors = GraphWPF.Colors;
{type turtle = static class
/// Передвигает Черепаху вперёд на расстояние r
static procedure Forw(r: real) := TurtleWPF.Forw(r);
/// Поворачивает Черепаху на угол da по часовой стрелке
static procedure Turn(da: real) := TurtleWPF.Turn(da);
/// Возвращает случайный цвет
static function RandomColor: Color := TurtleWPF.RandomColor;
/// Возвращает цвет по красной, зеленой и синей составляющей (в диапазоне 0..255)
static function RGB(r,g,b: byte): Color := TurtleWPF.RGB(r,g,b);
/// Устанавливает скорость черепашки (от 1 до 10)
static procedure SetSpeed(sp: integer) := TurtleWPF.SetSpeed(sp);
/// Прячет Черепаху
static procedure Hide := TurtleWPF.Hide;
/// Показывает Черепаху
static procedure Show := TurtleWPF.Show;
/// Опускает перо Черепахи
static procedure Down := TurtleWPF.Down;
/// Поднимает перо Черепахи
static procedure Up := TurtleWPF.Up;
/// Устанавливает ширину линии
static procedure SetWidth(w: real) := TurtleWPF.SetWidth(w);
/// Устанавливает цвет линии
static procedure SetColor(c: GColor) := TurtleWPF.SetColor(c);
/// Перемещает Черепаху в точку (x,y)
static procedure MoveTo(x,y: real) := TurtleWPF.MoveTo(x,y);
/// Сохраняет изображение, нарисованное Черепахой, в файл fname (например, 'a.png')
static procedure Save(fname: string) := TurtleWPF.Save(fname);
end;}
implementation
{$resource 'turtle.png'}
uses GraphWPF,WPFObjects,GraphWPFBase;
uses WPFObjects,GraphWPFBase;
uses System.Windows.Media.Animation;
uses System.Windows.Media;
uses System.Windows.Media.Imaging;
@ -33,8 +118,8 @@ type
var v := CreateVisual;
var p := Center;
var (x,y) := (transl.X,transl.Y);
var ax := new DoubleAnimation(a + transl.X, System.TimeSpan.FromSeconds(sec));
var ay := new DoubleAnimation(b + transl.Y, System.TimeSpan.FromSeconds(sec));
var ax := new DoubleAnimation(a + x, System.TimeSpan.FromSeconds(sec));
var ay := new DoubleAnimation(b + y, System.TimeSpan.FromSeconds(sec));
ax.FillBehavior := FillBehavior.Stop;
ay.FillBehavior := FillBehavior.Stop;
var transl1 := transl;
@ -56,9 +141,6 @@ type
begin
Invoke(AnimMoveByPE,a,b,sec);
Sleep(Round(sec*1000 + 50)); // 50 мс - За это время анимация должна закончиться
TurtleX += a;
TurtleY += b;
GraphWPF.MoveTo(TurtleX,TurtleY);
end;
procedure AnimRotateE(a,sec: real);
begin
@ -66,7 +148,6 @@ type
Sleep(Round(sec*1000 + 50));
end;
end;
Colors = GraphWPF.Colors;
var t: TurtleHelper;
@ -74,14 +155,21 @@ var
a: real := 0;
dr := False;
speed := 10;
Window := GraphWPF.Window;
function RandomColor := GraphWPF.RandomColor;
function RGB(r,g,b: byte) := GraphWPF.RGB(r, g, b);
var sl := 30;
procedure SetSpeed(sp: integer);
begin
speed := sp;
speed := sp.Clamp(1,10);
if sp > 10 then
sl := 0
else sl := 30;
end;
var sl := 30;
procedure Hide;
begin
t.Visible := False;
@ -113,32 +201,43 @@ begin
end;
end;
procedure TurnLeft(da: real) := Turn(da);
procedure TurnRight(da: real) := Turn(-da);
/// Продвигает Черепаху вперёд на расстояние r
procedure Forw(r: real);
begin
var v := r * Vect(Cos(DegToRad(a)),Sin(DegToRad(a)));
var (a,b) := (v.X,v.Y);
TurtleX += a;
TurtleY += b;
if (speed = 10) or (r < 20) then
begin
TurtleX += v.X;
TurtleY += v.Y;
if dr then
LineTo(TurtleX,TurtleY)
else MoveTo(TurtleX,TurtleY);
t.MoveBy(v.X,v.Y);
GraphWPF.LineTo(TurtleX,TurtleY)
else GraphWPF.MoveTo(TurtleX,TurtleY);
t.MoveBy(a,b);
Sleep(sl);
end
else
begin
if dr then
t.AnimMoveByE(v.X,v.Y,r/(50*speed)) // 450 в секунду при скорости 9
begin
t.AnimMoveByE(a,b,r/(50*speed)); // 450 в секунду при скорости 9
GraphWPF.MoveTo(TurtleX,TurtleY);
end
else
begin
t.AnimMoveBy(v.X,v.Y,r/(50*speed));
t.AnimMoveBy(a,b,r/(50*speed));
Sleep(Round(r/(50*speed)*1000)+50);
GraphWPF.MoveTo(TurtleX,TurtleY);
end;
end;
end;
procedure Back(r: real) := Forw(-r);
/// Опускает хвост Черепахи
procedure Down := dr := True;
@ -159,6 +258,9 @@ begin
GraphWPF.MoveTo(x,y);
t.Center := Pnt(x,y);
end;
procedure Save(fname: string) := Window.Save(fname);
begin
Window.Title := 'Исполнитель Черепаха WPF';

View file

@ -338,8 +338,18 @@ type
private
procedure AnimMoveByP(a,b,sec: real);
begin
var ax := new DoubleAnimation(a + transl.X, System.TimeSpan.FromSeconds(sec));
var ay := new DoubleAnimation(b + transl.Y, System.TimeSpan.FromSeconds(sec));
var (x,y) := (transl.X,transl.Y);
var ax := new DoubleAnimation(a + x, System.TimeSpan.FromSeconds(sec));
var ay := new DoubleAnimation(b + y, System.TimeSpan.FromSeconds(sec));
ax.FillBehavior := FillBehavior.Stop;
ay.FillBehavior := FillBehavior.Stop;
var transl1 := transl;
ax.Completed += (o,e) -> begin
transl1.X := x + a; // transl - ошибка с лямбдами!
end;
ay.Completed += (o,e) -> begin
transl1.Y := y + b;
end;
transl.BeginAnimation(TranslateTransform.XProperty, ax, HandoffBehavior.Compose);
transl.BeginAnimation(TranslateTransform.YProperty, ay, HandoffBehavior.Compose);
end;
@ -348,6 +358,15 @@ type
begin
var ax := new DoubleAnimation(x, System.TimeSpan.FromSeconds(sec));
var ay := new DoubleAnimation(y, System.TimeSpan.FromSeconds(sec));
ax.FillBehavior := FillBehavior.Stop;
ay.FillBehavior := FillBehavior.Stop;
var transl1 := transl;
ax.Completed += (o,e) -> begin
transl1.X := x;
end;
ay.Completed += (o,e) -> begin
transl1.Y := y;
end;
transl.BeginAnimation(TranslateTransform.XProperty, ax, HandoffBehavior.Compose);
transl.BeginAnimation(TranslateTransform.YProperty, ay, HandoffBehavior.Compose);
end;
@ -361,6 +380,10 @@ type
procedure AnimRotateP(a,sec: real);
begin
var an := new DoubleAnimation(a + rot.Angle, System.TimeSpan.FromSeconds(sec));
an.FillBehavior := FillBehavior.Stop;
an.Completed += (o,e) -> begin
rot.Angle := a + rot.Angle;
end;
rot.BeginAnimation(RotateTransform.AngleProperty, an, HandoffBehavior.Compose);
end;
procedure AnimScaleP(a,sec: real);
@ -368,6 +391,11 @@ type
var an := new DoubleAnimation(a, System.TimeSpan.FromSeconds(sec));
sca.CenterX := Width / 2;
sca.CenterY := Height / 2;
an.FillBehavior := FillBehavior.Stop;
an.Completed += (o,e) -> begin
sca.ScaleX := a;
sca.ScaleY := a;
end;
sca.BeginAnimation(ScaleTransform.ScaleXProperty, an, HandoffBehavior.Compose);
sca.BeginAnimation(ScaleTransform.ScaleYProperty, an, HandoffBehavior.Compose);
end;