#!/usr/local/bin/blassic
'This Blassic program is for use with the SEVO evolver program.
'Outputs a file containing a symbolic representation of the soup and a
'sample warrior of each type, as determined by a hash of the first few
'characters of each line of each warrior (default ins.mod). If no bench set
'is specified then randomly selects the sample, otherwise selects the
'highest-scoring warrior for each type, followed by the top-scoring warrior.
'Finally outputs a list of warriors for each hash (disable if not needed).
usewin=0  'set to 1 if running under windows
n=2000:d=50:f$="soup.txt"
benchbase$="/usr/local/share/cw/" 'location of bench sets (use \ if win)
bench$="nanob2"
'the following 2 lines must match the warriors and benchmark...
pmars$="pmars -bkl 5 -d 5 -s 80 -p 80 -c 800 -P"
rounds=142 '-r parm or 142 if nano -P
chars$=".:?~@#$%^&*-=+OX" 'characters used for the soup display
hashwidth=6 'how much of each warrior line is used to compute the hash
nchars=len(chars$)
'comment next 4 lines for no entry with defaults
'print "number of warriors (n) "; : input n
'print "width (d) "; : input d
'print "output file "; : input f$
'print "bench set (none to skip) "; : input bench$
print "processing..."
dim hashes(n,2),wlist(n,n),wnum(n,2)
if bench$="" then goto skipbenchlist
if usewin then ls$="dir /b ":ps$="\" else ls$="ls -1 ":ps$="/"
shell ls$+benchbase$+bench$+ps$+"*.red > bench.lst"
label skipbenchlist:
nwlist=0:topscore=-1:topwar$="":lc=0:accscore=0:randomize
open f$ for output as #2
for i=0 to n-1
 w$=str$(i)+".red"
 open w$ for input as #1
 hash=0:linenumber=0
 while not eof(1)
  line input #1,a$:linenumber=linenumber+1
  if left$(a$,1)<>";" then gosub addhash
 wend
 close #1
 chrhash=(hash mod nchars)+1
 print #2,mid$(chars$,chrhash,1);
 lc=lc+1 : if lc>=d then print #2,"":lc=0
 hashes(i+1,1)=hash:hashes(i+1,2)=chrhash
next i
print #2,""
for i=0 to n-1
 hash=hashes(i+1,1):skip=0
 if i<1 then goto skiphashcheck
 for j=1 to nwlist
  if hash<>wnum(j,1) or skip then goto nextlist
  wnum(j,2)=wnum(j,2)+1
  wlist(j,wnum(j,2))=i:skip=1
  label nextlist:
 next j
 label skiphashcheck:
 if skip then goto alreadyadded
 nwlist=nwlist+1:wnum(nwlist,1)=hash
 wnum(nwlist,2)=1:wlist(nwlist,1)=i
 label alreadyadded:
next i
print
print "Detected ";nwlist;" types out of ";n;" warriors"
print #2,"Detected ";nwlist;" types out of ";n;" warriors"
if bench$<>"" then print "Using ";bench$;" benchmark"
if bench$<>"" then print #2,"Using ";bench$;" benchmark"
print #2,""
for j=1 to nwlist
 members=wnum(j,2)
 if bench$="" then i=wlist(j,int(rnd*members)+1):goto skipbench
 print "Testing ";members;" members with hash=";wnum(j,1)
 'for nano list the instructions..
 z=instr(pmars$,"-s 80 "):if z=0 then goto dontlistinstructions
 w$=str$(wlist(j,1))+".red"
 open w$ for input as #5:line input #5,a$
 print "|";
 while not eof(5)
  line input #5,a$:print left$(a$,6);"|";
 wend:close #5:print
 label dontlistinstructions:
 topmscore=-1:i=-1
 for k=1 to members
  warnum=wlist(j,k):war$=str$(warnum)+".red"
  gosub benchmarkwar
  print "Warrior ";war$;" scores ";left$(str$(score)+"     ",6)
  if score>topmscore then topmscore=score:i=warnum
  if score>topscore then topscore=score:topwar$=war$
  accscore=accscore+score
 next k
 label skipbench:
 w$=str$(i)+".red"
 print #2,"Warrior ";w$;
 if bench$<>"" then print #2, "  score=";left$(str$(topmscore)+"     ",6);
 print #2,"  symbol ";mid$(chars$,hashes(i+1,2),1);
 print #2," (";members;
 if members > 1 then print #2," members)" else print #2," member)"
 open w$ for input as #1
 while not eof(1):line input #1,a$:print #2,a$:wend
 close #1:print #2,""
next j
if bench$="" then goto skiptopscore
print "Average score = ";left$(str$(accscore/n)+"     ",6)
print "Top-scoring warrior is ";topwar$;
print "  score=";left$(str$(topscore)+"     ",6)
print #2,"Average score = ";left$(str$(accscore/n)+"     ",6)
print #2,"Top-scoring warrior is ";topwar$;
print #2,"  score=";left$(str$(topscore)+"     ",6)
open topwar$ for input as #1
while not eof(1)
 line input #1,a$:print #2,a$:print a$
wend
close #1:print #2,""
label skiptopscore:
'uncomment next line to skip hash list...
'goto skiphashlist
print #2,"Hash list..."
for j=1 to nwlist
 a$=str$(wnum(j,1))+":":llen=len(a$)
 print #2,a$;
 for k=1 to wnum(j,2)
  a$=str$(wlist(j,k))+" ":ilen=len(a$)
  if llen+ilen>79 then print #2,"":print #2," ";:llen=1
  print #2,a$;:llen=llen+ilen
 next k
 print #2,""
next j
label skiphashlist:
close #2
end
label addhash:
linehash=0
for z=1 to hashwidth
 linehash=linehash+asc(mid$(a$,z,1))*z
next z
linehash=linehash*linenumber
hash=hash+linehash
return
label benchmarkwar:
nitems=0:score=0
open "bench.lst" for input as #3
while not eof(3)
 line input #3, opp$
 if usewin then opp$=benchbase$+bench$+ps$+opp$
 shell pmars$+" "+war$+" "+opp$+" > _scores.tmp"
 open "_scores.tmp" for input as #4
 line input #4,a$:close #4:kill "_scores.tmp"
 z=instr(a$," "):w=val(left$(a$,z)):t=val(mid$(a$,z))
 score=score+(w*3+t)*(100/rounds):nitems=nitems+1
wend:close #3:score=score/nitems
return
