Last active
January 7, 2016 10:53
-
-
Save taeguk/4960f486998132cb2d84 to your computer and use it in GitHub Desktop.
Lua file for SSM SlimeWar AI Contest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
Slime War Battle AI by taeguk | |
Recent modified in 2015-07-18 | |
]]-- | |
-- [applied methods] | |
-- Board:moveQSlime(fromx,fromy,tox,toy) | |
-- Board:moveSlime(fromx,fromy,tox,toy,number) | |
-- Board:getSlime(x,y) | |
-- Board:getTerritory(x,y) | |
-- Board:getMyQueenX() | |
-- Board:getMyQueenY() | |
-- Board:getEnemyQueenX() | |
-- Board:getEnemyQueenY() | |
-- global variables | |
eX = {1,1,9,9} | |
eY = {1,9,1,9} | |
homeX = 1 | |
homeY = 1 | |
b_dx = {0,-1,1,0} | |
b_dy = {1,0,0,-1} | |
dx = {} | |
dy = {} | |
prevQX = Board:getMyQueenX() | |
prevQY = Board:getMyQueenY() | |
queenFlag = 1 | |
edgeFlag = false | |
edgeX = 1 | |
edgeY = 1 | |
spreadFlag = true | |
-- functions | |
function moveQueenCenter() | |
local qX = Board:getMyQueenX() | |
local qY = Board:getMyQueenY() | |
local tX = 5 tY = 5 | |
local mDist = 11111 | |
local mIdx = 1 | |
for i=1,4 do | |
local nx = qX + dx[i] | |
local ny = qY + dy[i] | |
local dist = math.abs(tX-nx) + math.abs(tY-ny) | |
if not (nx < 1 or nx > 9 or ny < 1 or ny > 9) and dist < mDist then | |
mDist = dist | |
mIdx = i | |
end | |
end | |
if mDist <= 0 then | |
queenFlag = queenFlag + 1 | |
end | |
Board:moveQSlime(qX, qY, qX + dx[mIdx], qY + dy[mIdx]) | |
end | |
function moveQueenEdge() | |
local qX = Board:getMyQueenX() | |
local qY = Board:getMyQueenY() | |
local mX = qX - 1 < 9 - qX and 1 or (qX - 1 > 9 - qX and 9 or homeX) | |
local mY = qY - 1 < 9 - qY and 1 or (qY - 1 > 9 - qY and 9 or homeY) | |
if not edgeFlag then | |
if prevQX == qX then | |
edgeX = mX | |
edgeY = qY | |
else | |
edgeX = qX | |
edgeY = mY | |
end | |
edgeFlag = true | |
end | |
local cDist = math.abs(qX-edgeX) + math.abs(qY-edgeY) | |
if cDist <= 1 then | |
queenFlag = queenFlag + 1 | |
end | |
for i = 1, 4 do | |
local nx = qX + dx[i] | |
local ny = qY + dy[i] | |
local nDist = math.abs(nx-edgeX) + math.abs(ny-edgeY) | |
if not (nx < 1 or nx > 9 or ny < 1 or ny > 9) and nDist < cDist then | |
Board:moveQSlime(qX, qY, nx, ny) | |
break | |
end | |
end | |
end | |
function moveQueenCorner() | |
local qX = Board:getMyQueenX() | |
local qY = Board:getMyQueenY() | |
local cDist = math.abs(qX-homeX) + math.abs(qY-homeY) | |
if cDist <= 1 then | |
queenFlag = queenFlag + 1 | |
end | |
for i = 1, 4 do | |
local nx = qX + dx[i] | |
local ny = qY + dy[i] | |
local nDist = math.abs(nx-homeX) + math.abs(ny-homeY) | |
if not (nx < 1 or nx > 9 or ny < 1 or ny > 9) and nDist < cDist then | |
Board:moveQSlime(qX, qY, nx, ny) | |
break | |
end | |
end | |
return true | |
end | |
function escapeQueen() | |
local qX = Board:getMyQueenX() | |
local qY = Board:getMyQueenY() | |
local bDist = -1 | |
local bX = qX bY = qY | |
for x=1,9 do | |
for y=1,9 do | |
if Board:getSlime(x,y) >= 0 then | |
local mDist = 11111 | |
for i=1,9 do | |
for j=1,9 do | |
if Board:getSlime(i,j) < 0 then | |
local dist = math.abs(x-i) + math.abs(y-j) | |
if dist < mDist then mDist = dist end | |
end | |
end -- j loop | |
end -- i loop | |
if mDist > bDist then | |
bDist = mDist | |
bX = x | |
bY = y | |
end | |
end | |
end -- y loop | |
end -- x loop | |
local mDist = 11111 | |
local mIdx = 1 | |
for i=1,4 do | |
local nx = qX + dx[i] | |
local ny = qY + dy[i] | |
local dist = math.abs(bX-nx) + math.abs(bY-ny) | |
if not (nx < 1 or nx > 9 or ny < 1 or ny > 9) and Board:getSlime(nx,ny) >= 0 and dist < mDist then | |
mDist = dist | |
mIdx = i | |
end | |
end | |
Board:moveQSlime(qX, qY, qX + dx[mIdx],qY + dy[mIdx]) | |
end | |
function mergeMode() | |
local qX = Board:getMyQueenX() | |
local qY = Board:getMyQueenY() | |
for x = 1, 9 do | |
for y = 1, 9 do | |
if Board:getSlime(x,y) > 0 then | |
local cDist = math.abs(x-qX) + math.abs(y-qY) | |
local mx = {} my = {} | |
local cnt = 0 | |
for i = 1, 4 do | |
local nx = x + dx[i] | |
local ny = y + dy[i] | |
local nDist = math.abs(nx-qX) + math.abs(ny-qY) | |
if nDist <= cDist and not (nx < 1 or nx > 9 or ny < 1 or ny > 9) then | |
cnt = cnt + 1 | |
mx[cnt] = nx | |
my[cnt] = ny | |
end | |
end | |
for i = 1, cnt do | |
Board:moveSlime(x, y, mx[i], my[i], math.floor((Board:getSlime(x,y)-1)/cnt)) | |
end | |
end | |
end | |
end | |
end | |
function spreadMode() | |
local qX = homeX | |
local qY = homeY | |
for x = 1, 9 do | |
for y = 1, 9 do | |
if Board:getSlime(x,y) > 0 then | |
local cDist = math.abs(x-qX) + math.abs(y-qY) | |
local mx = {} my = {} | |
local cnt = 0 | |
local gCnt = 0 | |
for i = 1, 4 do | |
local nx = x + dx[i] | |
local ny = y + dy[i] | |
local nDist = math.abs(nx-qX) + math.abs(ny-qY) | |
if not (nx < 1 or nx > 9 or ny < 1 or ny > 9) and (Board:getSlime(nx,ny) <= 0 or nDist > cDist) then | |
cnt = cnt + 1 | |
mx[cnt] = nx | |
my[cnt] = ny | |
if Board:getSlime(nx,ny) == 0 then | |
gCnt = gCnt + 1 | |
mx[cnt], mx[gCnt] = mx[gCnt], mx[cnt] | |
my[cnt], my[gCnt] = my[gCnt], my[cnt] | |
end | |
end | |
end | |
local dn = cnt < Board:getSlime(x,y)-1 and cnt or Board:getSlime(x,y)-1 | |
for i = 1, dn do | |
if Board:getSlime(mx[i],my[i]) >= 0 or (math.abs(Board:getSlime(mx[i],my[i])) < math.floor((Board:getSlime(x,y)-1)/dn)) then | |
Board:moveSlime(x, y, mx[i], my[i], math.floor((Board:getSlime(x,y)-1)/dn)) | |
end | |
end | |
end | |
end | |
end | |
end | |
function attackMode() | |
local qX = Board:getEnemyQueenX() | |
local qY = Board:getEnemyQueenY() | |
for x = 1, 9 do | |
for y = 1, 9 do | |
if Board:getSlime(x,y) > 0 then | |
local cDist = math.abs(x-qX) + math.abs(y-qY) | |
local mIdx = 1 | |
local mDist = 11111 | |
for i = 1, 4 do | |
local nx = x + dx[i] | |
local ny = y + dy[i] | |
local nDist = math.abs(nx-qX) + math.abs(ny-qY) | |
if nx == qX and ny == qY then | |
Board:moveSlime(x,y,nx,ny,math.floor((Board:getSlime(x,y)-1)/3)) | |
end | |
if nDist < mDist and not (nx < 1 or nx > 9 or ny < 1 or ny > 9) then | |
mDist = nDist | |
mIdx = i | |
end | |
end | |
if Board:getSlime(x+dx[mIdx],y+dy[mIdx]) >= 0 or (math.abs(Board:getSlime(x+dx[mIdx],y+dy[mIdx])) < math.floor(Board:getSlime(x,y)-1)) then | |
Board:moveSlime(x, y, x+dx[mIdx], y+dy[mIdx], math.floor(Board:getSlime(x,y)-1)) | |
end | |
end | |
end | |
end | |
end | |
function detectEnemy() | |
local qX = Board:getMyQueenX() | |
local qY = Board:getMyQueenY() | |
for i=-1,1 do | |
for j=-1,1 do | |
local nx = qX + i | |
local ny = qY + j | |
if not (nx < 1 or nx > 9 or ny < 1 or ny > 9) and Board:getSlime(nx,ny) < 0 then | |
return true | |
end | |
end | |
end | |
return false | |
end | |
function defendMode() | |
local qX = Board:getMyQueenX() | |
local qY = Board:getMyQueenY() | |
for x = 1, 9 do | |
for y = 1, 9 do | |
if Board:getSlime(x,y) > 0 then | |
local mIdx = 1 | |
local mDist = 11111 | |
local flag = true | |
for i=1,4 do | |
local nx = x + dx[i] | |
local ny = y + dy[i] | |
local nDist = math.abs(nx-qX) + math.abs(ny-qY) | |
if not (nx < 1 or nx > 9 or ny < 1 or ny > 9) and (flag or Board:getSlime(nx,ny) < 0) and nDist <= mDist then | |
mDist = nDist | |
mIdx = i | |
if Board:getSlime(nx,ny) < 0 then | |
flag = false | |
end | |
end | |
end | |
Board:moveSlime(x, y, x+dx[mIdx], y+dy[mIdx], math.floor(Board:getSlime(x,y)-1)) | |
end | |
end | |
end | |
end | |
function randomConstants() | |
local rIdxs = {} | |
local check = {false, false, false, false} | |
local idx = 1 | |
while idx <= 4 do | |
local n = math.random(1,4) | |
if not check[n] then | |
check[n] = true | |
rIdxs[idx] = n | |
idx = idx + 1 | |
end | |
end | |
for i=1,4 do | |
dx[i] = b_dx[rIdxs[i]] | |
dy[i] = b_dy[rIdxs[i]] | |
end | |
end | |
function init() | |
local qX = Board:getMyQueenX() | |
local qY = Board:getMyQueenY() | |
local mIdx = 1 | |
local mDist = 11111 | |
randomConstants() | |
for i=1,4 do | |
local dist = math.abs(eX[i]-qX) + math.abs(eY[i]-qY) | |
if dist < mDist then | |
mDist = dist | |
mIdx = i | |
end | |
end | |
homeX = eX[mIdx] | |
homeY = eY[mIdx] | |
end | |
function checkSparse() | |
local cnt = 0 | |
for i=1,9 do | |
for j=1,9 do | |
if Board:getSlime(i,j) == 0 then | |
cnt = cnt + 1 | |
end | |
end | |
end | |
if cnt <= 5 then | |
spreadFlag = false | |
end | |
end | |
function main() | |
for indexTurn = 1, 100 do | |
local b_prevQX = Board:getMyQueenX() | |
local b_prevQY = Board:getMyQueenY() | |
randomConstants() | |
if queenFlag == 1 then moveQueenCenter() | |
elseif queenFlag == 2 then moveQueenEdge() | |
elseif queenFlag == 3 then moveQueenCorner() | |
else escapeQueen() | |
end | |
if detectEnemy() then defendMode() | |
elseif spreadFlag and indexTurn < 20 then checkSparse() spreadMode() | |
else attackMode() | |
end | |
prevQX = b_prevQX | |
prevQY = b_prevQY | |
nextTurn() | |
end | |
end | |
-- The flow of code starts here | |
init() | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment