Ошибка при переносе из pascal в c#
Формулировка задачи:
Здравствуйте,просматривая стандартные програмки на паскаль обнаружил интересную прогр. о моделировании поведения рыб(),я решил портировать эту програмку на c# с помощью библиотеки smallbasic. Код я переписал но программа не работает(.Под скажите в чем проблема пж.
Код на PascalAbc.Net
Листинг программы
- uses GraphABC;
- const types = 3; //число типов рыб минус 1
- rmax = 4; //радиус всех рыб
- CanEat = rmax; //максимальное расстояние при поедании
- eps = 0.00001; //необходимо при операциях с данными real
- epsustupi = 0.1; //насколько значима иерархия среди хищников
- strahkraj = 3; //во сколько раз жертвы боятся края меньше, чем хищников
- ustupi = CanEat*10; //насколько значима иерархия среди хищников
- BkColor = clBlack; //Фон
- Height = 600; //Высота графического окна
- Width = 780; //Ширина графического окна
- xmin = 10; //
- ymin = 10; //Минимальные и максимальные значения координат,
- xmax = Width - 100; //которые могут принимать рыбы
- ymax = Height - 140; //
- Type
- fishtype = class //Описание одной стаи
- c : color;
- public
- CanRazm, MaxKol, Kol, MaxLife, MinFood: integer;
- //цвет, размножение, макс. кол-во, текущее кол-во, макс. жизнь,
- //сколько хищнику нужно есть для размножения
- Speed, See: real; //Нормальная скорость и зрение в пикселях
- constructor create(ac:color; aCanRazm, aMaxKol, aMaxLife, aMinFood:integer; aSpeed, aSee: real);
- begin
- c:= ac; CanRazm:= aCanRazm; MaxKol:= aMaxKol; Kol:= 1;
- MaxLife:= aMaxLife; MinFood:= aMinFood; Speed:= aSpeed; See:= aSee
- end;
- procedure ShowKol(y: integer); //отобразить текущее кол-во
- var s: string;
- begin
- SetFontColor(c);
- TextOut(xmax + 20, y, ' ');
- s := IntToStr(kol);
- TextOut(xmax + 20, y, s);
- end;
- end;
- var opisanie: array[0..types] of fishtype; //данные для всех стай
- Type
- fish = class
- x, y, r, dx0, dy0: real; //текущие координаты, радиус и предыдущий шаг
- tip, life, razm, status, food: integer;
- //razm - время с момента последнего размножения,
- //status - состояние - спокойное или возбуждённое
- next, prev: fish; //двусвязный циклический список
- constructor Create(ax, ay, ar: real; atip: integer; aprev, anext: fish);
- begin
- x:= ax; y:= ay; r:= ar; tip:= atip; prev:= aprev; next:= anext;
- life:= 0; razm:= 0; dx0:= random; dy0:= random; status:= 1; food:= 0;
- end;
- procedure show;
- begin
- SetPenColor(opisanie[tip].c);
- circle(round(x), round(y), round(r))
- end;
- procedure hide;
- begin
- SetPenColor(BkColor);
- circle(round(x), round(y), round(r))
- end;
- procedure Destroy;
- begin
- hide;
- opisanie[tip].kol:= opisanie[tip].kol - 1;
- opisanie[tip].ShowKol(tip*40 + 20);
- end;
- procedure moveto(dx, dy: real);
- begin
- hide;
- x:= x + dx; y:= y + dy;
- if x > xmax then x:= xmax;
- if x < xmin then x:= xmin;
- if y > ymax then y:= ymax;
- if y < ymin then y:= ymin;
- show
- end;
- procedure MakeDeti(var mama, StartAkula, KonAkula, StartKilka, KonKilka : fish);
- //произвести потомство
- var d: fish;
- begin
- razm:= 0;
- food:= 0;
- d:= fish.create(x, y, r, tip, mama, next);
- next.prev:= d;
- next:= d;
- if mama = KonAkula then KonAkula:= d;
- if mama = KonKilka then KonKilka:= d;
- opisanie[tip].kol:= opisanie[tip].kol + 1;
- opisanie[tip].ShowKol(tip*40 + 20);
- end;
- procedure step(var ribka, StartAkula, KonAkula, StartKilka, KonKilka : fish);
- //Здесь алгоритмы для рыб
- var
- dx, dy, d, dx2, dy2, dmin: real;
- t, trup, found: fish;
- FoundOhot: boolean;
- begin
- status:= 1; //Нормальное состояние
- dx:= 0; dy:= 0;
- if tip > 0 then
- begin //Начало алгоритма для жертв
- t:= StartAkula;
- if t<>nil then
- repeat //Ищем всех хищников в поле видимости
- d:= sqrt((x - t.x)*(x - t.x) + (y - t.y)*(y - t.y));
- if d < opisanie[tip].See then
- begin
- if d < eps then d:= eps;
- dx2:= (x - t.x)/(d*d);
- dy2:= (y - t.y)/(d*d);
- dx:= dx + dx2;
- dy:= dy + dy2;
- status:= 2; //Возбуждённое состояние
- end;
- t:= t.next
- until t = KonAkula.next;
- //И обратим внимание на края:
- if x - xmin < opisanie[tip].See then dx:= dx + 1/((x - xmin + eps)*strahkraj);
- if xmax - x < opisanie[tip].See then dx:= dx + 1/((x - xmax - eps)*strahkraj);
- if y - ymin < opisanie[tip].See then dy:= dy + 1/((y - ymin + eps)*strahkraj);
- if ymax - y < opisanie[tip].See then dy:= dy + 1/((y - ymax - eps)*strahkraj);
- d:= sqrt(dx*dx + dy*dy);
- if d < eps then
- begin
- dx:= 2*status*random()*opisanie[tip].Speed - status*opisanie[tip].Speed;
- dy:= 2*status*random()*opisanie[tip].Speed - status*opisanie[tip].Speed
- end
- else
- begin
- dx:= status*opisanie[tip].Speed*dx/d;
- dy:= status*opisanie[tip].Speed*dy/d
- end
- end
- else {tip = 0}
- begin //Начало алгоритма для хищников
- dmin:= 11000;
- t:= StartAkula;
- while t<>ribka do //Проверяем всех выше по иерархии
- begin
- d:= sqrt((x - t.x)*(x - t.x) + (y - t.y)*(y - t.y));
- if (d < dmin) and (abs(dx0 - t.dx0) < epsustupi) and
- (abs(dy0 - t.dy0) < epsustupi) then dmin:= d;
- t:= t.next
- end;
- FoundOhot:= dmin < ustupi;
- dmin:= 11000;
- found:= nil;
- t:= StartKilka;
- if (t<>nil) and (life > 100) and not FoundOhot then
- repeat
- d:= sqrt((x - t.x)*(x - t.x) + (y - t.y)*(y - t.y));
- if d < dmin then
- begin
- dmin:= d;
- found:= t //found - ближайшая жертва
- end;
- t:= t.next
- until t = KonKilka.next;
- if (found <> nil) and (dmin < opisanie[tip].See) then
- begin
- status:= 2; //Возбуждённое состояние
- dx:= found.x - x;
- dy:= found.y - y;
- if dmin < CanEat + status*opisanie[tip].Speed then
- begin //Поедание
- found.next.prev:= found.prev;
- found.prev.next:= found.next;
- if (found = StartKilka) and (found = KonKilka) then
- begin
- //StartKilka:= nil;
- //KonKilka:= nil
- end;
- if found = StartKilka then
- StartKilka:= StartKilka.next;
- if found = KonKilka then
- KonKilka:= KonKilka.prev;
- found.destroy;
- found := nil;
- food:= food + 1
- end
- end
- else
- if (x <= xmin) or (x >= xmax) or (y <= ymin) or (y >= ymax) then
- begin
- dx:= 2*status*random()*opisanie[tip].Speed - status*opisanie[tip].Speed;
- dy:= 2*status*random()*opisanie[tip].Speed - status*opisanie[tip].Speed
- end
- else
- begin
- dx:= dx0; dy:= dy0 //Повтор предыдущего шага - патрулирование
- end;
- d:= sqrt(dx*dx + dy*dy);
- if d > eps then
- begin
- dx:= status*opisanie[tip].Speed*dx/d;
- dy:= status*opisanie[tip].Speed*dy/d;
- end
- end;
- //Начало алгоритма для всех рыб
- moveto(dx, dy);
- dx0:= dx; dy0:= dy;
- life:= life + 1; razm:= razm + 1;
- if opisanie[tip].Kol >= opisanie[tip].MaxKol then Razm:= 0;
- if (razm > opisanie[tip].CanRazm) and (food >= opisanie[tip].minfood) then
- MakeDeti(ribka, StartAkula, KonAkula, StartKilka, KonKilka);
- if life > opisanie[tip].MaxLife then //Смерть от старости
- begin
- trup:= ribka; ribka:= ribka.prev;
- trup.next.prev:= trup.prev;
- trup.prev.next:= trup.next;
- if trup = StartKilka then
- StartKilka:= StartKilka.next;
- if trup = KonKilka then
- KonKilka:= KonKilka.prev;
- if trup = StartAkula then
- StartAkula:= StartAkula.next;
- if trup = KonAkula then
- KonAkula:= KonAkula.prev;
- if trup = trup.next then ribka:= nil;
- if trup <> nil then
- trup.destroy;
- trup := nil;
- end
- end;
- end;
- function getAllCount:integer;
- var i,c:integer;
- begin
- c:=0;
- for i:=0 to types do
- c:=c+opisanie[i].Kol;
- getAllCount:=c;
- end;
- var i: integer;
- p, q, StartAkula, StartKilka, KonAkula, KonKilka, tek: fish;
- begin
- SetSmoothing(False);
- SetWindowSize(Width, Height);
- SetWindowLeft(200);
- SetWindowTop(50);
- SetWindowCaption('Битва за жизнь');
- SetFontSize(7);
- SetFontName('Arial');
- SetBrushColor(BkColor);
- FillRectangle(0, 0, Width, Height);
- SetFontColor(clWhite);
- TextOut(10, ymax + 20, 'Автор программы - Иванов С.О. e-mail: [email]removed@mail.ru[/email]');
- TextOut(10, ymax + 20+1*18, 'Программа моделирует поведение нескольких стай рыб. Справа - количества рыб в текущий');
- TextOut(10, ymax + 20+2*18, 'момент времени. Изменяя параметры в коде программы, можно влиять на ход битвы.');
- TextOut(10, ymax + 20+3*18, 'По умолчанию: красные - хищники, поедают любых рыб из других стай, не плодятся,');
- TextOut(10, ymax + 20+4*18, 'пока не поели; синие - жертвы, самые медленные, но быстрее всех плодятся; зелёные - жертвы,');
- TextOut(10, ymax + 20+5*18, 'быстрее синих, но плодятся медленнее; желтые - самые быстрые среди жертв, но желтых мало.');
- SetFontSize(12);
- StartAkula:= nil;
- StartKilka:= nil;
- KonAkula:= nil;
- KonKilka:= nil;
- //c - цвет.
- //CanRazm - минимальное количество ходов отдельно взятой рыбы между двумя
- // её последовательными размножениями.
- //MaxKol - максимально допустимое количество рыб данного вида.
- //Kol - количество рыб данного вида в текущий момент времени.
- //MaxLife - максимальная продолжительность жизни.
- // После того, как рыба сделает больше шагов, чем это число, она умирает.
- //MinFood - минимальное количество съеденных жертв, необходимое для размножения
- // (только для хищников; для жертв это количество принято за -1).
- //Speed - нормальная скорость. Максимальная скорость рыбы в 2 раза больше этого числа.
- //See - радиус обзора - как далеко видит рыба.
- //c, CanRazm, MaxKol, MaxLife, MinFood, Speed, See
- opisanie[3]:= fishtype.create(clYellow, 300, 15, 1500, -1, 0.99, 50);
- opisanie[2]:= fishtype.create(clGreen, 150, 50, 1500, -1, 0.9, 50);
- opisanie[1]:= fishtype.create(clBlue, 30, 50, 500, -1, 0.7, 35);
- opisanie[0]:= fishtype.create(clRed, 1000, 40, 5000, 1, 1, 500);
- SetPenColor(clWhite);
- rectangle(round(xmin - rmax - 1), round(ymin - rmax - 1),
- round(xmax + rmax + 1), round(ymax + rmax + 1));
- //Теперь нужно построить первоначальный список
- q:= fish.create(xmin + 10, ymax - 10, rmax, 0, nil, nil);
- p:= fish.create(xmin + 10, ymin + 10, rmax, 1, q, q);
- q.next:= p; q.prev:= p;
- StartAkula:= q; KonAkula:= q;
- StartKilka:= p; KonKilka:= p;
- p:= fish.create(xmax - 10, ymin + 10, rmax, 2, KonKilka, StartAkula);
- StartAkula.prev:= p;
- KonKilka.next:= p; KonKilka:= p;
- p:= fish.create(xmax - 10, ymax - 10, rmax, 3, KonKilka, StartAkula);
- StartAkula.prev:= p;
- KonKilka.next:= p; KonKilka:= p;
- for i:= 0 to types do opisanie[i].ShowKol(i*40 + 20);
- //И все ходят по очереди, пока хоть кто-то жив.
- tek:= StartKilka;
- //i:=0;c:=getallcount;LockDrawing;
- repeat
- tek:= tek.next;
- tek.step(tek, StartAkula, KonAkula, StartKilka, KonKilka);
- {i:=i+1;
- if i>=c then begin
- i:=0;c:=getallcount;
- Redraw;
- end;}
- until (tek = nil);
- end.
Решение задачи: «Ошибка при переносе из pascal в c#»
textual
Листинг программы
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using sb=Microsoft.SmallBasic.Library;
- namespace lost_fish
- {
- public class Maini
- {
- static Random rand = new Random();
- const int types=4;
- const int strahkraj = 3;
- const int rmax=4;
- const int CanEat = rmax;
- const double eps = 0.00001;
- const double epsustupi = 0.1;
- const int ustupi = CanEat*10;
- const int Height = 600;
- const int Width = 780;
- const int xmin = 10;
- const int ymin = 10;
- const int xmax = Width - 100;
- const int ymax = Height - 140;
- public class fishtype
- {
- public string s;
- public int canrazm, maxkol, kol, maxlife, minfood;
- public double speed, see;
- public fishtype(string s, int canrazm, int maxkol, int maxlife, int minfood, double speed, double see)
- {
- this.s = s;
- this.canrazm = canrazm;
- this.maxkol = maxkol;
- this.maxlife = maxlife;
- this.minfood = minfood;
- this.speed = speed;
- this.see = see;
- }
- public void showkol(int y)
- {
- string b;
- sb.GraphicsWindow.PenColor = "White";
- sb.GraphicsWindow.DrawText(xmax + 20, y, " ");
- b = kol.ToString();
- sb.GraphicsWindow.DrawText(xmax + 20, y, b);
- }
- }
- static fishtype[] opisanie = new fishtype[types];
- public class fish
- {
- public double x, y, r, dx0, dy0;
- public int tip, life, razm, status, food;
- public fish next;
- public fish prev;
- public sb.Primitive kr = new sb.Primitive();
- public fish()
- {
- }
- public fish(double x,double y,int r,int tip,fish prev,fish next)
- {
- this.x=x;
- this.y = y;
- this.r = r;
- this.tip = tip;
- this.prev = prev;
- this.next = next;
- this.life = 0;
- this.razm = 0;
- this.dx0 =rand.Next(1,Width - 100);
- this.dy0 = rand.Next(1,Height - 100);
- status = 1;
- food = 0;
- show();
- }
- public void show()
- {
- sb.GraphicsWindow.PenColor = "White";
- kr = sb.Shapes.AddEllipse(r*2, r*2);
- sb.Shapes.Move(kr, Math.Round(x), Math.Round(y));
- }
- public void Hide()
- {
- // sb.GraphicsWindow.PenColor = sb.GraphicsWindow.BackgroundColor;
- sb.Shapes.Remove(kr);
- }
- public void destroy()
- {//
- Hide();
- opisanie[tip].kol = opisanie[tip].kol - 1;
- opisanie[tip].showkol(tip * 40 + 40);
- }
- public void moveto(int dx,int dy)
- {
- x = x + dx;
- y=y+dy;
- if (x>xmax) x=xmax;
- if (y < xmin) x = xmin;
- if (y > ymax) y = ymax;
- if (y < ymin) y = ymin;
- sb.Shapes.Move(kr, x, y);
- }
- public void Makedeti(fish mama, fish startakula, fish konakula, fish startkilka, fish konkilka)
- {
- fish d = new fish();
- d.x = x;
- d.y = y;
- d.r = r;
- d.prev = mama;
- d.next = next;
- razm = 0;
- food = 0;
- next.prev = d;
- next = d;
- if (mama == konakula) konakula = d;
- if (mama == konkilka) konkilka = d;
- opisanie[tip].kol = opisanie[tip].kol + 1;
- opisanie[tip].showkol(tip * 40 + 20);
- }
- private double rain()
- {
- return (double)rand.Next(0, 10000000) / 10000000;
- }
- public void step(fish ribka, fish startakula, fish konakula,fish startkilka, fish konkilka)
- {
- double dx, dy, d, dx2, dy2, dmin;
- fish t, trup, found;
- bool foundohot;
- status = 1;
- dx = 0;
- dy = 0;
- if (tip > 0)
- {
- t = startakula;
- if (t != null)
- {
- do
- {
- d = Math.Sqrt((x - t.x) * (x - t.x) + (y - t.y) * (y - t.y));
- if (d < opisanie[tip].see)
- {
- dx2 = (x - t.x) / (d * d);
- dy2 = (y - t.y) / (d * d);
- dx = dx + dx2;
- dy = dy + dy2;
- status = 2;
- }
- t = t.next;
- } while (t != konakula.next);
- if ((x - xmin) < opisanie[tip].see) dx = (dx + 1) / ((x - xmin + eps) * strahkraj);
- if ((xmax - x) < opisanie[tip].see) dx = (dx + 1) / ((x - xmin - eps) * strahkraj);
- if ((y - ymin) < opisanie[tip].see) dy = (dy + 1) / ((y - ymin + eps) * strahkraj);
- if ((ymax - y) < opisanie[tip].see) dy = (dy + 1) / ((y - ymin - eps) * strahkraj);
- d = Math.Sqrt(dx * dx + dy * dy);
- if (d < eps)
- {
- dx = 2 * status * rain() * opisanie[tip].speed - status * opisanie[tip].speed;
- dy = 2 * status * rain()*opisanie[tip].speed - status*opisanie[tip].speed;
- }
- else
- {
- dx = status * opisanie[tip].speed * dx / d;
- dy = status * opisanie[tip].speed * dy / d;
- }
- }
- else
- {
- dmin = 11000;
- t = startakula;
- while(t!=ribka)
- {
- d = Math.Sqrt((x - t.x) * (x - t.x) + (y - t.y) * (y - t.y));
- if ((d < dmin) && (Math.Abs(dx0 - t.dx0) < epsustupi) && (Math.Abs(dy0 - t.dy0) < epsustupi)) dmin = d;
- t = t.next;
- }
- foundohot = dmin < ustupi;
- dmin = 11000;
- found = null;
- t = startkilka;
- if ((t != null) && (life > 100) && !foundohot)
- {
- do
- {
- d = Math.Sqrt((x - t.x) * (x - t.x) + (y - t.y) * (y - t.y));
- } while (t != konkilka.next);
- if ((found!=null)&&(dmin<opisanie[tip].see))
- {
- status=2;
- dx=found.x-x;
- dy=found.y-y;
- if((dmin<(CanEat+status*opisanie[tip].speed)))
- {
- found.next.prev=found.prev;
- found.prev.next=found.next;
- if ((found==startkilka)&&(found==konkilka))
- {
- // startkilka=null;
- //konkilka=null;
- }
- if (found==startkilka)startkilka=startkilka.next;
- if (found==konkilka)konkilka=konkilka.prev;
- found.destroy();
- found=null;
- food=food+1;
- }
- }
- else if ((x<=xmin)||(x>=xmax)||(y<=ymin)||(y>=ymin))
- {
- dx= 2*status*rain()*opisanie[tip].speed - status*opisanie[tip].speed;
- dy= 2*status*rain()*opisanie[tip].speed - status*opisanie[tip].speed;
- }
- else
- {
- dx=dx0;
- dy=dy0;
- }
- d=Math.Sqrt(dx*dx+dy*dy);
- if (d>eps)
- {
- dx=status*opisanie[tip].speed*dx/d;
- dy= status*opisanie[tip].speed*dy/d;
- }
- }
- moveto(Convert.ToInt32(dx),Convert.ToInt32(dy));
- dx0=dx;
- dy0=dy;
- life=life+1;
- razm=razm+1;
- if (opisanie[tip].kol>=opisanie[tip].maxkol)razm=0;
- if (razm>opisanie[tip].canrazm&&food>=opisanie[tip].minfood)
- Makedeti(ribka,startakula,konakula,startkilka,konkilka);
- if (life>opisanie[tip].maxlife)
- {
- trup=ribka;
- ribka=ribka.prev;
- trup.next.prev=trup.prev;
- trup.prev.next=trup.next;
- if (trup ==startkilka) startkilka = startkilka.next;
- if (trup==konkilka)konkilka=konkilka.prev;
- if (trup==startakula)startakula=startakula.next;
- if (trup==konakula)konakula=konakula.prev;
- if (trup==trup.next)ribka=null;
- if (trup!=null)trup.destroy();
- trup=null;
- }
- }
- }
- }
- }
- public int getallcount()
- {
- int i,c=0;
- for (i=0;i<=types;i++)
- {
- c+=opisanie[i].kol;
- }
- return c;
- }
- static void Main()
- {
- sb.GraphicsWindow.BackgroundColor = "Black";
- fish p,q,startakula,startkilka,konakula,konkilka,tek;
- sb.GraphicsWindow.Height=Height;
- sb.GraphicsWindow.Width=Width;
- sb.GraphicsWindow.Left=200;
- sb.GraphicsWindow.Top=50;
- sb.GraphicsWindow.FontSize=7;
- sb.GraphicsWindow.FontName="Arial";
- sb.GraphicsWindow.BrushColor=sb.GraphicsWindow.BackgroundColor;
- sb.GraphicsWindow.FillRectangle(0,0,Width,Height);
- sb.GraphicsWindow.FontSize=12;
- startakula=null;
- startkilka=null;
- konakula=null;;
- konkilka=null;
- opisanie[3]= new fishtype("Yellow", 300, 15, 1500, -1, 0.99, 50);
- opisanie[2]= new fishtype("Green", 150, 50, 1500, -1, 0.9, 50);
- opisanie[1]= new fishtype("Blue", 30, 50, 500, -1, 0.7, 35);
- opisanie[0]= new fishtype("Red", 1000, 40, 5000, 1, 1, 500);
- sb.GraphicsWindow.PenColor="White";
- sb.GraphicsWindow.DrawRectangle(Math.Round((decimal)xmin - rmax - 1),Math.Round((decimal)ymin - rmax - 1),Math.Round((decimal)xmax+rmax+1),Math.Round((decimal)ymax+rmax+1));
- q=new fish(xmin+10,ymax-10,rmax,0,null,null);
- p=new fish(xmin+10,ymin+10,rmax,1,q,q);
- q.next = p; q.prev = p;
- startakula = q;
- startkilka = p;
- konakula = q;
- konkilka = p;
- p = new fish(xmax - 10, ymin + 10, rmax, 2, konkilka, startakula);
- startakula.prev = p;
- konakula.next = p;
- konkilka = p;
- p = new fish(xmax - 10, ymax - 10, rmax,3, konkilka, startakula);
- startakula.prev = p;
- konkilka.next = p;
- konkilka = p;
- int i;
- for ( i = 0; i < types;i++)
- opisanie[i].showkol(i * 40 + 20); tek = startkilka;
- int j = 0;
- do
- {
- j++;
- tek = tek.next;
- tek.step(tek, startakula, konakula, startkilka, konkilka);
- } while (tek != null);
- // sb.GraphicsWindow.PenColor = "Red";
- //sb.GraphicsWindow.DrawText(100, 100, "GAme over");
- }
- }
- }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д