1 2(********************************************************************) 3(* *) 4(* dnafight.sd7 Bacterial dna fight programming game *) 5(* Copyright (C) 1985 Thomas Mertes *) 6(* *) 7(* This program is free software; you can redistribute it and/or *) 8(* modify it under the terms of the GNU General Public License as *) 9(* published by the Free Software Foundation; either version 2 of *) 10(* the License, or (at your option) any later version. *) 11(* *) 12(* This program is distributed in the hope that it will be useful, *) 13(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) 14(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) 15(* GNU General Public License for more details. *) 16(* *) 17(* You should have received a copy of the GNU General Public *) 18(* License along with this program; if not, write to the *) 19(* Free Software Foundation, Inc., 51 Franklin Street, *) 20(* Fifth Floor, Boston, MA 02110-1301, USA. *) 21(* *) 22(********************************************************************) 23 24 25const proc: dna (ORANGE) is func 26 27 local 28 const colorSet: FRIENDS is {ORANGE}; 29 var colorSet: enemy is colorSet.EMPTY_SET; 30 var direction: direct is HERE; 31 var directSet: killDirs is directSet.EMPTY_SET; 32 var directSet: eatDirs is directSet.EMPTY_SET; 33 var directSet: splitDirs is directSet.EMPTY_SET; 34 var directSet: helpDirs is directSet.EMPTY_SET; 35 var power: killPow is 0; 36 var power: eatPow is 0; 37 var power: splitPow is 0; 38 var power: helpPow is 0; 39 var power: split1Pow is 0; 40 var power: split2Pow is 0; 41 var power: newPow is 0; 42 var power: new1SplitPow is 0; 43 var power: new2SplitPow is 0; 44 var power: meal is 0; 45 var boolean: dangerHere is FALSE; 46 47 48 const func direction: optimalDir (in directSet: dirs) is func 49 result 50 var direction: optimalDir is HERE; 51 52 local 53 var direction: direct is HERE; 54 var power: pow is 0; 55 var power: help is 0; 56 var directSet: directs is directSet.EMPTY_SET; 57 58 begin (* optimalDir *) 59 if dirs = {HERE} then 60 optimalDir := HERE; 61 else 62 pow := 0; 63 directs := directSet.EMPTY_SET; 64 for direct range MAIN_DIRECTIONS do 65 if direct in dirs then 66 help := food(left[direct]) + food(direct) + 67 food(right[direct]); 68 if help > pow then 69 pow := help; 70 directs := directSet.EMPTY_SET; 71 incl(directs, direct); 72 elsif help = pow then 73 incl(directs, direct); 74 end if; 75 end if; 76 end for; 77 optimalDir := ranDir(directs); 78 end if; 79 end func; 80 81 82 begin (* dna (ORANGE) *) 83 enemy := ALL_COLORS; 84 excl(enemy, ORANGE); 85 killPow := 0; 86 eatPow := 0; 87 splitPow := 0; 88 helpPow := 0; 89 newPow := strength(HERE) - shrinkSize(strength(HERE)); 90 split1Pow := strength(HERE) - strength(HERE) div 2; 91 split2Pow := strength(HERE) div 2; 92 new1SplitPow := split1Pow - shrinkSize(split1Pow); 93 if strength(HERE) > 1 then 94 new2SplitPow := split2Pow - shrinkSize(split2Pow); 95 else 96 new2SplitPow := 0; 97 end if; 98 dangerHere := FALSE; 99 for direct range MAIN_DIRECTIONS do 100 if view(direct) = CLEAR then 101 meal := min(strength(HERE), food(direct)); 102 if (view( left [direct]) in enemy and 103 strength(left [direct]) >= newPow + meal) or 104 (view( right[direct]) in enemy and 105 strength(right[direct]) >= newPow + meal) then 106 noop; 107 else 108 if meal > eatPow then 109 eatPow := meal; 110 eatDirs := directSet.EMPTY_SET; 111 incl(eatDirs, direct); 112 elsif meal = eatPow then 113 incl(eatDirs, direct); 114 end if; 115 end if; 116 meal := min(strength(HERE) div 2, food(direct)); 117 if (view( left [direct]) in enemy and 118 strength(left [direct]) >= new2SplitPow + meal) or 119 (view( right[direct]) in enemy and 120 strength(right[direct]) >= new2SplitPow + meal) then 121 noop; 122 else 123 if meal>splitPow then 124 splitPow := meal; 125 splitDirs := directSet.EMPTY_SET; 126 incl(splitDirs, direct); 127 elsif meal = splitPow then 128 incl(splitDirs, direct); 129 end if; 130 end if; 131 else 132 if view(direct) in enemy then 133 if strength(direct)>strength(HERE) then 134 dangerHere := TRUE; 135 else 136 if (view( left [direct]) in enemy and 137 strength(left [direct]) >= newPow + strength(direct)) or 138 (view( right[direct]) in enemy and 139 strength(right[direct]) >= newPow + strength(direct)) then 140 noop; 141 else 142 if strength(direct) > killPow then 143 killPow := strength(direct); 144 killDirs := directSet.EMPTY_SET; 145 incl(killDirs, direct); 146 elsif strength(direct) = killPow then 147 incl(killDirs, direct); 148 end if; 149 end if; 150 end if; 151 else 152 if view(direct) in FRIENDS then 153 if (strength(direct)<=strength(HERE)) then 154 if (view( left [direct]) in enemy and 155 strength(left [direct]) >= strength(direct) and 156 strength(left [direct]) < newPow + strength(direct)) or 157 (view( right[direct]) in enemy and 158 strength(right[direct]) >= strength(direct) and 159 strength(right[direct]) < newPow + strength(direct)) then 160 if strength(direct) > helpPow then 161 helpPow := strength(direct); 162 helpDirs := directSet.EMPTY_SET; 163 incl(helpDirs, direct); 164 elsif strength(direct) = helpPow then 165 incl(helpDirs, direct); 166 end if; 167 end if; 168 end if; 169 end if; 170 end if; 171 end if; 172 end for; 173 meal := min(strength(HERE)-strength(HERE) div 2, food(HERE)); 174 if dangerHere or strength(HERE) = 1 or 175 killPow >= new1SplitPow + meal then 176 splitPow := 0; 177 splitDirs := directSet.EMPTY_SET; 178 else 179 splitPow := new1SplitPow + meal + new2SplitPow + splitPow; 180 end if; 181 if not dangerHere then 182 meal := min(strength(HERE), food(HERE)); 183 if meal > eatPow then 184 eatPow := meal; 185 eatDirs := directSet.EMPTY_SET; 186 incl(eatDirs, HERE); 187 else 188 if meal = eatPow then 189 incl(eatDirs, HERE); 190 end if; 191 end if; 192 end if; 193 eatPow := newPow + eatPow; 194 killPow := newPow + killPow; 195 helpPow := newPow + helpPow; 196 if killDirs <> directSet.EMPTY_SET and 197 killPow >= strength(HERE) - newPow then 198 kill(optimalDir(killDirs)) 199 else 200 if max(max(eatPow, splitPow), helpPow)>0 then 201 if splitPow >= eatPow then 202 if helpPow>splitPow then 203 kill(optimalDir(helpDirs)); 204 else 205 split(optimalDir(splitDirs), split1Pow, split2Pow); 206 end if; 207 else 208 if helpPow>eatPow then 209 kill(optimalDir(helpDirs)); 210 else 211 eat(optimalDir(eatDirs), strength(HERE)); 212 end if; 213 end if; 214 else 215 noop; 216 end if; 217 end if; 218 end func; (* dna (ORANGE) *) 219