-- 15/09/2k7: algorithms for Nomignolov's Intervalo's script, Jean M. Morales -- 15/09/2k7: start -- 15/09/2k7: added Oscillator, Halver and Filler -- 16/09/2k7: added Center and Borders (Mari), Median (Mari) -- : Random, Bodyguard, Inner Oscillator (Mari), Primer (Mari) -- 30/09/2k7: added Mirror, Uneven -- Situation: string to array situation_to_board = function (situation) local board = {}; for i = 1,64 do board[i] = string.sub(situation, i, i); end return board; end stb = situation_to_board; ALG = function (n, situation) res = 0; if (n == 1) then res = ALG_01(situation); end if (n == 2) then res = ALG_02(situation); end if (n == 3) then res = ALG_03(situation); end if (n == 4) then res = ALG_04(situation); end if (n == 5) then res = ALG_05(situation); end if (n == 6) then res = ALG_06(situation); end if (n == 7) then res = ALG_07(situation); end if (n == 8) then res = ALG_08(situation); end if (n == 9) then res = ALG_09(situation); end if (n == 10) then res = ALG_10(situation); end if (n == 11) then res = ALG_11(situation); end return res; end -- Oscillator -- - A = 1, ..., 32; B = 33, ..., 64 -- - p(X) = number of player's piece in set -- - play in B if p(B) < p(A), else in A -- - play in the empty cell farther from the center ALG_01 = function (situation) local res = 0; local pA = 0; local pB = 0; local S = stb(situation); for i = 1,32 do if (S[i] == "p") then pA = pA + 1; end if (S[32 + i] == "p") then pB = pB + 1; end end if (pB < pA) then for i = 1,64 do if (S[65 - i] == ".") then res = 65 - i; break; end end else for i = 1,64 do if (S[i] == ".") then res = i; break; end end end if (res == 0) then print("Error in algorithm Oscillator!!!"); end return res; end -- Halver -- - find the longest run of empty cells -- (take the one in case of draw) -- - place a piece in the middle of it -- (if there are n cells, n even, put in the middle of n=1) ALG_02 = function (situation) local res = 0; local S = stb(situation); local s1 = 0; local s2 = 0; local started = 0; local m1 = 0; local m2 = -1; for i = 1,64 do if (S[i] == ".") then if (started == 0) then s1 = i; s2 = i; started = 1; else s2 = i; end else if (started == 1) then -- just finished if ((s2 - s1 + 1) > (m2 - m1 + 1)) then m1 = s1; m2 = s2; end started = 0; end end end if (started == 1) then if ((s2 - s1 + 1) > (m2 - m1 + 1)) then m1 = s1; m2 = s2; end started = 0; end local n = m2 - m1 + 1; if (math.mod(n, 2) == 0) then res = m1 + n/2; else res = m1 + (n-1)/2; end if (res == 0) then print("Error in algorithm Halver!!!"); end return res; end -- Filler -- - Play in the first empty cell starting from 1 ALG_03 = function (situation) local res = 0; local S = stb(situation); for i = 1,64 do if (S[i] == ".") then res = i; break; end end if (res == 0) then print("Error in algorithm Filler!!!"); end return res; end -- Center and borders (Mari 16/09/2k7) -- - Count pieces to tell what turn is it. -- - Play with the following order: -- - Center most from the right -- - Farther to the left -- - Center most from the left -- - Farther to the right -- - If half board is filled, oscillate in the other half ALG_04 = function (situation) local res = 0; local S = stb(situation); local n_turns = 0; for i = 1,64 do if (S[i] == "n") then n_turns = n_turns + 1; else if ((S[i] == "a") or (S[i] == "p")) then n_turns = n_turns + 0.5; end end end -- n_turns should be integer -- CR, BL, CL, BR local found = 0; while (found == 0) do if (math.mod(n_turns, 4) == 0) then for i = 33,64 do -- CR if (S[i] == ".") then res = i; found = 1; break; end end n_turns = 2; --> so CL end if (math.mod(n_turns, 4) == 1) then for i = 1,32 do -- BL if (S[i] == ".") then res = i; found = 1; break; end end n_turns = 3; --> so BS end if (math.mod(n_turns, 4) == 2) then for i = 1,32 do -- CL if (S[33-i] == ".") then res = 33-i; found = 1; break; end end n_turns = 0; --> so CR end if (math.mod(n_turns, 4) == 3) then for i = 33,64 do -- BR if (S[64+33-i] == ".") then res = 64+33-i; found = 1; break; end end n_turns = 1; --> so BR end end if (res == 0) then print("Error in algorithm Center and Borders!!!"); end return res; end -- Median (Mari 16/09/2k7) -- - In a situation with n empty cells, play -- in the n/2 (or (n+1)/2) ALG_05 = function (situation) local res = 0; local S = stb(situation); local n_empty = 0; local pos = 0; for i = 1,64 do if (S[i] == ".") then n_empty = n_empty + 1; end end if (math.mod(n_empty, 2) == 0) then pos = n_empty/2; else pos = (n_empty+1)/2; end for i = 1,64 do if (S[i] == ".") then pos = pos - 1; if (pos == 0) then res = i; break; end end end if (res == 0) then print("Error in algorithm Median!!!"); end return res; end -- Random (16/09/2k7) -- - Play at random... ALG_06 = function (situation) local res = 0; local S = stb(situation); local n_empty = 0; local pos = 0; for i = 1,64 do if (S[i] == ".") then n_empty = n_empty + 1; end end pos = math.random(n_empty); for i = 1,64 do if (S[i] == ".") then pos = pos - 1; if (pos == 0) then res = i; break; end end end if (res == 0) then print("Error in algorithm Random!!!"); end return res; end -- Bodyguard (16/09/2k7) -- - Put a piece in a cell next to an opponent's -- piece, else random. ALG_07 = function (situation) local res = 0; local S = stb(situation); for i = 1,64 do if (S[i] == "a") then if ((i > 1) and (S[i-1] == ".")) then res = i-1; break; end if ((i < 64) and (S[i+1] == ".")) then res = i+1; break; end end end if (res == 0) then res = ALG_06(situation); end if (res == 0) then print("Error in algorithm Bodyguard!!!"); end return res; end -- Inner Oscillator (Marisa - 16/09/2k7) -- - Put a piece nearer to the center ALG_08 = function (situation) local res = 0; local S = stb(situation); for i = 1,32 do if (S[32 + i] == ".") then res = 32 + i; break; else if (S[33 - i] == ".") then res = 33 - i; break; end end end if (res == 0) then print("Error in algorithm Inner Oscillator!!!"); end return res; end -- Primer (Marisa - 16/09/2k7) -- - Put a piece in a prime numbered position, else random ALG_09 = function (situation) local res = 0; local S = stb(situation); if (S[61] == ".") then res = 61; end if (S[59] == ".") then res = 59; end if (S[53] == ".") then res = 53; end if (S[47] == ".") then res = 47; end if (S[43] == ".") then res = 43; end if (S[41] == ".") then res = 41; end if (S[37] == ".") then res = 37; end if (S[31] == ".") then res = 31; end if (S[29] == ".") then res = 29; end if (S[23] == ".") then res = 23; end if (S[19] == ".") then res = 19; end if (S[17] == ".") then res = 17; end if (S[13] == ".") then res = 13; end if (S[11] == ".") then res = 11; end if (S[7] == ".") then res = 7; end if (S[5] == ".") then res = 5; end if (S[3] == ".") then res = 3; end if (S[2] == ".") then res = 2; end if (res == 0) then res = ALG_06(situation); end if (res == 0) then print("Error in algorithm Primer!!!"); end return res; end -- Mirror (30/09/2k7) -- - Put a piece in the first i with 65-i empty, else random. ALG_10 = function (situation) local res = 0; local S = stb(situation); for i = 1,32 do if ((S[i] ~= ".") and (S[65-i] == ".")) then res = 65 - i; break; end end if (res == 0) then res = ALG_06(situation); end if (res == 0) then print("Error in algorithm Mirror!!!"); end return res; end -- Uneven (30/09/2k7) -- - Put a piece in the first empty i when in 1,i there are -- more friendly pieces than opponent's pieces (> 0). ALG_11 = function (situation) local res = 0; local S = stb(situation); local n_my = 0; local n_opp = 0; for i = 1,64 do if (S[i] == "p") then n_my = n_my + 1; end if (S[i] == "a") then n_opp = n_opp + 1; end if ((S[i] == ".") and (n_opp > 0) and (n_my > n_opp)) then res = i; break; end end if (res == 0) then res = ALG_06(situation); end if (res == 0) then print("Error in algorithm Uneven!!!"); end return res; end