%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % MiniZinc plays Dragster % % Description: a MiniZinc program to simulate the % logic of the game Dragster by Activision, based on % the original Omnigamer's spreadsheet. % % !!!>>> Tip: Use Chuffed built-in solver <<Time=5.5778 % MAXFRAME=166->Time=5.5444 % MAXFRAME=165->Time=5.511 int : MAXFRAME = 167; % Target distance (97*256=24832) int : FINALDIST = 24832; % Starting frame var 0..14 : STARTFRAME; constraint (STARTFRAME mod 2) = 0; % multiple of 2, max 14 % Starting Tach var 0..30 : STARTTACH; constraint (STARTTACH mod 3) = 0; % multiple of 3, max 30 % Some constants and types ... var int : MAXGEAR = 4; var int : MAXTACH = 31; set of int : FRAMES = 0..MAXFRAME; set of int : GEARS = 0..4; set of int : SPEEDS = 0..253; set of int : TACHS = 0..40; set of int : PFRAMES = 1..MAXFRAME; % Instead of using Power2 function we use an array array [0..4] of int : Pow2 = array1d(0..4 ,[1, 2, 4, 8, 16]); array [0..4] of int : Pow2Sub1 = array1d(0..4 ,[0, 1, 2, 4, 8]); array [0..4] of int : Pow2Sub2 = array1d(0..4 ,[0, 0, 1, 2, 4]); array [FRAMES] of var int : Distance; % distance list array [FRAMES] of var GEARS : Gear; % gear list array [FRAMES] of var 0..1 : Shift; % shift list array [FRAMES] of var 0..1 : Gas; % gas list array [FRAMES] of var SPEEDS : Speed; % speed list array [FRAMES] of var TACHS : Tach; % tach list array [FRAMES] of var TACHS : PostTach; % post tach list array [FRAMES] of var 0..1 : Advance; % advance list array [FRAMES] of var SPEEDS : Limit; % limit list %array [FRAMES] of var 0..1 : Stall; % shift list % Initial conditions ... constraint Advance[0] = 1; constraint Speed[0] = 0; constraint Distance[0] = 0; constraint Tach[0] = STARTTACH; constraint PostTach[0] = STARTTACH; % ... Starting Gear ... constraint Gear[0] = 0; % <<0, IF(G5=1,I5,IF(I50, IF(Shift[i-1]=1,Speed[i-1],IF(Speed[i-1] 0 then if Shift[i-1] = 1 then Speed[i-1] else if Speed[i-1] < Limit[i] then Speed[i-1]+2 else if Speed[i-1] = Limit[i] then Speed[i-1] else Speed[i-1] - 1 endif endif endif else 0 endif ); %J6=FLOOR(IF(K6>=20,K6*POWER(2,E6-1)+POWER(2,E6-2),K6*POWER(2,E6-1)),1) %Limit[i]=FLOOR(IF(Tach[i]>=20,Tach[i]*Pow2GearM1[Gear[i]]+Pow2GearM2[Gear[i]],Tach[i]*Pow2GearM1[Gear[i]]),1) constraint forall(i in FRAMES) ( Limit[i] = if Gear[i] > 0 then Tach[i]*Pow2Sub1[ Gear[i] ] + if Tach[i] >= 20 then Pow2Sub2[ Gear[i] ] else 0 endif else Tach[i] div 2 endif ); %K6=IF(G5=1,IF(H6=1,L5+3,L5-3),IF(B6=1,IF(H6=1,L5+1,L5-1),L5)) %Tach[i]=IF(Shift[i-1]=1,IF(Gas[i]=1,PostTach[i-1]+3,PostTach[i-1]-3),IF(Advance[i]=1,IF(Gas[i]=1,PostTach[i-1]+1,PostTach[i-1]-1),PostTach[i-1])) constraint forall(i in PFRAMES) ( Tach[i] = if Shift[i-1] = 1 then ( PostTach[i-1] + if Gas[i]=1 then +3 else -3 endif ) else ( if Advance[i]=1 then PostTach[i-1] + ( if Gas[i]=1 then +1 else -1 endif ) else PostTach[i-1] endif ) endif ); %L6=IF(G5=1,K6,IF((J6-I5)>=16,K6-1,K6)) %PostTach[i]=IF(Shift[i-1]=1,Tach[i],IF((Limit[i]-Speed[i-1])>=16,Tach[i]-1,Tach[i])) constraint forall(i in PFRAMES)( PostTach[i] = if Shift[i-1]=1 then Tach[i] else if (Limit[i] - Speed[i-1])>=16 then Tach[i]-1 else Tach[i] endif endif ); %M6=M5+I5 %Distance[i]=Distance[i-1]+Speed[i-1] constraint forall(i in PFRAMES)( Distance[i] = Distance[i-1] + Speed[i-1] ); % Winning condition constraint Distance[MAXFRAME] >= FINALDIST; % Optimization: assume that after frame 140, speed is at least 200 %constraint forall(i in 140..MAXFRAME)( % Speed[i] >=200 %); %solve satisfy; solve maximize Distance[MAXFRAME];