{ USSR 2.ww2ai By Josh Haas } {Set up some variables...} CONST LAND = 0; CONST AIR = 1; CONST SEA = 2; CONST VWEIGHT = 5; CONST FWEIGHT = 20; CONST MWEIGHT = 100; CONST AIDGOV = 7; CONST AIDREB = 6; CONST CONLAND = 0; CONST MERCHANT = 0; CONST TRANSPORT = 9; NbrNations := getnationcount(); NbrZones := getzonecount(); NbrUnits := getunitcount(); us := getcurrentplayer(); SetArray(routezone, NbrZones); SetArray(routescore, NbrZones); SetArray(needtransport, NbrZones); SetArray(threatcount, NbrZones); SetArray(defcount, NbrZones); SetArray(attack, NbrZones); SetArray(gone, NbrZones); SetArray(ourland, NbrZones); for i := 0 to NbrZones - 1 do begin routezone[i] := i; routescore[i] := 0; needtransport[i] := false; threatcount[i] := 0; defcount[i] := 0; attack[i] :=0; gone[i] := false; ourland[i] := 0; end; OurCap := getnationcapitalzone(us); {Diplomatic Code- tries to ally with potential major power allies, then allies with minor powers based on their relative strengths (currently based on the value and troops in their capital zone)} friend := -1; score := 0; for i := 0 to NbrNations - 1 do begin stance := getnationstance(us, i); if (stance <> 100) AND (stance <> -100) then begin cap := getnationcapitalzone(i); if cap <> -1 then begin nscore := getzonevalue(cap) * VWEIGHT; nscore := nscore + getzoneforcecount(cap, false, false, true, true, true, false); end else begin nscore := 0; end; if stance > 75 then nscore := nscore + FWEIGHT; if (stance > 0) and (isnationmajorpower(i)) then nscore := nscore + MWEIGHT; if nscore > score then begin score := nscore; friend := i; end; end; end; {we found our friend, now aid him if he likes us and aid rebels if he does not} if friend <> -1 then for i := 1 to 5 do {overkill is good} if (getnationstance(us, friend) > -10) or (isnationmajorpower(friend)) then orderdiplomatic(friend, AIDGOV) else orderdiplomatic(friend, AIDREB); {Formations} OrderChangeFormations( 10, 30, 80, 100, 30, 10, 10, 90, 70, 80, 70, 100, 100, 50, 60 ); {Choose a zone to route resources from islands to} score := 0; pzone := -1; for i := 1 to NbrZones - 1 do if getzoneowner(i) <> -1 then if (getnationalliance(getzoneowner(i)) = getnationalliance(us)) and (iszoneport(i)) and (NOT iszoneembattled(i)) then begin nscore := getzonevalue(i) + getzonefactories(i); if findclosestenemyzone(i, 6) <> -1 then nscore := nscore + 10; if findclosestenemyzone(i, 2) = -1 then nscore := nscore + 12; if nscore > score then begin score := nscore; pzone := i; end; end; {Count free transport space} tweight := 0; for i := 0 to NbrUnits - 1 do if (getunitowner(i) = us) and (getunitforcecounttype(i, TRANSPORT) > 0) then tweight := tweight + getunittransportroom(i); crisis := false; {Go through zones- route resources and collect intelligence} for i := 0 to NbrZones - 1 do begin if getzoneowner(i) = us then begin {check if we need transports} if i = OurCap then deftrans := 50 else deftrans := getzonefactories(i) + 8; if (findclosestenemyzone(i, 3) = -1) and (getzoneforcecount(i, true, false, false, true, false, false) > deftrans) and (iszoneport(i)) then needtransport[i] := true; {route resources} if OurCap = i then orderglobalrouteresources(i, 20); if (iszoneport(i)) and (getzonefactories(i) = 0) and (findclosestenemyzone(i, 6) = -1) and (pzone <> -1) then begin rzone := pzone; score := 10; for j := 0 to getzoneneighborcount(i) - 1 do begin n := getzoneneighbor(i, j); if iszoneland(n) then if (getzoneautoroutezone(n) <> i) and (routezone[n] <> i) and (getnationalliance(getzoneowner(n)) = getnationalliance(us)) then rzone := n; end; end else begin rzone := i; score := 5 * getzonefactories(i) + getzonevalue(i); if i = OurCap then score := score + 30; if getzoneresources(i) > getzonefactories(i) * 10 then score := score div 3; for j := 0 to getzoneneighborcount(i) - 1 do begin n := getzoneneighbor(i, j); if getzoneowner(n) <> -1 then begin nscore := 5 * getzonefactories(n) + getzonevalue(n); if n = OurCap then nscore := nscore + 15; if getzoneresources(n) > getzonefactories(n) * 10 then nscore := nscore div 3; if routezone[n] <> n then nscore := routescore[n]; if getzoneautoroutezone(n) <> n then nscore := nscore + 0; if getnationalliance(getzoneowner(n)) <> getnationalliance(us) then nscore := 0; if routezone[n] = i then nscore := 0; if getzoneautoroutezone(n) = i then nscore := 0; if nscore >= score then begin score := nscore; rzone := n; end; end; end; end; orderautorouteresources(i, rzone); routezone[i] := rzone; routescore[i] := score; {build factories and troops, and ships if you have too much troops} if (routezone[i] = i) or (getzoneowner(routezone[i]) <> us) then if (getzonefactories(i) = 0) and (getzoneresources(i) >= 25) then orderbuildfactory(i) else if (getzonefactories(i) < getzonevalue(i)) and (getzoneresources(i) > 25) and (getzoneresources(i) > 12 * getzonefactories(i)) then orderbuildfactory(i); f := 6 * getzonefactories(i); bn := getzoneresources(i) div 2; {if bn > f then bn := f;} if (getzoneforcecount(i, true, false, false, true, false, false) > 50) AND (findclosestenemyzone(i, 4) = -1) and (tweight < 60) and (iszoneport(i)) then orderbuildnavy( i, 0, getzoneresources( i ) div 4, 0, 0, 0, 0, 0 ) else orderbuildarmy(i, 0, bn / 4, 3 * bn / 4, 0 ); end; {Get strategic information} okay := getzoneowner(i) <> -1; if okay then okay := getnationalliance(getzoneowner(i)) = getnationalliance(us); if okay then begin defcount[i] := 0; if getzoneforcecount(i, true, false, false, true, false, false) > 0 then for j := 0 to getzoneunitcount(i) - 1 do begin u := getzoneunit(i, j); if (getunitowner(u) = us) and (getunitclass(u) = LAND) then defcount[i] := defcount[i] + getunitforcecount(u); end; ourland[i] := defcount[i]; for j := -1 to getzoneneighborcount(i) - 1 do begin if j = -1 then n := i else n := getzoneneighbor(i, j); okay := getzoneowner(n) = -1; if not okay then okay := isnationmajorpower(getzoneowner(n)); if okay then threatcount[i] := threatcount[i] + getzoneforcecount(n, false, true, false, true, true, false); end; if (getzonefactories(i) = 0) or (getzoneautoroutezone(i) <> i) then threatcount[i] := 0; if i = OurCap then threatcount[i] := threatcount[i] + 60; if (i = OurCap) and ((iszoneembattled(i) or (threatcount[i] - 15 >= getzoneforcecount(i, true, false, false, true, true, false)))) then crisis := true; end; end; {Choose a zone to send transports to} okay := OurCap <> -1; if okay then okay := iszoneport(OurCap); if okay then okay := findclosestenemyzone(OurCap, 3) <> -1; if okay then tzone := OurCap else begin tzone := -1; score := -99999999; for i := 0 to NbrZones - 1 do if getzoneowner(i) <> -1 then if (getnationalliance(getzoneowner(i)) = getnationalliance(us)) and (iszoneport(i)) and (findclosestenemyzone(i, 3) <> -1) and (not needtransport[i]) then begin if OurCap <> -1 then nscore := -1 * distance(i, OurCap) else nscore := getzonevalue(i); if nscore > score then begin score := nscore; tzone := i; end; end; end; if tzone <> -1 then if getzoneforcecount(tzone, true, false, false, true, true, false) > 20 then if findclosestenemyzone(tzone, 1) = - 1 then tzone := -1; {Order ground forces on a zone by zone basis} for i := 0 to NbrZones - 1 do if ourland[i] > 0 then begin u := 0; {Discuss who to obliterate} azone := -1; for j := 0 to getzoneneighborcount(i) - 1 do begin n := getzoneneighbor(i, j); if getzoneowner(n) <> -1 then if (azone = -1) and (getnationstance(getzoneowner(n), us) = -100) and (attack[n] <> 2) then begin if attack[n] = 1 then azone := n else begin score := getzoneforcecount(n, false, true, true, true, true, false); def := score; for k := 0 to getzoneneighborcount(n) - 1 do begin nn := getzoneneighbor(n, k); if not gone[nn] then begin cont := ourland[nn]; if threatcount[nn] > 0 then cont := cont - (threatcount[nn] - def); score := score - cont; end; end; if score < (-0.4 * getzoneforcecount(n, false, true, true, true, true, false) * (1+ getzoneterrainbonus(n) / 100.0) * (1 + getzoneborderdefense(n, i) / 8.0) ) - 2 then azone := n; end; end; end; ourl := ourland[i]; {Defend our territory!} need := threatcount[i]; defcount[i] := defcount[i] - ourl; if azone <> -1 then need := need - getzoneforcecount(azone, false, true, true, true, true, false); if (need > ourl) and (ourl > 60) then need := ourl - 15; ourl := ourl - need; while (u < getzoneunitcount(i)) and (need > 0) do begin unit := getzoneunit(i, u); if (getunitowner(unit) = us) and (getunitclass(unit) = LAND) then begin orderunitmove(unit, i); if getunitforcecount(unit) > 3 then orderunitdividepct(unit, 50); need := need - getunitforcecount(unit); defcount[i] := defcount[i] + getunitforcecount(unit); end; Inc( u ); end; ourl := ourl + need; need := 0; {use troops to attack; if enemy is pitiful do not use all troops and mark as attack = 2} if azone <> -1 then begin need := getzoneforcecount(azone, false, true, true, true, true, false) + 10; ourl := ourl - need; if ourl > 0 then attack[azone] := 2; while (u < getzoneunitcount(i)) and (need > 0) do begin unit := getzoneunit(i, u); if (getunitowner(unit) = us) and (getunitclass(unit) = LAND) then begin orderunitinvade(unit, azone); need := need - getunitforcecount(unit); end; Inc( u ); end; end; ourl := ourl + need; need := 0; {send troops to aid neighbors in need} for j := 0 to getzoneneighborcount(i) - 1 do begin n := getzoneneighbor(i, j); need := threatcount[n] - defcount[n]; ourl := ourl - need; while (u < getzoneunitcount(i)) and (need > 0) do begin unit := getzoneunit(i, u); if (getunitowner(unit) = us) and (getunitclass(unit) = LAND) then begin orderunitmove(unit, n); need := need - getunitforcecount(unit); defcount[n] := defcount[n] + getunitforcecount(unit); end; Inc( u ); ourl := ourl + need; need := 0; end; end; {extra troops must move out! attack if empty or pitiful (mark as attack = 2)} for j := 0 to getzoneneighborcount(i) - 1 do begin n := getzoneneighbor(i, j); need := 0; if (getzoneowner(n) <> -1) then if (getnationstance(us, getzoneowner(n)) < 70) and (friend <> getzoneowner(n)) then if getzoneforcecount(n, false, true, true, true, true, false) * 2 <= ourl then need := (getzoneforcecount(n, false, true, true, true, true, false) * 2) + 1; ourl := ourl - need; while (u < getzoneunitcount(i)) and (need > 0) do begin unit := getzoneunit(i, u); if (getunitowner(unit) =us) and (getunitclass(unit) = LAND) then begin orderunitinvade(unit, n); need := need - getunitforcecount(unit); attack[n] := 2; end; Inc( u ); ourl := ourl + need; need := 0; end; end; {maneuver around if large threat and move towards front if no threats } if ourl > 0 then begin mzone := -1; btzone := -1; for j := 0 to getzoneneighborcount(i) - 1 do begin n := getzoneneighbor(i, j); if getzoneforcecount(n, false, true, false, true, true, false) > 5 then btzone := n; end; if btzone <> -1 then begin mzone := getzoneneighbor(btzone, 0); if mzone = i then mzone := getzoneneighbor(btzone, 1); for j := 1 to getzoneneighborcount(btzone) - 1 do begin n := getzoneneighbor(btzone, j); if getzoneowner(n) <> -1 then if (getnationstance(getzoneowner(n), us) < 100) and (not iszoneneighbor(i, n)) then mzone := n; end; end else begin mzone := findclosestenemyzone(i, 15); if mzone = -1 then mzone := ourcap; end; {move all remaining troops to mzone} while u < getzoneunitcount(i) do begin unit := getzoneunit(i, u); if (getunitowner(unit) = us) and (getunitclass(unit) = LAND) then begin orderunitmove(unit, mzone); end; Inc( u ); end; end; gone[i] := true; end; {Go through units and order airforce and navy} for i := 0 to NbrUnits - 1 do if getunitowner(i) = us then begin if getunitclass(i) = SEA then begin notrans := false; if iszoneland(getunitzone(i)) then orderunitlaunch(i); if getunitforcecounttype(i, MERCHANT) > 0 then begin if pzone <> -1 then orderunitdock(i, pzone); end else if getunitforcecounttype(i, TRANSPORT) > 0 then begin if getunittransportroom(i) < 2 * getunitforcecounttype(i, TRANSPORT) then begin targ := tzone; close := findclosestenemyzone(getunitzone(i), 15); if targ = -1 then targ := close; if close <> -1 then if distance(getunitzone(i), targ) > 3 * distance(getunitzone(i), close) then targ := close; if targ <> -1 then begin if iszoneneighbor(getunitzone(i), targ) then orderunitdisembarkall(i, targ); dist := 9999999; disem := -1; for j := 0 to getzoneneighborcount(targ) - 1 do begin n := getzoneneighbor(targ, j); ndist := distance(n, getunitzone(i)); if (ndist < dist) and (not iszoneland(n)) then begin disem := n; dist := ndist; end; end; orderunitmove(i, disem); end else begin notrans := true; end; end else begin loadzone := -1; dist := 999999999; for j := 0 to NbrZones - 1 do if needtransport[j] then if distance(getunitzone(i), j) < dist then begin dist := distance(getunitzone(i), j); loadzone := j; end; if loadzone <> -1 then begin if iszoneneighbor(getunitzone(i), loadzone) then orderunitembarkall(i, loadzone); dist := 9999999; disem := -1; for j := 0 to getzoneneighborcount(loadzone) - 1 do begin n := getzoneneighbor(loadzone, j); ndist := distance(n, getunitzone(i)); if (ndist < dist) and (not iszoneland(n)) then begin disem := n; dist := ndist; end; end; orderunitmove(i, disem); end else begin notrans := true; end; end; end else begin notrans := true; end; if notrans then begin targ := -1; dist := 999999999; for j := 0 to NbrUnits - 1 do if (getnationstance(us, getunitowner(j)) = -100) and (getunitclass(j) = SEA) then if distance(getunitzone(i), getunitzone(j)) < dist then begin dist := distance(getunitzone(i), getunitzone(j)); targ := getunitzone(j); end; if targ <> -1 then begin orderunitmove(i, targ); end else begin dist := 9999999; targ := -1; for j := 0 to NbrZones - 1 do begin if getzoneowner(j) <> -1 then if (getzonefactories(j) > 0) and (iszoneport(j)) and (getnationstance(us, getzoneowner(j)) = -100) then if distance(getunitzone(i), j) < dist then begin dist := distance(getunitzone(i), j); targ := j; end; end; if targ <> -1 then orderunitbombard(i, targ); end; end; end else if getunitclass(i) = AIR then begin ok := getzoneowner(getunitzone(i)) = -1; if not ok then okay := getnationalliance(us) <> getnationalliance(getzoneowner(getunitzone(i))); if getunitbaseunit(i) <> -1 then begin dist := 99999999; for j := 0 to NbrZones - 1 do begin if (getzoneowner(j) <> -1) then if getnationalliance(us) = getnationalliance(getzoneowner(j)) then if findclosestenemyzone(j, 6) <> -1 then if distance(getunitzone(i), j) < dist then if truedistance(j, getunitzone(i)) < 12 then begin orderunitrebase(i, j); dist := distance(getunitzone(i), j); end; end; end else if ok then begin if (getzoneforcecount(getunitzone(i), false, true, true, true, true, true) = 0) or (getzoneforcecount(getunitzone(i), true, false, false, true, false, true) = 0) then orderunitreturntobase( i ); end else begin if getunitorder(i) <> 0 then begin orderunitreturntobase( i ); end else begin okay := OurCap <> -1; if okay then okay := iszoneembattled(OurCap); if (okay) or (crisis) then orderunitrebase(i, OurCap) else begin nTarget := -1; dist := 200000; for j := 0 to NbrZones - 1 do if (getzoneforcecount(j, false, true, false, true, true, false) > 0) or (iszoneembattled(j)) then if (iszoneembattled(j)) or (getzoneforcecount(j, false, true, true, true, true, true) < 6) then if distance(getunitzone(i), j) < dist then if truedistance(getunitzone(i), j ) < 5 then begin nTarget := j; dist := distance(getunitzone(i), j); end; if nTarget <> -1 then begin orderunitairstrike(i,nTarget); end else begin okay := OurCap <> -1; If okay then okay := findclosestenemyzone(OurCap, 4) <> -1; if okay then orderunitrebase(i, OurCap) else begin dist := 2000000; targ := -1; for j := 0 to NbrZones - 1 do begin if (getzoneowner(j) <> -1) then if getnationalliance(us) = getnationalliance(getzoneowner(j)) then if findclosestenemyzone(j, 4) <> -1 then if distance(getunitzone(i), j) < dist then if truedistance(j, getunitzone(i)) < 12 then begin targ := j; dist := distance(getunitzone(i), j); end; end; if targ <> -1 then orderunitrebase(i, targ); end; end; end; end; end; end; end;