I worked on a quick-and-dirty implementation of this algorithm where instead of visibility true-false the flood-fill attempts to find the height of the LOS. (The map array has heights of the things in the square.) My idea is to use it to modify the attractiveness of hexes for the AI to consider moving to. The result is less than satisfactory, so far. If anyone has any ideas, I'd like to see this work.
<html><head><title>Test javascript Breadth-first Flood-fill</title><script language='javascript'><br><br>var map = [[1,1,1,2,1,1,1,1,1,1,1],<br> [1,1,1,2,1,1,1,1,1,1,1],<br> [1,1,2,2,1,1,1,1,1,1,1],<br> [1,1,2,2,1,1,1,2,1,1,1],<br> [1,1,1,1,1,1,1,3,1,1,1],<br> [1,1,1,1,1,1,1,2,1,1,1],<br> [1,1,1,1,1,1,1,1,1,1,1],<br> [1,1,1,1,2,1,2,1,1,1,1],<br> [1,1,1,1,1,1,1,1,1,1,1],<br> [1,1,1,1,1,1,1,1,1,1,1],<br> [1,1,1,1,1,1,1,1,1,1,1]]<br><br>var out = new Array();<br><br>for (y = 0; y <= 10; y++) {<br> out[y] = new Array();<br> for (x = 0; x <= 10; x++) {<br> out[y][x] = new Array();<br> out[y][x][0] = 0; // Visited flag<br> out[y][x][1] = 0; // Height<br> out[y][x][2] = 0; // Attack strength<br> }<br>}<br><br>function format(num) {<br> var fmt = ' ' + num.toFixed(1);<br> return '|' + fmt.substr(fmt.length-4, 4);<br>}<br><br>function doit() {<br><br> var stack = new Array();<br><br> function get_hgt(a) {<br> var x = a[0];<br> var y = a[1];<br> var dx = a[2];<br> var dy = a[3];<br> var str = a[4];<br> var rng = a[5];<br> var ax = Math.abs(dx);<br> var ay = Math.abs(dy);<br> var az = ax + ay;<br><br> var f1 = ay / ax;<br> var f2 = ax / ay;<br> var h = out[y][x][1];<br> if (dy > 0) {<br> if (dx > 0) {<br> if (ax > ay) {<br> h = out[y][x-1][1] * (1 - f1) + out[y-1][x-1][1] * f1;<br> } else if (ax < ay) {<br> h = out[y-1][x][1] * (1 - f2) + out[y-1][x-1][1] * f2;<br> } else {<br> h = out[y-1][x-1][1];<br> }<br> } else if (dx < 0) {<br> if (ax > ay) {<br> h = out[y][x+1][1] * (1 - f1) + out[y-1][x+1][1] * f1;<br> } else if (ax < ay) {<br> h = out[y-1][x][1] * (1 - f2) + out[y-1][x+1][1] * f2;<br> } else {<br> h = out[y-1][x+1][1];<br> }<br> } else { // dx == 0<br> h = out[y-1][x][1];<br> }<br> } else if (dy < 0) {<br> if (dx > 0) {<br> if (ax > ay) {<br> h = out[y][x-1][1] * (1 - f1) + out[y+1][x-1][1] * f1;<br> } else if (ax < ay) {<br> h = out[y+1][x][1] * (1 - f2) + out[y+1][x-1][1] * f2;<br> } else {<br> h = out[y+1][x-1][1];<br> }<br> } else if (dx < 0) {<br> if (ax > ay) {<br> h = out[y][x+1][1] * (1 - f1) + out[y+1][x+1][1] * f1;<br> } else if (ax < ay) {<br> h = out[y+1][x][1] * (1 - f2) + out[y+1][x+1][1] * f2;<br> } else {<br> h = out[y+1][x+1][1];<br> }<br> } else { // dx == 0<br> h = out[y+1][x][1];<br> }<br> } else { // dy == 0<br> if (dx > 0) {<br> h = out[y][x-1][1];<br> } else if (dx < 0) {<br> h = out[y][x+1][1];<br> } else { // dx == 0 -- this cant ever happen<br> h = out[y][x][1];<br> }<br> }<br><br> return h;<br> }<br><br> function flood_fill() {<br><br> while (stack.length) {<br><br> var a = stack.shift();<br> var x = a[0];<br> var y = a[1];<br> var dx = a[2];<br> var dy = a[3];<br> var str = a[4];<br> var rng = a[5];<br> var dist = Math.sqrt(dx*dx + dy*dy);<br><br> if (out[y][x][0] == 0) {<br> out[y][x][0] = 1;<br> out[y][x][1] = Math.max(get_hgt(a), map[y][x]);<br> if (dist <= rng && map[y][x] + 0.25 >= out[y][x][1])<br> out[y][x][2] += str * (rng-dist*0.75) / rng;<br> }<br><br> if (dist < rng) {<br> if (x < 10) {<br> if (out[y][x+1][0] == 0) {<br> var b = new Array()<br> for (i=0;i<a.length;i++) b<span style="font-weight:bold;"> = a<span style="font-weight:bold;">;<br> b[0]++;<br> b[2]++;<br> stack.push(b);<br> }<br> }<br> if (x > 0) {<br> if (out[y][x-1][0] == 0) {<br> var b = new Array()<br> for (i=0;i<a.length;i++) b<span style="font-weight:bold;"> = a<span style="font-weight:bold;">;<br> b[0]--;<br> b[2]--;<br> stack.push(b);<br> }<br> }<br> if (y < 10) {<br> if (out[y+1][x][0] == 0) {<br> var b = new Array()<br> for (i=0;i<a.length;i++) b<span style="font-weight:bold;"> = a<span style="font-weight:bold;">;<br> b[1]++;<br> b[3]++;<br> stack.push(b);<br> }<br> }<br> if (y > 0) {<br> if (out[y-1][x][0] == 0) {<br> var b = new Array()<br> for (i=0;i<a.length;i++) b<span style="font-weight:bold;"> = a<span style="font-weight:bold;">;<br> b[1]--;<br> b[3]--;<br> stack.push(b);<br> }<br> }<br> }<br> }<br> }<br><br> for (y = 0; y <= 10; y++)<br> for (x = 0; x <= 10; x++)<br> out[y][x][0] = 0;<br><br> // sx,sy, dx,dy, str,rng<br> var a = [4,5,0,0,5,4];<br> stack.push(a);<br><br> flood_fill();<br><br> for (y = 0; y <= 10; y++)<br> for (x = 0; x <= 10; x++)<br> out[y][x][0] = 0;<br><br> // sx,sy, dx,dy, str,rng<br> var b = [6,5,0,0,4,3];<br> stack.push(b);<br><br> flood_fill();<br><br> var dump = '<pre><u> 0 1 2 3 4 5 6 7 8 9 10</u>\n';<br> for (y = 0; y <= 10; y++) {<br> dump += ' ' + (y < 10 ? ' ' : '''') + y;<br> for (x = 0; x <= 10; x++) {<br> if (y == 5 && (x == 4 || x == 6))<br> dump += '<font color="red">'+format(out[y][x][1])+'</font>';<br> else<br> dump += format(out[y][x][1]);<br> }<br> dump += '\n<u> ';<br> for (x = 0; x <= 10; x++) {<br> if (y == 5 && (x == 4 || x == 6))<br> dump += '<font color="red">'+format(out[y][x][2])+'</font>';<br> else<br> dump += format(out[y][x][2]);<br> }<br> dump += '</u>\n';<br> }<br> dump += '</pre>';<br><br> var output = document.getElementById('output');<br> output.innerHTML = dump;<br>}<br><br></script><br></head><br><body onload='doit();'><br><div id='output'></div><br></body><br></html><br></pre><br><br><!--EDIT--><span class=editedby><!--/EDIT-->[Edited by - ID Merlin on October 31, 2007 2:27:44 PM]<!--EDIT--></span><!--/EDIT-->