我有一个简单的问题:
我在ADA中同时运行了一些任务。他们一起创建了一个模拟代表一个想象国家的选举。如果出现某种情况,我想重新启动整个模拟。所以我想中止每个任务,然后重新启动它们。如何在不重新创建任务的情况下执行此操作?我确信有一个更好的方式,但我似乎无法找到它。顺便说一句,任务是在一个数组中。在此先感谢!!
with Ada.Text_IO;
use Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
procedure Election is
type RandNum is new Integer range 1..100;
package RandInt is new Ada.Numerics.Discrete_Random(RandNum);
use RandInt;
task type Youngster;
task type DarkSide;
task type Guard;
NowVoting: Boolean := False;
YoungsterNum: Positive := 7;
DarkNum: Positive := 3;
G: Generator;
type PartyType is array (Positive range 1..3) of Natural;
task Place is
entry Vote(Num: in RandNum; Cheat: in Boolean);
end Place;
protected Collector is
procedure GoHome;
procedure GuardIn;
procedure GuardOut;
procedure Arrest;
function HowManyArrested return Natural;
function HowManyGuards return Natural;
function HowMany return Integer;
private
Home: Integer := 0;
Guards: Natural := 2;
Arrested: Natural := 0;
end Collector;
task body Place is
Party: PartyType := (0,0,0);
Guard1: Guard;
Guard2: Guard;
Votes: Natural := 0;
begin
Put_Line("-----------------------------------------------");
Put_Line(" A SZAVAZĂS KEZDETÉT VESZI");
Put_Line("-----------------------------------------------");
while Collector.HowMany /= YoungsterNum and Collector.HowManyArrested /= DarkNum loop
accept Vote(Num: in RandNum; Cheat: in Boolean) do
NowVoting := True;
if Num < 33 then
Party(1) := Party(1) + 1;
elsif Num > 33 and Num < 66 then
Party(2) := Party(2) + 1;
else
Party(3) := Party(3) + 1;
end if;
Votes := Votes + 1;
delay 2.0;
Put("Ifjonctanácsok Intergalaktikus Szövetsége: ");
Put_Line(Integer'Image(Party(1)));
Put("ĹfelsĂ©ge Leghűbb EllenzĂ©ke: ");
Put_Line(Integer'Image(Party(2)));
Put("Demokratikus Ellenzék: ");
Put_Line(Integer'Image(Party(3)));
Put("Ă–sszesĂtve: ");
Put_Line(Natural'Image(Votes));
Put_Line("-----------------------------------------------");
if Cheat then
Put_Line("!!! C S A L Ă S !!!");
end if;
NowVoting := False;
end;
end loop;
if (Votes-(YoungsterNum + DarkNum)) > ((YoungsterNum + DarkNum) / 20) then
Put_Line("A szavazást meg kell ismételni!");
end if;
end Place;
task body Youngster is
Num: RandNum;
Success: Boolean := False;
Time: Natural := 0;
begin
Reset(G);
Num := Random(G);
while Success = False loop
while Time /= 6 and Success = False loop
if NowVoting = False and (Collector.HowManyGuards = 2
or Collector.HowManyGuards = 0) then
Place.Vote(Num, False);
Success := True;
Collector.GoHome;
else
Time := Time + 1;
delay 1.0;
end if;
end loop;
if Success = False then
Num := Random(G);
Time := 0;
end if;
end loop;
end Youngster;
task body DarkSide is
Num: RandNum;
Success: Boolean := False;
Time: Natural := 0;
begin
delay 2.0;
Reset(G);
loop
Num := Random(G);
if Collector.HowManyGuards = 0 and Collector.HowManyArrested /= DarkNum then
Place.Vote(Num, True);
delay 2.0;
else
Collector.Arrest;
Put_Line("!!! L E A T A R T Ă“ Z T A T Ă S !!!");
exit;
end if;
end loop;
end DarkSide;
protected body Collector is
procedure GoHome is
begin
Home := Home + 1;
end GoHome;
procedure GuardOut is
begin
Guards := Guards - 1;
end GuardOut;
procedure GuardIn is
begin
Guards := Guards + 1;
end GuardIn;
procedure Arrest is
begin
Arrested := Arrested + 1;
end Arrest;
function HowManyArrested return Natural is
begin
return Arrested;
end HowManyArrested;
function HowManyGuards return Natural is
begin
return Guards;
end HowManyGuards;
function HowMany return Integer is
begin
return Home;
end HowMany;
end Collector;
task body Guard is
Num: RandNum;
begin
Reset(G);
while Collector.HowMany /= YoungsterNum and Collector.HowManyArrested /= DarkNum loop
Num := Random(G);
if Collector.HowManyGuards = 2 then
if Num <= 30 then
Collector.GuardOut;
Put_Line("(((Ĺr kiment szabályosan!)))");
delay 10.0;
Collector.GuardIn;
Put_Line("(((Ĺr visszatĂ©rt!)))");
delay 4.0;
end if;
else
if Num <= 25 then
Collector.GuardOut;
Put_Line("(((Ĺr kiment szabálytalanul!)))");
delay 10.0;
Collector.GuardIn;
Put_Line("(((Ĺr visszatĂ©rt!)))");
delay 4.0;
end if;
end if;
end loop;
end Guard;
Youngsters: array (1..YoungsterNum) of Youngster;
Dark: array(1..DarkNum) of DarkSide;
begin
null;
end Election;
put_lines是匈牙利语,没关系。所以我想做的是这是真的:
if (Votes-(YoungsterNum + DarkNum)) > ((YoungsterNum + DarkNum) / 20) then
然后我希望所有这些重新开始:
Youngsters: array (1..YoungsterNum) of Youngster;
Dark: array(1..DarkNum) of DarkSide;
task Place is
entry Vote(Num: in RandNum; Cheat: in Boolean);
end Place;
当然还有两名守卫,这是不言而喻的。我希望这很清楚。
答案 0 :(得分:2)
如果选举任务目前只是一项包含在任务中的选举模拟,那么多项选举可以并行进行:
-- Not compiled
task body Simulated_Elections is
begin
Initialize_Electoral_Information;
Determine_Candidates;
Run_Election;
Inaugurate;
end Simulated_Elections;
然后只需将功能放在带退出的循环中即可:
-- Still not compiled
task body Simulated_Elections is
begin
loop
select
accept The_Voice_Of_The_People;
or
accept Tyranny_And_Dictatorship;
exit;
or
terminate;
end select;
Initialize_Electoral_Information;
Determine_Candidates;
Run_Election;
Inaugurate;
end loop;
end Simulated_Elections;
答案 1 :(得分:2)
好吧,我发现我找到了一个解决这个问题的答案,也很优雅,可以分享。我不会在这里发布代码,只是要点:
我希望我已经清楚了。我认为这在其他语言中被称为循环屏障。