Saturday, May 25, 2013

What Would You Like to Eat Today?


Oh man, it is so totally freeing not having to create those stale blog posts! Here are two more mini -games micro-games I whipped up later in the week. They're both related to food (no surprise, right?) and I think I'm really getting to master the whole choose-your-adventure-game-mode. I think it would be relatively achievable to write a storybook and have several different possible endings! How cool would that be? I also found out that it's actually pretty useful to create diagrams in a notebook before starting to code everything out. It's like drafting an essay or creating a plan so that everything makes sense and you don't have to waste time figuring those silly little details out. Ah, this is so much better and way more engaging! I hope you all give these games a try!

// here's my first version: 

var omelette = prompt("Good morning! Are you hungry for breakfast? The chickens and ducks laid a whole bunch of eggs, so we're planning to make omelettes for everyone. Do you eat meat?").toUpperCase();

switch(omelette) {
  case 'YES':
    var salmon = prompt("Do you eat fish?").toUpperCase();
    if(salmon === 'YES') {
      console.log("One smoked salmon and tomato omelette coming right up!");
    } else {
      console.log("We'll have your ham and cheese omelette plated in a jiffy!");
    }
    break;
  case 'NO':
      var dairy = prompt("Do you eat dairy?").toUpperCase();
    if(dairy === 'YES') {
      console.log("Well here's a cheesy mushroom and onion omelette... one of my favorites!");
    } else {
      console.log("Sorry, we don't have any omelettes for you!");
    }
    break;
  default:
    console.log("Say you don't like omelettes? Well we have some soggy oatmeal leftover from yesterday's brunch...");
}
     

// here's the second (and slightly more intricate) one: 

var hungry = prompt("So I see you're feeling a little hungry. Well, what time is it (BREAKFAST, LUNCH, or DINNER time)?").toUpperCase();

switch(hungry) {
  case 'BREAKFAST':
    var meat_breakfast = prompt("It's breakfast time! Do you eat meat?").toUpperCase();
    var dairy_breakfast = prompt("Do you eat dairy?").toUpperCase();
    if(meat_breakfast === 'YES' && dairy_breakfast === 'YES') {
      console.log("Have some bacon and eggs!");
    } else if(meat_breakfast === 'YES' && dairy_breakfast === 'NO') {
      console.log("Allergic to dairy? How about some sausage and hashbrowns?");
    } else if(meat_breakfast === 'NO' && dairy_breakfast === 'YES') {
      console.log("What about a tomato and spinach omelette?");
    } else {
      console.log("How about some fresh fruit?");
    }
    break;
  case 'LUNCH':
    var meat_lunch = prompt("Lunchtime! Do you eat meat?").toUpperCase();
    var dairy_lunch = prompt("What about dairy? Can you have milk? Eggs?").toUpperCase();
    if(meat_lunch === 'YES' && dairy_lunch === 'YES') {
      console.log("Alrighty, how about a ham and cheese sandwich? Does that sound good to you?");
    } else if(meat_lunch === 'YES' && dairy_lunch === 'NO') {
      console.log("Well what about just a tunafish sandwich?");
    } else if(meat_lunch === 'NO' && dairy_lunch === 'YES') {
      console.log("Grilled cheese for one! Coming right up!");
    } else {
      console.log("What about a classic PB and J sandwich? Does that sound good to you?");
    }
    break;
  case 'DINNER':
    var meat_dinner = prompt("Ah, the last and BEST meal of the day! Do you include meat in your diet?").toUpperCase();
    var dairy_dinner = prompt("How about dairy?").toUpperCase();
    if(meat_dinner === 'YES' && dairy_dinner === 'YES') {
      console.log("What about some pepperoni pizza?");
    } else if(meat_dinner === 'YES' && dairy_dinner === 'NO') {
      console.log("How about the classic spaghetti and meatballs? We'll hold the cheese, don't worry about that!");
    } else if(meat_dinner === 'NO' && dairy_dinner === 'YES') {
      console.log("In the mood for mac and cheese! I know I am!");
    } else {
      console.log("Well in that case, what about a nice refreshing kale salad?");
    }
    break;
  default:
    console.log("Hmm... you sure you're hungry?");
}


P.S. I started using canv.as and it is so freaking fun. Here's my page.

ZOMBIE SUSHI ATTACK


I originally wanted to blog about another assignment from Codeacademy and title it J.S. Project : Choose Your Own Adventure Part 2!  I had even planned to mimic the same written format--which had set the tone in all the twenty posts preceding this one. Even though this formulaic composition had initially seemed effective in helping me review all the new concepts, the procedure quickly became a drag and I soon felt like blogging these assignments became more of a drudgery than a fun way to imbibe all this new material. 

However I was determined to continue this habit, perhaps subconsciously fearing that if I stopped posting on a semi-regular basis, it would seem like I wasn't really making much progress. I measured my progress to the number of posts I churned out--whether or not the quality of content each had possessed. This once interactive learning method soon became a mindless conversion of text from one window to another and I was fooling myself, until Monday... when I couldn't find my keys. You see, during the day I am the only person at home so not being able to locate my keys essentially means, not being able to go outside. Frustrated that I couldn't go on my daily jog or run by the local grocery store to grab some food, I was stuck here... Trapped... With this pain of this assignment looming over my head. So I bit the bullet and took a look at this one assignment and decided to give it a go...NOT thinking about this blog, NOT thinking about putting the instructor's words into my own and creating a teaching post, but to just work directly with the code itself. A few days ago, I stumbled upon this "open source collaborative web development debugging tool" and it was the key to my problem! I studied the code provided from Codeacademy and wrote my own--incorporating my adventures of working at a hostess at a sushi bar. 

This is my code, and you can even demo it right here

var zombie_sushi = prompt("OH NO! The bucket of plutonium got all over the sushi and now they've turned into brain-craving zombies! Do you SLAY them, EAT them, or RUN?").toUpperCase(); 

switch(zombie_sushi) {
  case 'SLAY': 
    var macho = prompt("So, you consider yourself macho? (YES or NO)?").toUpperCase(); 
    var buff = prompt("Let's see if those burpees did anything to your level of fitness! You think you're ready?").toUpperCase();
    if(macho === 'YES' || buff === 'YES') {
      console.log("You only need one of the two! You massacred all the zombie sushi! Good job, bro!");
    } else {
      console.log("You're not macho OR buff? Sucks for you, probably should have worked on those squats a little more. You died!");
    }
    break; 
  case 'EAT': 
    var soy_sauce = prompt("All right, I guess you can try to defeat them this way... Eeeurgh. Got your soy sauce packets (YES or NO)?").toUpperCase(); 
    var wasabi = prompt("Hold on a minute, dude. You've got your green glob of wasabi with you, right?").toUpperCase(); 
    if(soy_sauce === 'YES' && wasabi === 'YES') {
      console.log("Woohoo! You've defeated the zombie sushi, hopefully you won't get a bellyache later on!"); 
    } else { 
      console.log("Dang! You can only use the magical combination of soy sauce and wasabi together! Not on their own. Sorry man, but you're dead!");
    }
    break;
  case 'RUN': 
    var speedy = prompt("Come on, let's get a move on! You're fast, right?").toUpperCase(); 
    var rollerblades = prompt("Wait, you have rollerblades in your backpack?").toUpperCase(); 
    if(speedy === 'YES' || rollerblades === 'YES') {
      console.log("Bam, you got away! You live to see another glimpse of the sunlight.");
    } else {
      console.log("Oh no, you're too slow and you didn't have your rollerblades in your bag? Sorry man, but you're a goner.");
    }
    break;
  default:
    console.log("Woah, bro. Didn't understand what you said. Hit Run and try again, this time picking SLAY, EAT, or RUN!");
}

/* I know it's short, but it's a start. And I had a whole lot of fun writing this--even though it's pretty nonsensical... but who cares. Maybe I'll animate it someday? */

I think from now on, I'm going to stray away from the previous formulaic and boring method I've used to craft my post and focus on something a little more creative and thoughtful. It's way more fun and I hope you enjoy!

Monday, May 20, 2013

J.S. Project: Dragon Slayer



We'll be combining while loops with some other control statements (like if / else statements) to create a dragon slaying minigame.

01 / 04 : Let's first start off by declaring the variables which we'll be using. We're going to need a variable to check if we're still slaying, a variable to check if we hit the dragon, a variable to keep track of how much damage we've dealt the dragon this round, and a variable to keep track of total damage. We'll also be relying on random numbers to see if we hit the dragon, and if so, how much damage we did. JavaScript generates random numbers like this:
    var randomNumber = Math.random();
This creates a random number between 0 and 1. By multiplying the number and rounding it down, we can make it a random whole number. For example:
    Math.floor(Math.random() * 5 + 1);
will generate a random number between 1 and 5 inclusive. Now let's declare and set the following variables:
    1. slaying equal to true
    2. youHit to a random number that's either 0 (which JavaScript reads as 'false') or 1 {which JavaScript reads as 'true')
    3. damageThisRound to a random number between 1 and 5 (inclusive)
    4. totalDamage to 0
    HINT - by multiplying the random number (which is between 0 and 1) by 5, we make it a random number between 0 and 5 (for example, 3.1841). Math.floor() rounds this number down to a whole number, and adding 1 and the end changes the range from between 0 and 4 to between 1 and 5 (up to and including 5).

var slaying = true;
var youHit = Math.random();
var damageThisRound = Math.floor(Math.random() * 5 + 1);
var totalDamage = 0;

02 / 04 : Wonderful. Now let's add in our while loop. We want to run this whole game as long as we're trying to kill the dragon--that is, while slaying is true. When checking variables like slaying that are set to true, we don't need to write something like this:
    while(slaying === true)
Instead, we can just write:
    while(slaying)
Now let's create a while loop that only executes when slaying is true. For this exercise, set slaying to false in the body of the loop (we want to make sure the loop can exit... no infinite loops for us!) 

var slaying = true;
while(slaying) {
    slaying = false;
}

03 / 04 : Now time to add a couple of branches to our program so it can handle different outcomes. You know what this means... if and else! Inside the while loop, create an if / else statement that checks the value of youHit. If it's 1 (true), it should log a congratulatory message to the console, telling the user (s)he hit the dragon. If it's 0 (false), it should log a message to the console saying that the dragon defeated you. Either way, slaying should be set to false, since either you beat the dragon (and the slaying's over) or the dragon beat you!

while(slaying) {
    if (youHit) {
        console.log("You hit!");
    } else {
        console.log("You missed!");
    }
    slaying = false;
}

04 / 04 : We're gonna add the second 'if' statement. In the first branch of our if statement (right after the console.log() where we congratulate the player for hitting the dragon), let's set totalDamage equal to totalDamage + damageThisRound. The shortcut for this is: the += operator. When you type
    totalDamage += damageThisRound 
you're telling JavaScript to add totalDamage and damageThisRound together, then assign the new value to totalDamage. Inside the first if statement, create a second if statement that checks to see if totalDamage is greater than or equal to 4. If so, it should log to the console that the player slew the dragon and set slaying equal to false (since the dragon's dead, the slaying is over). If totalDamage isn't greater than or equal to 4, youHit should be assigned a new random 1 or 0. (This is as easy as setting youHit to the same expression you used when you first declared it.)


while(slaying) {
    if (youHit) {
        console.log("You hit!");
        totalDamage += damageThisRound;
            if ( totalDamage >= 4) {
                console.log("You win!");
                slaying = false
            } else { 
                youHit = Math.floor(Math.random()*2);
            }
    } else {
        console.log("You missed!");
        slaying = false;
    }
}


You did it! You've written your own dragon slaying game!

Wednesday, May 15, 2013

J.S. Project: Search Text for Your Name



Today, we're going to write a short program that checks a block of text for my name. More specifically, it's going to check for the first letter of my name, then push (add) the number of characters equal to my name's length to an array. By inspecting the array, we'll be able to see if our name was mentioned.

/*jshint multistr:true */
text = "Blah blah blah blah blah blah blah blah Jenny blah \
blah blah blah blah blah blah Jenny blah blah blah blah \
blah blah blah blah blah blah blah blah blah Jenny";

var myName = "Jenny";
var hits = [];

// Look for "J" in the text
for(var i = 0; i < text.length; i++) {
    if (text[i] === "J) {
        // If we find it, add characters up to
        // the length of my name to the array
        for(var j = i; j < (myName.length + i) ; j++) {
            hits.push(text[j]);
        }
    }
}

if (hits.length === 0) {
    console.log("Your name wasn't found!");
} else {
    console.log(hits);
}

01 / 05 : Let's start by declaring our variables: text, myName, and hits. Since text could be quite long, try putting a blackslash (\) at the end of each line to make our string "wrap" to the next line of the editor. We can ignore the /*jshint multistr:true */ for now because all it does is tell the console to stop worrying about our use of backslash characters for wrapping long lines of text. Now set the following three variables:
1. text, and make a string containing some text
2. myName, and make a string containing just your name
3. hits, and make it an empty array
    HINT - make an empty array by setting your variable equal to [] (an array with nothing in it)

var text = "blah blah Jenny blah blah blah Jenny blah";
var myName = "Jenny";
var hits = [];

02 / 05 : Let's write our outer for loop. Below our existing code, create a for loop that starts at 0, continues until it reaches the end of text, and increments by 1 each time. (Meaning it will check each character in the string).
    HINT - Remember the syntax for a for loop looks like this:
        for(var i = 0; i < condition; i++) {
            // Do something !
        }
    In place of "condition", put the condition that will stop the loop from running. In this case, our  
    condition should be less text.length.

for(var i = 0; i < text.length; i++) {

}

03 / 05 : Nice! Now let's move on to the if statement. We'll want to place the if statement inside our for loop to make sure the program checks the if statement each time it moves forward through the loop. Essentially, the for loop is saying: "Hey program! Go through every letter in 'text'." The if statement will say: if you see something interesting, push that text into an array!" You can treat a string like an array of characters: For instance, you know that
        var myArray = ['hello', 'world'];
        myArray[0]; // equals 'hello'
But this also works on strings!
        var myName = 'Jenny';
        myName[0] // equals 'J'
Add your if statement in the body of your for loop and it should check to see whether the curent letter is equal to the first letter of your name.
    HINT - Remember, an if statement looks like thisis:
        if (some condition) {
            // Do something!
        }

    You can check the i th letter of text like so: \
    // Assuming your name starts with 'E'
    if (text[i] === 'E') {
        // Do something!
    }

for (var i = 0; i < text.length; i++){
    if (text[i] === 'J') {
 
    }
}

04 / 05 : Now time to add your second "for" loop. You're going to write it inside the body of your first if statement (between the if's {}s). This loop is going to make sure each character of your name gets pushed to the final array. The if statement says: "If we find the first letter of your name, start the second for loop!" This loop says: "I'm going to add characters to the array until I hit the length of the user's name." So if your name is 11 letters long, your loop should add 11 characters to hits if it ever sees the first letter of myName in text. We'll want to set our second loop's iterator to start at the first one, so it picks up where that one left off. If our first loop starts with
    for(var i = 0; // rest of loop setup
our second loop should be something like
    for(var j = i; // rest of loop setup
In the body of our loop, have our program use the .push() method of hits. Just like strings and arrays have a .length method, arrays have a .push() method that adds the thing between parentheses to the end of the array, for example:
    newArray = [];
    newArray.push('hello');
    newArray[0] // equals 'hello'
    HINT - the loop should stop when it hits the value of the first iterator plus the length of the myName
    variable.

for(var i = 00; i < text.length; i++){
    if (text[i] === 'J') {
        for(var j = i; j < (myName.length + i); j++){
            hits.push(text[j]);
        }
    }
}

05 / 05 : You've now got the engine of your search program running! It's going to:
    1. loop through the array
    2. compare each letter to the first letter of your name, and if it sees that letter:
    3. it will push that letter and all the letters that follow it to an array, stopping when the number of
        letters it pushes are equal to the number of letters in your name.
So under your existing code (and outside all your other loops!) Set up an if / else statement. If you don't have any hits, log "Your name wasn't found!" to the console. Otherwise, log the hits array to the console.

if (hits.length === 0) {
    console.log("Your name wasn't found!");
} else {
    console.log(hits);
}

** Unfortunately, this system isn't perfect. For instance, if the paragraph contains both "Jenny" and "Jerry", we'll see this in our hits array:
['J', 'e', 'n', 'n', 'y', 'J', 'e', 'r', 'r', 'y']

Friday, May 3, 2013

Javascript: Review of Functions


// Introducing Functions 

A function can be defined by preceding a bunch of code with the word function followed by its inputs. These inputs are known as parameters and are enclosed with (). The associated code is enclosed with {}.

// Accepts a number x as input and returns its square
var square = function(x) {
    return x * x;
};

// Accepts a number x as input and returns its cube
var cube = function(x) {
    return x * x * x;
};

cube(7);

// Understanding Parameters
Functions can have zero, one, or more parameters. You can think of these as input that the function receives, and then uses to do something.

// the code example shows a function that takes two number as arguments and returns their product
var multiply = function (x, y) {
    return x * y;
};

multiply(2, 5);

// Argument Types, part 1
We just saw that the naming of parameters doesn't impact the caller of a function. In JavaScript, you don't need to specify a type when defining a function which means that when someone else calls your function, they can supply any type of argument that they want to-- a number, a string, an array, etc. This may lead to some strange behavior if you call your multiply function with a string:

multiply("tweedledee", "tweedledum");
// returned value is NaN (stands for, not a number)

// Argument Types, part 2
Let's say that we want to make sure that the caller always gets a numeric value back, even if the input wasn't of the right type... To achieve that, we need to check the type of argument that was passed in. If it wasn't a number, we probably shouldn't try to multiply it. We'll just return 0 in that case.

var cube = function (x) {
    if (typeof(x) !== 'number') return 0;
    return x * x * x;
};

// the cube() function should return 0.
cube("test");

// Local Variables
Each parameter of a function is effectively a variable. It has a name that we can use inside the function to refer to the value that was supplied by the call to the function. Once the function has been called, is that name available outside the function? To test this, let's run the code below as is:

var volume = function (w, l, h) {
    return w * l * h;
};

volume(2, 3, 4) ;
console.log(w);

We get a "Reference: Error", w is not defined. What that means is that the name w was set to the value 2 inside the function when it was called, but was never defined outside of the function. For the code to work, we've got to set:

var w = 15;

What if you need additional local variables beyond the arguments (e.g. to hold an intermediate result)? In the volume function, you can see an example of such a local variable. The variable area is local because it is visible only inside the function. Even after the function has been called, area is still not defining outside the function and referring to it triggers an error.

var volume = function (w, l, h) {
    var area = w * l;
    return area * h;
};

// var area = 36
console.log("Inside the function, area is 6");
console.log("The volume is " + volume(2, 3, 4));
console.log("Outside the function, area is " + area);

You'll get another Reference Error: area is not defined... so now, uncomment line 6 and you'll have:
Inside the function, the area is 6
The volume is 24
Outside the function, area is 36

Now you see a slightly different version of the volume function: can you spot the difference?


var area = 36;
var volume = function (w, l, h) {
    area = w * l;
    return area * h;
};

console.log(volume(2, 3, 4));
console.log(area);


Area is no longer preceded by var. The area variable is no longer local to the function. Instead, when the function has been called, the area is set to 2 * 3 = 6 when volume is called. The area variable outside the function is called a global variable because it is visible everywhere. Modifying it inside a function is referred to as a side-effect and is generally something you want to avoid. This is why you should always use var when declaring variables!

var area = 36;
var volume = function (w, l, h) {
    var area = w * l;
    return area * h;
};

console.log(volume(2, 3, 4));
console.log(area);

Wednesday, May 1, 2013

J.S. Project: Rock, Paper, Scissors


Today, we're going to create the classic rock paper scissors game! Each player chooses either rock, paper, or scissors and the possible outcomes are:

Rock destroys scissors.
Scissors cut paper.
Paper covers rock.

Our code will break the game into three components:
a. User makes a choice
b. Computer makes a choice
c. A compare function will determine who wins

We are going to first start off by asking the user which option they'd like to pick. We're going to use this choice later in the compare function to determine the winner.

01 / 07 : declare a variable called userChoice and set it equal to the answer we get by asking the user: "Do you choose rock, paper, or scissors?":
    HINT - remember to prompt the user to ask a question...

var userChoice = prompt("Do you choose rock, paper, or scissors?");

02 / 07 : Awesome sauce! Now, we've gotta get the computer to make a choice too. The game is going to be fun (and worth playing) if the computer chooses randomly. If we declare a variable and set it equal to Math.random(), that variable will equal a number between 0 and 1. Declare a variable called computerChoice and set it equal to Math.random(). Then, print out computerChoice so you can see how Math.random() works!

var computerChoice = Math.random();
console.log(computerChoice);

03 / 07 : So we've created computerChoice but it now equals a random number between 0 and 1. We need to somehow translate this random number into a random choice of rock, paper, or scissors:
    1. If computerChoice is between 0 and 0.33, make computerChoice equal to rock.
    2. If computerChoice is between 0.34 and 0.66, make computerChoice equal to paper.
    3. If computerChoice is between 0.67 and 0.99, make computerChoice equal to scissors.
We've gotta use if / else if / else because there are three outcomes (we use if / else for two):

if ( 0 <= computerChoice <=  0.33 ) {
    console.log("rock");
} else if ( 0.34 <=  computerChoice <=  0.66 ) {
    console.log("paper");
} else {
    console.log("scissors");
}

04 / 07 : Now comes the fun part! We're going to create a function that takes two parameters (the two choices made) and return the winning choice. We have to first figure out all the different outcomes, which are essentially the choices that the user makes equaling the choice the computer makes. Declare a  function called compare() taking two parameters choice1 and choice2. Inside the function, write an if statement such that if the two parameters equal each other, the function will return: "The result is a tie!".

function compare(choice1, choice2) {
    if (choice1 === choice2) {
        return("The result is a tie!");
    }
}

05 / 07 : Wonderful. Now, let's consider the other scenarios in this game: what if choice1 is "rock"? Given choice1 is "rock",
        a. if choice2 is "scissors", then "rock" wins.
        b. if choice2 is "paper", then "paper" wins.
How are we going to structure this? Well, we've already got an if statement, so the code inside that if statement will be another if statement itself! Write an if statement where the condition is choice1 equals "rock". Then, in the code block for that if statement, write an if / else statement. In that statement, if choice2 is "scissors", return "rock wins". Otherwise, return "paper wins".
    HINT - putting if statements inside if statements might be a little tricky at first. Here's an outline of what the syntax should look like:
if (condition) {
    if (condition) {
        return "some string";
    } else {
        return "some other string";
    }
}

if (choice1 === "rock") {
    if (choice2 === "scissors") {
        return("rock wins");
    } else {
        return("paper wins");
    }
}  

06 / 07 : Well, what if choice1 is "paper"?
        a. if choice2 is "rock", then "paper" wins.
        b. if choice2 is "scissors", then "scissors" wins.
We're gonna use the same structure to add these two extra scenarios:

if (choice1 === "paper") {
    if (choice2 === "rock") {
        return("paper wins");
    } else {
        return("scissors wins");
    }
 }

07 / 07 : Lastly, we've got to consider what if choice1 s "scissors:
        a. if choice2 is "rock", then "rock" wins.
        b. if choice2 is "paper", then "scissors" wins.
We're almost done, let's take the same structure we've used in the past couple exercises and apply it to these two new scenarios:

if (choice1 === "scissors") {
    if (choice2 === "rock") {
        return("paper wins");
    } else {
        return("scissors wins");
    }
}
     
Finally, call your function and pass in userChoice and computerChoice as your two parameters:

compare(userChoice, computerChoice);

// now, here's the entire game all in one go: 


var userChoice = prompt("Do you choose rock, paper or scissors?");

var computerChoice = Math.random();
if (computerChoice < 0.34) {
    computerChoice = "rock";
} else if(computerChoice <= 0.67) {
computerChoice = "paper";
else {
computerChoice = "scissors";
}

function compare( choice1, choice2 ) {
    if (choice1 === choice2 ) {
        return("The result is a tie!");
    }
   
    if (choice1 === "rock") {
        if (choice2 === "scissors") {
            return("rock wins");
        } else {
            return("paper wins");
        }
    }
   
    if (choice1 === "paper") {
        if (choice2 === "rock") {
            return("paper wins");
        } else {
            return("scissors wins");
        }
    }
   
    if (choice1 === "scissors") {
        if (choice2 === "rock") {
            return("rock wins");
        } else {
            return("scissors wins");
        }
    }
}

compare(userChoice, computerChoice);


Congrats on making your awesome game!

P.S. Check out my new video where I give you all a tour of my room

Song of the day // The Hours (Beach House)