I use my own library for a lot of stuff, and recently I decided to add gradient functionality, but I've encountered a problem that I seem to remember having a while ago also, and this is the matter of my gradient being slightly off near the end. First, the code in question:
gradient = function(l, g)
{
var r = [], s = [], f = g.length - 1;
for (var x = 0; x < g.length; x++)
g[x] = (typeof(g[x]) == 'string' ? g[x] : g[x].join(','))._replace(['#', ' ', 'rgb(', ')'], ''),
g[x] = (g[x].indexOf(',') != -1
? g[x].split(',')
: g[x].chunk(2).map(function(_)
{
return _.fromBase('hex');
}));
for (var x = 0; x < f; x++)
s[x] = [(g[x][0] - g[x + 1][0]) / (l - 1) * f, (g[x][1] - g[x + 1][2]) / (l - 1) * f, (g[x][2] - g[x + 1][2]) / (l - 1) * f];
for (var x = 0; x < l; x++)
r[x] = '', ([0, 1, 2]).map(function(_)
{
var c = Math.floor(x / (l / (g.length - 1)));
r[x] += (g[c][_] - s[c][_] * (x - (l / (g.length - 1)) * c)).toBase('hex').pad('0', 2);
});
return r;
};
And, of course, my library: http://wimg.co.uk/HJ0X8B.js
Have fun in there! : ) If you think you might be able to help in any way at all, the custom functions I use in the gradient snippet are _replace(), chunk(), map(), and toBase() and fromBase()... as you'll be able to see at this demo page, everything pretty much works (at least in Opera and Firefox) save for the gradient being ever so slightly off at the end (hover to be shown the hex value). For example, calling gradient(50, ['ffffff', 'ffff00', '00ff00']) does indeed create an array of length fifty that contains hexadecimal color values gradually shifting from red to yellow and then to lime, however the last color isn't exactly lime (in this case, it comes out 05ff00); this means that there's something slightly off in the mathematics and not the methodology.
So... anybody willing to wade through the jungle that is the code I find so strangely beautiful to help me arrive at a solution? All assistance is greatly appreciated.
gradient = function(l, g)
{
var r = [], s = [], f = g.length - 1;
for (var x = 0; x < g.length; x++)
g[x] = (typeof(g[x]) == 'string' ? g[x] : g[x].join(','))._replace(['#', ' ', 'rgb(', ')'], ''),
g[x] = (g[x].indexOf(',') != -1
? g[x].split(',')
: g[x].chunk(2).map(function(_)
{
return _.fromBase('hex');
}));
for (var x = 0; x < f; x++)
s[x] = [(g[x][0] - g[x + 1][0]) / (l - 1) * f, (g[x][1] - g[x + 1][1]) / (l - 1) * f, (g[x][2] - g[x + 1][2]) / (l - 1) * f];
for (var x = 0; x < l; x++)
r[x] = '', ([0, 1, 2]).map(function(_)
{
var c = Math.floor(x / (l / (g.length - 1)));
r[x] += (g[c][_] - s[c][_] * (x - ((l-1) / (g.length - 1)) * c)).toBase('hex').pad('0', 2);
});
return r;
};
Use (l-1) instead of l on the last calculation line since you have prepared the s array for l-1 steps not l.
BTW your code is really hard to understand, try to write more understandable and standart code. And do write for loops instead of [0, 1, 2].map(sth).
Related
https://jsfiddle.net/2L4t9saq/180/ is my fiddle
most of the code is just useless, ill just post the stuff that matters
var baseConverter = function(r, e, n) {
var o = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (e <= 0 || e > o.length || n <= 0 || n > o.length) return console.log("Base unallowed"), null;
var l, t = 0;
if (10 != e) {
var a = r.length;
for (l = 0; l < a; l++) {
var u, f = -1;
for (u = 0; u < o.length; u++)
if (r[l] == o[u]) {
f = 1;
break
}
if (u >= e) return console.log("Symbol unallowed in baseform"), null;
if (-1 == f) return console.log("Symbol not found"), null;
var s = a - l - 1;
t += 0 == s ? u : u * Math.pow(e, s)
}
} else t = parseInt(r);
if (10 != n) {
for (var g = []; t > 0;) {
var i = t % n;
if (i < 0 || i >= o.length) return console.log("Out of bounds error"), null;
g.push(o[i]), t = parseInt(t / n)
}
return g.reverse().toString().replace(/,/g, "")
}
return t.toString()
}
var b36torgba = function(input) {
for (var i = 1; i < (input.length / 8) + 1; i++) {
var arr = input
var r = arr.charAt[0 + (i - 1) * 8] + "" + arr.charAt[1 + (i - 1) * 8]
var g = arr.charAt[2 + (i - 1) * 8] + "" + arr.charAt[3 + (i - 1) * 8]
console.log(g.charAt[2])
var b = arr.charAt[4 + (i - 1) * 8] + "" + arr.charAt[5 + (i - 1) * 8]
console.log(b)
var a = arr.charAt[6 + (i - 1) * 8] + "" + arr.charAt[7 + (i - 1) * 8]
console.log(a)
var rrgba = baseConverter(r, 36, 10)
var grgba = baseConverter(r, 36, 10)
var brgba = baseConverter(r, 36, 10)
var argba = baseConverter(r, 36, 10)
var bigMessOfAVariable = "rgba(" + rrgba + "," + grgba + "," + brgba + "," + argba + "),"
return bigMessOfAVariable;
}
}
you can ignore the top function, all it is is a base converter script, that takes in three inputs, an input, the base its in, and the base it should be converted to: eg baseConverter(73,36,10) will output 255.
now, the problem is with my b36torgba function.
it will take in a string, which is guaranteed to have a length that is either 0, 8, or a multiple of 8, this is just standardization to make sure everything runs smoothly, without having 700 indexOf[] functions.
it takes in the input, and divides it by 8, this tells the function how many bytes it has to go through, and how many it will spit out, so a string "[7300002S7300002S]" should (divided by 8) output 2, therefore the script runs 2 iterations.
currently, it should be taking in the string, and assigning each group of 2 characters (again standard) to a specific variable, this will allow it to all be put in the end and outputted as the same string but in base 10 rgba (hence 73 being use, 73 in base 36 is 255), but before it can do any of that, it breaks when it tries to find the characters in a string, saying this syntax error:
Uncaught TypeError: Cannot read property '0' of undefined
at b36torgba ((index):40)
at window.onload ((index):55)
why does it break as soon as it tries to feed the string into my charAt()'s?
ps: i do understand that the code in its current state, if it worked, it'd only output the rgba value of the last 8 characters
Easy mistake. You're using charAt (which is a function) by doing charAt[index] (using square brackets), rather than charAt(index) (using round brackets). Fixing that up should solve your issue.
Also - you're calling the function by doing b36torgba(["7300002S7300002S"]) in your JSFiddle, and trying to do string manipulation on it. Since ["7300002S7300002S"] is an array, not a string, .charAt() won't work on it. Try calling the function by doing b36torgba("7300002S7300002S") instead.
I love this JS Parallax technique used in this website
https://www.beamland.com/
Based on scrolling a set div, change in css VH, showing what is under.
I am trying to reproduce something similar, but I am failing to get the formula of calculating the height of the visible screen vs the scroll, vs the whole height of the document.
So I digged under the hood of that website, but I am not understanding what kind of calculation is being done to achieve the effect.
BEAM.initParallax = function() {
function a() {
var a = q - 1,
b = a / j,
c = Math.ceil(b),
d = 100 - a % j / j * 100 + "vh",
e = 100 * b + 4e3 / j + "vh";
r = !1, "Mobile Safari" !== h.browser.name && "Android" !== h.os.name || (e = a + 30 + "px"), c < 1 && (c = 1), a % j === 0 && a > 0 && c++;
for (var f = 0; f < m.length; f++) f + 1 > c ? m[f].style.height = "100vh" : f - 1 < c && (m[f].style.height = "0vh");
m[c - 1] && (m[c - 1].style.height = d), o.removeClass("is-active"), $(o[c - 1]).addClass("is-active"), b < s ? (l.removeAttr("style").addClass("stuck"), n.removeClass("faded")) : l[0].hasAttribute("style") || (n.addClass("faded"), l.removeClass("stuck").css("top", e))
}
function b() {
if (s = 3.887, k <= 1024) {
s = 3.915;
var a = Math.abs(j - document.getElementsByClassName("Parallax-spacer")[0].style.height);
$(".Parallax-spacer").css("height", j + "px"), a > 20 && Math.ceil((q - 1) / j) >= 4 && (p < q && (a *= -1), window.scrollTo(0, q - 4 * a))
}
}
function c() {
return "Android" === h.os.name ? i.outerHeight() : i.innerHeight()
}
function d() {
return "Android" === h.os.name ? i.outerWidth() : i.outerWidth()
}
function e() {
p = q, q = window.scrollY, f()
}
function f() {
r || window.requestAnimationFrame(a), r = !0
}
if ($(".Parallax-Hero").length) {
var g = new UAParser,
h = g.getResult(),
i = $(window),
j = c(h),
k = d(h),
l = $("div.Nav-Main"),
m = $(".Parallax-panel"),
n = $(".Parallax-wayfinder"),
o = n.find(".Parallax-pagination--dot"),
p = 0,
q = 0,
r = !1,
s = 0;
b(), $(".Parallax-pagination--dot").on("mouseup touchend", function(a) {
a.preventDefault();
var b = $(".Parallax-pagination--dot").index(this),
c = b * j + 1;
$("html, body").animate({
scrollTop: c + "px"
}, 500)
}), i.on("scroll", function() {
e()
}), i.on("resize", function() {
j = c(h), k = d(h), b(), e()
}), window.requestAnimationFrame(a)
}
I even looked at various other parallax and code effect on codepen, but I don't find something similar to this effect, to understand the calculation.
Can someone help me to unveil the logic? Thank you
This is a minified code. For development purposes, you better rename the variables so you could read easily.
m = $(".Parallax-panel"),
becomes:
parallaxPanel = $(".Parallax-panel"),
then
m.length
is
parallaxPanel.length
q = window.scrollY
becomes
windowScrollY = window.scrollY
then
a = windowScrollY - 1;
j = c(h),
becomes
windowHeight = c(h),
Try this ad see if you could understend better.
Update:
The reason I suggested this naming convention is for you to understand these calculations better.
b = a / j;
This is not clear, but:
b = (windowScrollY - 1) / windowHeight;
is more obvious. window.ScrollY is the number of pixels the document is currently scrolled vertically from the origin. window.outerHeight is window's height.
c = Math.ceil(b);
b is float so now c is an integer.
d = 100 - a % j / j * 100 + "vh";
d = 100 - (windowScrollY - 1) % windowHeight / windowHeight * 100 + "vh";
This gives percentage scrolled.
I won't be able to decode it all for you. You should have math and programming knowledge to do it.
What I'm doing: I'm developing a mobile dictionary app for a number of languages
How I'm doing it: Using ionic framework with combination of some angular and some pure js (imported from a working online dictionary site of the same languages)
The problem: Our search function is an approximate search that uses a Levenstein distance calculator to rank all entries in the dictionary with respect to the query form. When the dictionary has up to 1,500 words, this isn't a problem at all on phones, but when the dictionary has around 10,000 words, there is about a 5-8 second delay before results are shown, despite it being instantaneous on a web browser using "ionic serve". When I run firebug, the javascript that takes the longest time to process are the distance calculations, so my working assumption is that this is where I should start, but I'm open to any suggestions at all.
Here's the distance calculator:
/**
* editDistance.js
*
* A simple Levenshtein distance calculator, except weighted such
* that insertions at the beginning and deletions at the end cost less.
*
* AUTHOR: Pat Littell
* LAST UPDATED: 2015-05-16
*/
var distanceCalculator = {
insertionCost : 1.0,
deletionCost : 1.0,
insertionAtBeginningCost : 0.11,
deletionAtEndCost : 0.1,
substitutionCost : 1.0,
getEditDistance : function(a, b) {
if(a.length === 0) return b.length;
if(b.length === 0) return a.length;
var matrix = [];
// var currentInsertionCost, currentDeletionCost, currentSubstitutionCost = 0;
// increment along the first column of each row
var i;
for(i = 0; i <= b.length; i++){
matrix[i] = [i * this.insertionAtBeginningCost];
}
// increment each column in the first row
var j;
for(j = 0; j <= a.length; j++){
matrix[0][j] = j;
}
// Fill in the rest of the matrix
for(i = 1; i <= b.length; i++){
for(j = 1; j <= a.length; j++){
currentInsertionCost = matrix[i][j-1] + this.insertionCost;
currentSubstitutionCost = matrix[i-1][j-1] + (b.charAt(i-1) != a.charAt(j-1) ? this.substitutionCost : 0);
currentDeletionCost = matrix[i-1][j] + (j==a.length ? this.deletionAtEndCost : this.deletionCost);
matrix[i][j] = Math.min(currentSubstitutionCost, Math.min(currentInsertionCost, currentDeletionCost));
}
}
return matrix[b.length][a.length];
},
// Given a query <a> and a series of targets <bs>, return the least distance to any target
getLeastEditDistance : function(a, bs) {
var that = this;
return Math.min.apply(null, bs.map(function(b) {
return that.getEditDistance(a,b);
}));
}
}
First of all, if you have a known dictionary you will get the fastest solution with something like a Levenshtein Automata, which will solve this in linear time to get all candidates. You can't beat this with a general purpose implementation.
With that said, this implementation of levenshtein distance is a few times faster than yours.
function distance(s, t) {
if (s === t) {
return 0;
}
var n = s.length, m = t.length;
if (n === 0 || m === 0) {
return n + m;
}
var x = 0, y, py, a, b, c, d, e, f, k;
var p = new Array(n);
for (y = 0; y < n;) {
p[y] = ++y;
}
for (; (x + 3) < m; x += 4) {
var tx0 = t.charCodeAt(x);
var tx1 = t.charCodeAt(x + 1);
var tx2 = t.charCodeAt(x + 2);
var tx3 = t.charCodeAt(x + 3);
a = x;
b = x + 1;
c = x + 2;
d = x + 3;
e = x + 4;
for (y = 0; y < n; y++) {
k = s.charCodeAt(y);
py = p[y];
if (py < a || b < a) {
a = (py > b ? b + 1 : py + 1);
}
else {
if (tx0 !== k) {
a++;
}
}
if (a < b || c < b) {
b = (a > c ? c + 1 : a + 1);
}
else {
if (tx1 !== k) {
b++;
}
}
if (b < c || d < c) {
c = (b > d ? d + 1 : b + 1);
}
else {
if (tx2 !== k) {
c++;
}
}
if (c < d || e < d) {
d = (c > e ? e + 1 : c + 1);
}
else {
if (tx3 !== k) {
d++;
}
}
p[y] = e = d;
d = c;
c = b;
b = a;
a = py;
}
}
for (; x < m;) {
tx0 = t.charCodeAt(x);
a = x;
b = ++x;
for (y = 0; y < n; y++) {
py = p[y];
if (py < a || b < a) {
b = (py > b ? b + 1 : py + 1);
}
else {
if (tx0 !== s.charCodeAt(y)) {
b = a + 1;
}
else {
b = a;
}
}
p[y] = b;
a = py;
}
f = b;
}
return f;
}
I would also not use map in getLeastEditDistance, it is very slow. Just use a normal loop. Also Math.min with many arguments is not very performant.
I am working with Levenstein distances by my self and I have not found a good way to improve performance and will not recommend using it in a non-batch application.
I suggest you use another approach by using a search tree. A binary or ternary search tree can also find near match.
A good place to start is those articles:
http://www.codeproject.com/Articles/5819/Ternary-Search-Tree-Dictionary-in-C-Faster-String
or
http://www.codeproject.com/Articles/68500/Balanced-Binary-Search-Tree-BST-Search-Delete-InOr
The code is relatively simple sp you should not use much time to port it to JavaScript.
function getAnswer(){
var answer, c = 334;
while (c < 999){
var a = Math.round(((1000 - c) / 2) - 0.5), b = Math.round((1000 - c) / 2);
while (a > 0 && b < c){
if (Math.pow(a, 2) + Math.pow(b, 2) != Math.pow(c, 2)){
a -= 1;
b += 1;
}else{
answer = a * b * c;
}
}
c += 1;
}
document.getElementById("a").innerHTML = answer;
}
Hi! I am a beginner programmer in javascript, and I have been trying to solve problem 9 in Project Euler. That problem goes like this:
A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,
a^2 + b^2 = c^2
For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2.
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.
I don't know why no answer appears, and my script crashes/program stops running, whenever I run this script. Please explain and tell me what's wrong with my script.
When you have found the answer, you don't stop with the iteration. Even worse, you don't change the values of a and b any more, so they never reach the end of the iteration, and you're stuck in an infinite loop.
You'll need to break out of the loop when you've found the answer. Or even break out of both your nested loops, using a label:
function getAnswer() {
var answer,
c = 334;
find: while (c < 999) {
var a = Math.round(((1000 - c) / 2) - 0.5),
b = Math.round((1000 - c) / 2);
while (a > 0 && b < c) {
if (Math.pow(a, 2) + Math.pow(b, 2) == Math.pow(c, 2)) {
answer = a * b * c;
break find;
}
a -= 1;
b += 1;
}
c += 1;
}
document.getElementById("a").innerHTML = answer;
}
Notice that it would be easier if your function just returned the answer, instead of populating #a with it. You'd call it like
document.getElementById("a").innerHTML = getAnswer();
and can just return a * b * c; to break out of the whole function.
Hy,
I am trying to implement an Connect Four Game in javascript / jQuery. First off this is no homework or any other duty. I'm just trying to push my abilities.
My "playground" is a simple html table which has 7 rows and 6 columns.
But now I have reached my ken. I'm stuck with the main functionality of checking whether there are 4 same td's around. I am adding a class to determine which color it should represent in the game.
First I thought I could handle this with .nextAll() and .prevAll() but this does not work for me because there is no detection between.
Because I was searching for siblings, when adding a new Item and just looked up the length of siblings which were found and if they matched 4 in the end I supposed this was right, but no its not :D Is there maybe any kind of directNext() which provides all next with a css selector until something different comes up ?
I will put all of my code into this jsfiddle: http://jsfiddle.net/LcUVf/5/
Maybe somebody has ever tried the same or someone comes up with a good idea I'm not asking anybody to do or finish my code. I just want to get hints for implementing such an algorithm or examples how it could be solved !
Thanks in anyway !
DOM traversal is not particularly efficient so, when you can avoid it, I'd recommend doing so. It'd make sense for you to build this as a 2D array to store and update the state of the game. The table would only be a visual representation of the array.
I know that, normally, you would build the array with rows as the first dimension and columns as the second dimension but, for the purposes of being able to add pieces to each column's "stack," I would make the first dimension the columns and the second dimension the rows.
To do the check, take a look at this fiddle I made:
http://jsfiddle.net/Koviko/4dTyw/
There are 4 directions to check: North-South, East-West, Northeast-Southwest, and Southeast-Northwest. This can be represented as objects with the delta defined for X and Y:
directions = [
{ x: 0, y: 1 }, // North-South
{ x: 1, y: 0 }, // East-West
{ x: 1, y: 1 }, // Northeast-Southwest
{ x: 1, y: -1 } // Southeast-Northwest
];
Then, loop through that object and loop through your "table" starting at the farthest bounds that this piece can possibly contribute to a win. So, since you need 4 pieces in a row, the currently placed piece can contribute in a win for up to 3 pieces in any direction.
minX = Math.min(Math.max(placedX - (3 * directions[i].x), 0), pieces.length - 1);
minY = Math.min(Math.max(placedY - (3 * directions[i].y), 0), pieces[0].length - 1);
maxX = Math.max(Math.min(placedX + (3 * directions[i].x), pieces.length - 1), 0);
maxY = Math.max(Math.min(placedY + (3 * directions[i].y), pieces[0].length - 1), 0);
To avoid any issues with less-than and greater-than (which I ran into), calculate the number of steps before looping through your pieces instead of using the calculated bounds as your conditions.
steps = Math.max(Math.abs(maxX - minX), Math.abs(maxY - minY));
Finally, loop through the items keeping a count of consecutive pieces that match the piece that was placed last.
function isVictory(pieces, placedX, placedY) {
var i, j, x, y, maxX, maxY, steps, count = 0,
directions = [
{ x: 0, y: 1 }, // North-South
{ x: 1, y: 0 }, // East-West
{ x: 1, y: 1 }, // Northeast-Southwest
{ x: 1, y: -1 } // Southeast-Northwest
];
// Check all directions
outerloop:
for (i = 0; i < directions.length; i++, count = 0) {
// Set up bounds to go 3 pieces forward and backward
x = Math.min(Math.max(placedX - (3 * directions[i].x), 0), pieces.length - 1);
y = Math.min(Math.max(placedY - (3 * directions[i].y), 0), pieces[0].length - 1);
maxX = Math.max(Math.min(placedX + (3 * directions[i].x), pieces.length - 1), 0);
maxY = Math.max(Math.min(placedY + (3 * directions[i].y), pieces[0].length - 1), 0);
steps = Math.max(Math.abs(maxX - x), Math.abs(maxY - y));
for (j = 0; j < steps; j++, x += directions[i].x, y += directions[i].y) {
if (pieces[x][y] == pieces[placedX][placedY]) {
// Increase count
if (++count >= 4) {
break outerloop;
}
} else {
// Reset count
count = 0;
}
}
}
return count >= 4;
}
I released a fully working version of the game on Github.
It implements an optimised variation on the algorythm Sirko mentioned.
To avoid any unnecessary redunancy, the algorythm directly checks the DOM rather than a JS table. As that algorythm requires a minimum amount of checks, the performance overhead for accessing the DOM is neglectable.
The current player and a flag for keeping track of whether the game has ended are basicly the only statuses stored in the JS itself.
I even used the DOM to store strings. It has no external dependencies and is supported by all versions of IE from IE6 upwards as well as modern browsers.
Code is optimised for filesize and performance. The latest version also includes animation, even though the total JS code of the game is still only 1.216 bytes after minification.
The Code :
Here's the full, un-minified JS code :
(function (doc, win, onclick, gid, classname, content, showMessage) {
var
a, b, c, colorLabel, cid, players, current, finished, newgameLabel, wonLabel, laststart = 1,
cellAt = function (i, j) {
return doc[gid](cid + i + j);
},
isCurrentColor = function (i, j) {
return cellAt(i, j)[classname] === players[current];
},
start = function () {
current = laststart = (laststart + 1) % 2;
finished = 0;
colorLabel[content] = colorLabel[classname] = players[current = (current + 1) % 2];
for (a = 1; a < 7; a++)
for (b = 1; b < 8; b++)
cellAt(a, b)[classname] = '';
},
makeMove = function (i, j, s) {
s > 0 && (cellAt(s, j)[classname] = '');
cellAt(s + 1, j)[classname] = players[current];
s === i - 1 ? function (i, j) {
return function (i, j) {
for (a = j - 1; 0 < a && isCurrentColor(i, a); a--) {
}
for (b = j + 1; 8 > b && isCurrentColor(i, b); b++) {
}
return 4 < b - a;
}(i, j) || function (i, j) {
for (c = i + 1; 7 > c && isCurrentColor(c, j); c++) {
}
return 3 < c - i;
}(i, j) || function (i, j) {
for (a = i - 1, b = j - 1; 0 < a && !(1 > b) && isCurrentColor(a, b); a--)
b--;
for (c = i + 1, b = j + 1; 7 > c && !(7 < b) && isCurrentColor(c, b); c++)
b++;
return 4 < c - a
}(i, j) || function (i, j) {
for (a = i - 1, b = j + 1; 0 < a && !(7 < b) && isCurrentColor(a, b); a--)
b++;
for (c = i + 1, b = j - 1; 7 > c && !(1 > b) && isCurrentColor(c, b); c++)
b--;
return 4 < c - a;
}(i, j);
}(i, j)
? finished = 1 && win[showMessage](doc[gid](wonLabel)[content].replace("%s", players[current].toLowerCase())) && start()
: colorLabel[content] = colorLabel[classname] = players[current = (current + 1) % 2]
: setTimeout(function () {
makeMove(i, j, s + 1)
}, 20);
};
return function (n, w, c, h, p1, p2) {
cid = c;
newgameLabel = n;
wonLabel = w;
colorLabel = doc[gid](c);
players = [doc[gid](p1)[content], doc[gid](p2)[content]];
for (a = 1; a < 7; a++)
for (b = 1; b < 8; b++)
cellAt(a, b)[onclick] = function (b, a) {
return function () {
if (!finished)
for (a = 6; a > 0; a--)
if (!cellAt(a, b)[classname]) {
makeMove(a, b, 0);
break;
}
};
}(b);
;
doc[gid](h)[onclick] = function () {
win[showMessage](doc[gid](newgameLabel)[content]) && start()
};
start();
};
})(document, window, "onclick", "getElementById", "className", "innerHTML", "confirm")("newgame", "won", "color", "restart", "p1", "p2");
A screenshot :
In general a 2dimensional array would be better suited for checking for a line of 4. You could then do something like the following:
function check( lastPiece, playground, player ) {
// check length in each direction
var l = 1,
i = 1;
// top to bottom
while( (playground[ lastPiece.x ][ lastPiece.y - i ] === player) && ((lastPiece.y - i) >= 0) ) { l += 1; i += 1; };
i = 1;
while( (playground[ lastPiece.x ][ lastPiece.y + i ] === player) && ((lastPiece.y + i) <= MAX_Y) ) { l += 1; i += 1; };
if ( l >= 4 ) { return true; }
// left to right
l = 1;
while( (playground[ lastPiece.x - i][ lastPiece.y ] === player) && ((lastPiece.x - i) >= 0) ) { l += 1; i += 1; };
i = 1;
while( (playground[ lastPiece.x + i][ lastPiece.y ] === player) && ((lastPiece.x + i) <= MAX_X) ) { l += 1; i += 1; };
if ( l >= 4 ) { return true; }
// same for top left to bottom right and bottom left to top right
// . . .
// if we got no hit until here, there is no row of 4
return false;
}
EDIT: added checks for borders of the playground