Skip to content

Commit

Permalink
Part of Issue #20 - Merge in CWOPS CWT Contest changes.
Browse files Browse the repository at this point in the history
Merge commit 'd29e4d6' into 20-fd-prototype
  • Loading branch information
w7sst committed Sep 19, 2022
2 parents 68cd1d4 + d29e4d6 commit 2e9ac67
Show file tree
Hide file tree
Showing 21 changed files with 7,020 additions and 93 deletions.
5,427 changes: 5,427 additions & 0 deletions CWOPS.LIST

Large diffs are not rendered by default.

140 changes: 140 additions & 0 deletions CWOPS.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
unit CWOPS;

interface

uses
SysUtils, Classes, Contnrs, PerlRegEx, pcre;

type
TCWOPSRec= class
public
call: string;
Name: string;
Number: string;
end;

TCWOPS= class
private
CWOPSList: TList;
procedure LoadCWOPS;
procedure Delimit(var AStringList: TStringList; const AText: string);

public
constructor Create;
function getcwopsid(): integer;
function getcwopscall(id:integer): string;
function getcwopsname(id:integer): string;
function getcwopsnum(id:integer): integer;
function IsNum(Num: String): Boolean;
end;

var
CWOPSCWT: TCWOPS;


implementation

uses
log;

procedure TCWOPS.LoadCWOPS;
var
slst, tl: TStringList;
i: integer;
CWO: TCWOPSRec;
begin
slst:= TStringList.Create;
tl:= TStringList.Create;
try
CWOPSList:= TList.Create;
slst.LoadFromFile(ParamStr(1) + 'CWOPS.LIST');
slst.Sort;

for i:= 0 to slst.Count-1 do begin
self.Delimit(tl, slst.Strings[i]);
if (tl.Count = 4) then begin
CWO:= TCWOPSRec.Create;
CWO.Call:= UpperCase(tl.Strings[0]);
CWO.Name:= UpperCase(tl.Strings[1]);
CWO.Number:= tl.Strings[2];
if CWO.Call='' then continue;
if CWO.Name='' then continue;
if CWO.Number='' then continue;
if IsNum(CWO.Number) = False then continue;
if length(CWO.Name) > 10 then continue;
if length(CWO.Name) > 12 then continue;

CWOPSList.Add(CWO);


end;
end;

finally
slst.Free;
tl.Free;
end;


end;

constructor TCWOPS.Create;
begin
inherited Create;
LoadCWOPS;
end;

function TCWOPS.getcwopsid(): integer;
begin
result := random(CWOPSList.Count);
end;


function TCWOPS.getcwopscall(id:integer): string;

begin
result := TCWOPSRec(CWOPSList.Items[id]).Call;
end;

function TCWOPS.getcwopsname(id:integer): string;

begin
result := TCWOPSRec(CWOPSList.Items[id]).Name;
end;

function TCWOPS.getcwopsnum(id:integer): integer;

begin
result := strtoint(TCWOPSRec(CWOPSList.Items[id]).Number);
end;

function TCWOPS.IsNum(Num: String): Boolean;
var
X : Integer;
begin
Result := Length(Num) > 0;
for X := 1 to Length(Num) do begin
if Pos(copy(Num,X,1),'0123456789') = 0 then begin
Result := False;
Exit;
end;
end;
end;




procedure TCWOPS.Delimit(var AStringList: TStringList; const AText: string);
const
DelimitChar: char= ',';
begin
AStringList.Clear;
AStringList.Delimiter := DelimitChar;
AStringList.StrictDelimiter := True;
AStringList.DelimitedText := AText;
end;

end.



21 changes: 19 additions & 2 deletions Contest.pas
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ constructor TContest.Create;
Agc.AttackSamples := 155; //AGC attack 5 ms
Agc.HoldSamples := 155;
Agc.AgcEnabled := true;
NoActivityCnt :=0;

Init;
end;
Expand Down Expand Up @@ -282,13 +283,29 @@ function TContest.Minute: Single;
procedure TContest.OnMeFinishedSending;
var
i: integer;
z: integer;
begin
//the stations heard my CQ and want to call
if (not (RunMode in [rmSingle, RmHst])) then
if (msgCQ in Me.Msg) or
((QsoList <> nil) and (msgTU in Me.Msg) and (msgMyCall in Me.Msg))then
for i:=1 to RndPoisson(Activity / 2) do Stations.AddCaller;

begin
z := 0;
for i:=1 to RndPoisson(Activity / 2) do
begin
Stations.AddCaller;
z := 1;
end;
if z=0 then begin
// No maximo fica 3 cq sem contesters
inc(NoActivityCnt);
if ((NoActivityCnt > 2) or (NoStopActivity > 0) ) then begin
Stations.AddCaller;
NoActivityCnt := 0;
end;

end;
end;
//tell callers that I finished sending
for i:=Stations.Count-1 downto 0 do
Stations[i].ProcessEvent(evMeFinished);
Expand Down
33 changes: 31 additions & 2 deletions DxOper.pas
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ TDxOperator = class
function GetReplyTimeout: integer;
function GetWpm: integer;
function GetNR: integer;
function GetName: string;
procedure MsgReceived(AMsg: TStationMessages);
procedure SetState(AState: TOperatorState);
function GetReply: TStationMessage;
Expand Down Expand Up @@ -65,17 +66,45 @@ function TDxOperator.GetSendDelay: integer;
end;

function TDxOperator.GetWpm: integer;
const
useGaussLim: Boolean = True; { use gaussian distribution instead of random }
var
mean, limit: Single;
begin
if RunMode = rmHst
then Result := Ini.Wpm
else Result := Round(Ini.Wpm * 0.5 * (1 + Random));
else if (MaxRxWpm = -1) or (MinRxWpm = -1) { use original algorithm }
then Result := Round(Ini.Wpm * 0.5 * (1 + Random))
else if useGaussLim then { use Gaussian w/ limit, [Wpm-Min, Wpm+Max] }
begin // assume Wpm=30, MinRxWpm=6, MaxRxWpm=2
mean := Ini.Wpm + (-MinRxWpm + MaxRxWpm)/2; // 30+(-6+2)/2 = 30-4/2 = 28
limit := (MinRxWpm + MaxRxWpm)/2; // (6+2)/2 = 4 wpm
Result := Round(RndGaussLim(mean, limit)); // [28-4, 28+4] -> wpm [24,32]
end
else { use Random value, [Wpm-Min,Wpm+Max] }
Result := Round(Ini.Wpm - MinRxWpm + (MinRxWpm + MaxRxWpm) * Random);
end;

function TDxOperator.GetNR: integer;
Var
n1: integer;
begin
if NRDigits = 1 then
Result := 1 + Round(Random * Tst.Minute * Skills)
else begin
n1 := trunc(power(10,NRDigits));
n1 := n1-1;
Result := Random(n1);
end;
end;


function TDxOperator.GetName: string;
begin
Result := 1 + Round(Random * Tst.Minute * Skills);
Result := 'ALEX';
end;


function TDxOperator.GetReplyTimeout: integer;
begin
if RunMode = rmHst then
Expand Down
26 changes: 23 additions & 3 deletions DxStn.pas
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
interface

uses
SysUtils, Classes, Station, RndFunc, Ini, CallLst, Qsb, DxOper, Log, SndTypes;
SysUtils, Classes, Station, RndFunc, Dialogs, Ini, CWOPS, CallLst, Qsb, DxOper, Log, SndTypes;

type
TDxStation = class(TStation)
Expand All @@ -21,6 +21,8 @@ TDxStation = class(TStation)
procedure ProcessEvent(AEvent: TStationEvent); override;
procedure DataToLastQso;
function GetBlock: TSingleArray; override;
var
Operid: integer;
end;


Expand All @@ -37,7 +39,14 @@ constructor TDxStation.CreateStation;

HisCall := Ini.Call;
// Adding a contest: DxStation.CreateStation - load a random callsign
MyCall := PickCall; // Pick one Callsign from Calllist
case SimContest of
scCwt: begin
Operid := CWOPSCWT.getcwopsid();
MyCall := CWOPSCWT.getcwopscall(Operid);
end;
else
MyCall := PickCall; // Pick one Callsign from Calllist
end;

Oper := TDxOperator.Create;
Oper.Call := MyCall;
Expand All @@ -46,8 +55,17 @@ constructor TDxStation.CreateStation;
NrWithError := Ini.Lids and (Random < 0.1);

Wpm := Oper.GetWpm;

// Adding a contest: DxStation.CreateStation - get Exch1 (e.g. Name), Exch2 (e.g. NR), and optional UserText
NR := Oper.GetNR;
case SimContest of
scCwt: begin
OpName := CWOPSCWT.getcwopsname(Operid);
NR := CWOPSCWT.getcwopsnum(Operid);
end;
else
NR := Oper.GetNR;
end;
//showmessage(MyCall);

if Ini.Lids and (Random < 0.03) then
RST := 559 + 10 * Random(4)
Expand Down Expand Up @@ -149,11 +167,13 @@ procedure TDxStation.DataToLastQso;
TrueNR := Self.NR;
case ActiveContest.ExchType1 of
etRST: TrueExch1 := IntToStr(Self.NR);
etOpName: TrueExch1 := Self.OpName;
else
assert(false);
end;
case ActiveContest.ExchType2 of
etSerialNr: TrueExch2 := IntToStr(Self.NR);
etCwopsNumber: TrueExch2 := IntToStr(Self.NR);
else
assert(false);
end;
Expand Down
Loading

0 comments on commit 2e9ac67

Please sign in to comment.