Ошибка при переносе из 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"); } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д