For Loop is starting at the wrong number - javascript

For some reason the second for loop is starting at 1. I do realize that first for loop i starts at one. That's is meant to be. However, even though j for loop says to start at 0, it starts at 1 anyways.
var findWinners = function (playersRay) {
var players = playersRay;
var results = new Array();
//getdealers dealers hand and info
var dealerHand = players[0]
var dealerScore = dealerHand.getScore()
var dealerBust = dealerScore > 21 ? true : false;
//loops through all players; skips dealer (array position 0)
var numPlayers = players.length;
for (var i=1; i<numPlayers; i++) {
//loops through all the players hands.
//player might have more than 1 hand if he splits his cards
var player = players[i];
var numHands = player.length;
results[i] = new Array();
for (var j=0; j<numHands; j++)
var handScore = player[j].getScore();
if (handScore > 21) {
results[i][j] = false;
}
else if (dealerScore > 21) {
results[i][j] = true;
}
else if (handScore > dealerScore) {
results[i][j] = true;
}
else {
results[i][j] = false;
}
}
return results;
}
It returns this: [undefined, [undefined, true]]
It should return this: [undefined, [true]]
Just in case you want to know. A sample playersRay is: [Object, [Object]]
The object has information about the dealer's or player's blackjack hand.
Link to full code: https://docs.google.com/open?id=0BxvwY0fUFc3aMTdTOXU0b0ttamM

In Javascript, when you omit the curly braces around a statement, it only runs the first line. The behavior appears to omit only the first index, when I suspect there's only two. So if you add some more to iterate, you should notice it's actually just running the last index.
For example:
for (var i = 0; i < 10; i++)
console.log('First line: ', i);
console.log('Second line: ', i);
http://jsfiddle.net/MMQD8/
Gives:
First line: 0
First line: 1
First line: 2
First line: 3
First line: 4
First line: 5
First line: 6
First line: 7
First line: 8
First line: 9
Second line: 10
MDN explains it thusly:
statement
A statement that is executed as long as the condition
evaluates to true. To execute multiple statements within the loop, use a block
statement ({ ... }) to group those statements.

Related

Passing hands of cards around a table in Javascript

This seems like a stupidly simple thing to do, but I can't figure out what I'm doing wrong. The goal is to have an array of 8 other arrays, which each contain hands of cards (in the example, the arrays just contain arbitrary numbers). Then, depending on whether passDirection is set to -1 or 1, each array is cycled through and replaced with the one next to it. The desired end result is that the values of playerList essentially shift by 1 either up or down, and this can be repeated several times without issue.
What's actually happening with the code I have below, though, is that all the arrays are just being replaced with what's at index 0, except for the first one. How can I fix this?
var playerList = new Array;
var passDirection = -1;
for(i = 0; i < 8; i++) {
playerList.push([playerList.length,i]); // Fill Arrays with arbitrary data
}
for (i=0; i< playerList.length; i++) {
console.log(i + ": " + playerList[i]); // Check their values before anything is done to them
}
for(q=0; q < 5; q++){ // Repeat the process 5 times, just because.
var bufferArray = playerList[0]; // Put Array Element 0's value in a buffer as it will be replaced first
for(i = 0; i < playerList.length && i > (playerList.length * -1); i += passDirection) {
var catcher = i; // 'catcher' should be the array that gets replaced
var passer = catcher - passDirection; // 'passer' should be the one it gets replaced with
if (catcher < 0) {
catcher = catcher + playerList.length;
}
if (passer < 0) {
passer = passer + playerList.length;
} else if (passer >= playerList.length) {
passer = passer - playerList.length;
}
if (passer == 0) {
playerList[catcher] = bufferArray;
} else {
playerList[catcher] = playerList[passer];
}
}
for (i=0; i< playerList.length; i++) {
console.log(i + ": " + playerList[i]);
}
console.log("...");
}
https://jsfiddle.net/3r1Lhwc5
You have two errors in your code:
if (passer = 0) is performing an assignment. You need if (passer === 0).
The passer index is looking at the wrong side of the value. Currently you are first getting from 1 and putting at 0, then getting from 0 and putting at 7 (i.e. -1). Notice how you are moving the same value in the second iteration. You need to change passer = catcher - passDirection to passer = catcher + passDirection
Note that all this can be done much easier with the splice, shift, unshift, pop and push Array methods (on the main playerList).
You can make your life easier by using Array methods to move elements from the beginning to end of an array or vice versa. Using this in the body of your for loop should do the trick:
if (passDirection === -1) {
const first = playerList.shift();
playerList.push(first);
}
else {
const last = playerList.pop();
playerList.unshift(last);
}

Why Javascript console.log result is undefined while reversing the string?

var a = "gsdgtrshghf";
function reverseString(strr){
if (!strr.length){
var result="";
for(var i=strr.length;i>0;i++){
var a=strr.chatAt(i);
result+=a;
}
}return result;
}
console.log(reverseString(a))
When I tried to run it it returned me "undefined". I wonder what's the problem here.
The main reason is you are declaring var result="" and returning from outside of if(so it become undefined as its scope is only inside if statement) and other errors areas mention in comments you have a typo, charAt not chatAt. You can also simply use strr[i] to get the char. Also, you should do i-- and i >= 0 if you start at strr.length, otherwise for loop is immediately completed at the condition check. Check the below code.
var a = "gsdgtrshghf";
function reverseString(strr){
var result="";
if (strr.length){
for(var i=strr.length-1;i>=0;i--){
var a=strr.charAt(i);
result+=a;
}
}
return result;
}
console.log(reverseString(a))
Have a look:
var a = "gsdgtrshghf";
function reverseString(strr) {
var result = "";
if (strr.length != null) {
for (var i = strr.length - 1; i >= 0; i--) {
var a = strr.charAt(i);
result += a;
}
}
return result;
}
console.log(reverseString(a));
// Better
const reverse = str => Array.from(str).reverse().join('');
console.log(reverse('foo 饾寙 bar ma帽ana man虄ana'));
Explanation
It's charAt(i) not chatAt(i)
Loop should start from length - 1 and end at 0 and i should be decremented
And finally declare the variable outside of if
i.e for(var i = strr.length - ; i >= 0; i--){
not for(var i=strr.length;i>0;i++){
Better yet, use combo of Array.from(str).reverse().join(''), as it even works with Unicode characters, as pointed out in comments by gaetanoM

Why does this loop terminate partway through?

I'm trying to write a program to find the smallest common multiple of the provided parameters that can be evenly divided by both, as well as by all sequential numbers in the range between these parameters.
The range will be an array of two numbers that will not necessarily be in numerical order.
For example, for 1 and 3 - find the smallest common multiple of both 1 and 3 that is evenly divisible by all numbers between 1 and 3.
Why does the loop stop at i = 510,000 (or something close to that) instead of 7,000,000, as I set it?
I also have a screenshot with the output:
function smallestCommons(arr) {
var start;
var finish;
var something;
if(arr[0] < arr[1]){start = arr[0]; finish = arr[1];}else{
start = arr[1]; finish = arr[0];
}
for(var i = finish;i <= 7000000;i++){
var boolea = true;
for(var j = start;j <= finish;j++){
if(i % j !== 0){boolea = false;break;} // 2 % 1
}
if(boolea)return i;
something = i;
}
console.log("final i = " + i);
return 0;
}
Try to add this at the beginning of your loop
// noprotect
it must be that jsbin is forcing your code to exit from the loop. See source

Splice NOT removing certain characters

I'm working on some codewars problems and I came to this 'remove noise thing', I guess the point is to escape backslash \ and use replace method, which was easy. But I didn't want to use replace, instead I found myself in trouble trying to remove items with splice method.
Funny thing is, when I debug in Chrome dev tools, step by step I see items get removed, but console.log spits out certain characters($/路|陋l) problematic to remove, and at the end gets returned and join with those characters. Why is that?
function removeNoise(str) {
var base = "%$&/#路#|潞\陋";
var arr = str.split('');
for(var i = 0; i < arr.length; i++) {
var item = arr[i];
var condition = base.indexOf(item);
if(condition + 1) {
//works like a charm
//arr[i] = '';
arr.splice(i,1);
//this thing wont work
//when debugging it removes the items from the array
//console log print no removing
}
}
return arr.join('');
}
removeNoise('he%$&/#路#|潞\陋\llo'); //=> $/路|陋llo
You're using splice to remove entries from your array, but you're then incrementing i for the next loop. If you remove the entry at index 5 from a 10-entry array, what was the entry at index 6 is now at index 5 (of what's now a 9-entry array), so you don't want to increment your index.
The solution is to use a while loop and only update i if you don't splice:
function removeNoise(str) {
var base = "%$&/#路#|潞\陋";
var arr = str.split('');
var i = 0;
while (i < arr.length) {
var item = arr[i];
var condition = base.indexOf(item);
if (condition + 1) {
// Remove this entry, reuse same value for 'i'
arr.splice(i,1);
} else {
// Don't remove this entry, move to next
++i;
}
}
return arr.join('');
}
var result = removeNoise('he%$&/#路#|潞\陋\llo');
var pre = document.createElement('pre');
pre.appendChild(
document.createTextNode(result)
);
document.body.appendChild(pre);
You're removing characters from your array. This will throw your indexer variable i out of sync with the characters you want to test. Easy way to fix is to start at the end of the array working your way to the beginning.
Change your for loop to this.
for(var i = arr.length -; i <= 0; i--) {
function removeNoise(str) {
var base = "%$&/#路#|潞\陋";
var arr = str.split('');
for(var i = arr.length - 1; i <= 0 ; i--) {
var item = arr[i];
if(base.indexOf(item) >= 0) {
//remove the offending character
arr.splice(i,1);
}
}
return arr.join('');
}
removeNoise('he%$&/#路#|潞\陋\llo'); //=> $/路|陋llo

Testing if an array contains any one of eight 3-key values -- Tic Tac Toe game

I'm working on a simple Tic Tac Toe game in Javascript. Right now, to check for a winner, I have a function that first gets whose turn it is and then finds wherever they have an X or an O on the board. The spaces they have are numbered (1-8) and added to an array. So far so good.
Now I'm trying to compare another array, the array with all of the winning combinations:
var winningCombinations = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7]];
with a test array, that should come up a winner as it contains 2, 5, and 8.
Source of my test:
<script>
var test = [2,4,5,8]
var winningCombinations = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7]];
for(var x=0; x<winningCombinations.length; x++) {
if (winningCombinations[x].indexOf(test) > -1) {
alert("Win!");
} else {
alert ("No win.");
}
}
</script>
I think right now it's only testing for [2,4,5,8] as an entire value--not for an instance of the individual numbers inside. This is where I'm stumped. How can I check to see if the test array, in any order, matches any of the winningCombinations values?
Try this:
var test = [2,4,5,8]
var winningCombinations = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7]];
var combLength = 0;
for (var i in winningCombinations) {
combLength = winningCombinations.length;
for (var j in winningCombinations[i]) {
if (-1 == test.indexOf(winningCombinations[i][j])) {
break;
}
}
if (combLength - 1 == j) {
alert("Win!");
}
}
in the first if statement we're checking if the currently looped item in currently looped array (seems confusing, I know) is present in the test array. If not we already know that test array is not a winning array.
Moreover, I suggest wrapping all this stuff in a function like this:
function isWinner(playerNumbers, winningCombinations) {
var combLength = 0;
for (var i in winningCombinations) {
combLength = winningCombinations.length;
for (var j in winningCombinations[i]) {
if (-1 == playerNumbers.indexOf(winningCombinations[i][j]) {
break;
}
}
if (combLength - 1 == j) {
return true;
}
}
return false;
}
var test = [2,4,5,8]
var winningCombinations = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7]];
if (isWinner(test, winningCombinations)) {
alert("Win!");
} else {
alert ("No win.");
}
You really arent checking equality, you're checking if one array is a subset of another. For this, I would recommend changing test to an object in the form {2: 1, 4: 1, 5: 1, 8: 1}. The ones are in there just to evaluate to true, they don't really matter. The important thing is the key.
function checkSubset(a, b) {
//returns true if EVERY element in the array causes the next function to return true
return a.every(function(e) {
return !!b[e]; //returns true if b contains e
});
}
Then call checkSubset(winningCombinations[x], test).
That being said, there are much better ways to evaluate the state of a tic tac toe board.
The naive method would just check every combination and make sure test contains every element of one of the combinations:
var winner = false;
for (var i = 0; i < winningCombinations.length && !winner; i++) {
var matches = true;
for(var j = 0; j < winningCombinations[i].length && matches; j++)
if(test.indexOf(winningCombinations[i][j]) == -1)
matches = false;
if(matches)
winner = true;
}
If you encapsulate these in functions and return matches and winner you can get rid of the ugly loop conditions:
function matchesCombination(test, combination)
{
for(var i = 0; i < combination.length; i++)
if(text.indexOf(combination[i]) == -1)
return false;
return true;
}
function isWinner(test, combinations)
{
for(var i = 0; i < combinations.length; i++)
if(matchesCombination(test, combinations[i])
return true;
return false;
}
It may not be the best answer, but off the top of my head you could loop through the values in the winning conditions and do an if statement that requires all 3 indexOfs to be != -1.
i.e. for each array in winning combinations, loop through each value in the array and do test.indexOf(value) and check to see that it's not -1. If all 3 values come back as not equal to -1 then you have a win condition.

Categories