Saturday, February 21, 2015

Getting Started with OpenCV

OpenCV is a great library for doing all sorts of computer vision.  It's also easy enough that you can use it for all sorts of menial tasks, like resizing images, cropping, adjusting colors, etc.  And best of all, it's FAST.  I have used ImageMagick in the past, and OpenCV feels a ton faster.  If you want some data to support that claim, see this link.

Given that OpenCV is fast, general-purpose, and not too hard to use, I thought it would be a good topic for CSE398.  Here's the tutorial I wrote.

I opted to do everything in Java, because that seemed easier than worrying about memory management.  Of course, that also means it's harder to find good documentation.  I ended up transliterating a lot of C++ code to show how various features work.

Since I'm not expert in Computer Vision, I wouldn't be surprised if I got some things wrong in the tutorial.  Please don't hesitate to send a note if you find any errors!

Monday, February 16, 2015

An Introduction to Extending Code

Here's yet another CSE398 tutorial.  This time it's about how to dynamically load code, or to otherwise create extensions that expand the behavior of a program.  I realized that while students have heard of "DLL Hell", they don't know how to make DLLs (or their Unix equivalent, "shared objects").

DLLs are like lambdas (did you like yesterday's post?): if you don't know how to use them, you end up doing an outrageous amount of work to get an effect that would otherwise be simple.  The tutorial starts by showing how to load and use a shared object in C++, which lets me introduce my basic Makefile template, function pointers, and C++ name mangling.  Then it shows how to do dynamic class loading in Java.  We move from there to using exec or spawn to do inter-process communication (IPC) between Node.js and Java or C++ programs.

I tried to make the tutorial a little bit more fun, by hiding the code for a Java Pig Latin converter.  This was also an attempt to get people to look at the HTML code for my tutorials.  I don't think students realize how easy it is to do clean web design by hand, once you know a little CSS and jQuery.

As with all of my CSE398 tutorials, I wrap up with next steps, this time involving the use of existing Node.js packages to load C++ and Java code directly into a running node server.

Sunday, February 15, 2015

A Few Great C++11 Features

A few years back, I heard a talk by John Spicer of Edison Design Group on new features in C++11. After hearing John's talk, I realized that my students and I all fell into his category of programmers who knew the "FORTRAN subset of C++".  Sure, I've written lots of code over the years, and a C++ compiler will understand that code.  But was it really C++?  Was it idiomatic?  And even if it was, would it still be considered idiomatic in the face of C++11?

C++11 adds tons of cool features.  The concurrency support is great.  The STL is even better than before.  But the best part, in my opinion, is lambdas.  With lambdas, data structure design gets a lot easier.  One "map" function can replace all of those one-off functions that otherwise go into a data structure (min, max, average, selectIf, countIf, etc.).

Here's a program I wrote to demonstrate some of the features of C++11.


/// This is a demonstration of a few nice C++11 features: auto, the ':'
/// iterator, initializer lists, std::function, and lambda expressions.  In
/// many cases, it's possible to achieve the same effect as I present using
/// even less code, but by being explicit I hope I have made the code and
/// comments easy to follow

#include <functional>
#include <iostream>
#include <map>
#include <string>
#include <vector>

using namespace std; // I'm being lazy here... should explicitly use cout,
                     // endl, function, map, pair, string, and vector


/// wrapped_map_t extends map<string, string>.  We start with a map of
/// key/value pairs, where both the key and value are strings, and we add a
/// new method to it.  The new method, apply_to_all, lets us apply a lambda
/// to (a copy of) every key/value pair that is in the map.
///
/// my claim is that lambdas fundamentally change the art of data structure
/// design.  To support my claim, I will show how this one simple function
/// obviates many public functions that one might want int a data structure
/// (count, print, extract_keys, find_matching_keys, etc).
struct wrapped_map_t : public map<string, string>
{
    /// the apply_to_all function simply iterates through the key/value pairs
    /// of the map, calling lambda(key, value) for each pair.  Strictly
    /// speaking, std::map is a red/black tree, and this will do a pre-order
    /// traversal
    void apply_to_all(function<void(const string, const string)>& lambda)
    {
        // note the use of C++11 'auto' keyword to avoid having to specify
        // the type of the iterator
        for (auto i = begin(), e = end(); i != e; ++i)
            lambda(i->first, i->second);
    }
};

int main()
{
    // declare an instance of the extended map
    wrapped_map_t kvpairs;

    // populate the map with some keys and values.  We're going to use some
    // great C++ magic here: initializer lists.  We don't even have to know
    // the type of the list, but the compiler will deduce that it's something
    // like pair<string,string>[]
    kvpairs.insert({{"donald", "duck"}, {"mickey", "mouse"},
                    {"minnie", "mouse"}, {"bat", "man"},
                    {"super", "man"}, {"milo", "otis"},
                    {"mighty", "mouse"}, {"rocky", "squirrel"},
                    {"bullwinkle", "moose"}});

    // 'func' is a reference to a function that takes two strings as its
    // parameters, and returns nothing.  This is a lot nicer than the old C
    // syntax in use before C++11 (i.e., void (*func)(string, string)).
    function<void(string, string)> func;

    // let's assign a new lambda to func.  the lambda will simply print its
    // parameters
    func = [](string k, string v) { cout << "{" << k << ", " << v << "} "; };
    // now let's apply func to every element in the set.  No need for a
    // "print_in_sorted_key_order" function in our class.  It would be
    // trivial to add "print keys" and "print values" features without
    // changing the data structure... we'd just need to pass different
    // lambdas
    cout << "KVPairs = ";
    kvpairs.apply_to_all(func);
    cout << endl;

    // The last example was pretty boring.  A function pointer could have
    // done that easily.  Now let's pass in a function that has a captured
    // reference to a variable that is local to this function.  In that way,
    // each time the lambda is called, it can access the function 'my_count'
    // that we declare *right here*.  The net result is that we can count the
    // elements in the map, without requiring map to provide a "count()"
    // function.  Note that the parameters to the lambda aren't used, and
    // that's OK.
    int my_count = 0;
    func = [&my_count](string k, string v) { my_count++; };
    kvpairs.apply_to_all(func);
    cout << "Elements in map = " << my_count << endl;

    // OK, so we could have achieved that effect with an apply_to_all that
    // took three parameters: string, string, int&.  But would we really want
    // to do that for every possible pass-by-reference type?  For example,
    // here we pass a vector of strings so that we can copy out all keys from
    // the map
    vector<string> keys;
    func = [&keys](string k, string v) {keys.push_back(k);};
    kvpairs.apply_to_all(func);
    // print the keys, to show that it worked
    cout << "Keys in map = {";
    for (auto i : keys)
        cout << i << ",";
    cout << "}" << endl;

    // note, too, that we can use the lambda to capture multiple local
    // variables, and that some can be pass by value while others are pass by
    // reference.  Here 'pre' is pass by value, 'keys' is pass by reference,
    // and our function copies into 'keys' all keys in the map whose values
    // begin with 'mo'
    string pre = "mo";
    keys.clear();
    func = [&keys, pre](string k, string v) { if (v.find(pre) == 0) keys.push_back(k);};
    kvpairs.apply_to_all(func);
    cout << "Keys whose values start with 'mo' = {";
    for (auto i : keys)
        cout << i << ",";
    cout << "}" << endl;

    // this example is much like the prior one.  Here we extract all
    // key/value pairs where the key begins with 'mi'
    pre = "mi";
    vector<pair<string, string>> pairs;
    func = [&pairs, pre] (string k, string v)
        { if (k.find(pre) == 0) pairs.push_back(make_pair(k, v)); };
    kvpairs.apply_to_all(func);
    cout << "Elements whose key begins with 'mi' = {";
    for (auto i : pairs)
        cout << "{"<<i.first<<", "<<i.second<<"} ";
    cout << "}" << endl;

    // the point of this example is to illustrate that when the lambda is
    // called with the key and value, the function we are executing *cannot*
    // modify the internals of the map.  Put another way, the lambda does not
    // become a member function of the class.  So, for example, if we wanted
    // to add a suffix to every key, then the only way we could do it would
    // be by explicitly updating the k/v pair in the map.
    string suf = " <3";
    // note: we need to capture *kvpairs itself* by reference
    func = [&kvpairs, suf] (string k, string v) { kvpairs[k] = v+suf; };
    kvpairs.apply_to_all(func);
    // use a lambda to print it out
    func = [](string k, string v) { cout << "{" << k << ", " << v << "} "; };
    cout << "Modified kvpairs = ";
    kvpairs.apply_to_all(func);
    cout << endl;
}

Don't forget that you need to use the -std=c++11 flag when you compile this with g++.

Saturday, February 14, 2015

Fun with Google Forms

Here's a link to another of my tutorials for CSE398.  I figured this out in the course of making a registration page for an elementary school's after-school enrichment program.  We wanted the convenience of a Google Form, with all results going to a shared spreadsheet, but we also wanted to be able to keep people from registering for activities that were either (a) not available based on their child's grade level, or (b) already at capacity.

The trick is to make a separate worksheet in the Google Spreadsheet that is attached to the form, set it up to summarize the data in the main sheet of the spreadsheet, publish the second worksheet, and only the second worksheet, and then consume it as JSON.  Then it's just a matter of using JavaScript on the client side to fetch the JSON, parse it, and use the resulting data to drive the UI.

Somewhere along the way, I realized that the Google Form is really two components with a straightforward API connecting them.  We can't change the API, but we can have a different front-end that interacts with the same back-end, as long as we respect the API.  Once I realized that, it seemed worthwhile to make a tutorial about it.

The link to the tutorial is here.  Hopefully it is easy to follow.  As with my other CSE398 tutorials, there are "next steps" that I leave up to the student.

Disclaimer: there are ways to hack the technique I present, so don't use it for anything mission-critical.  You'll still get the safety that Google Forms provides, but people can get around the JavaScript-based validation.

Friday, February 13, 2015

My Favorite Graphics Tutorials

This isn't a particularly long post, but if anyone is looking for tutorials to help them make graphics for their mobiLEHIGH games, I think Chris Hildenbrand's tutorials on making vector art with Inkscape are great.  Here are some links:

You can also check out Chris's blog.

Remember: when making art for games, png is the preferred format.  It has transparency support, and it uses lossless compression, so your nice crisp lines won't get blurred like in jpegs.

Thursday, February 12, 2015

Getting started with Node.js

This semester I'm teaching a new class, CSE398: Large Scale Software Development.  The goal of the class is to provide students with a hands-on experience designing and implementing bigger programs than they see in a typical class.  My informal informal motto is "If you need to have a database and a web site, that's not two projects... it's half a project, because you don't have a desktop or mobile component."

That may seem trite, but my feeling is that it's important to use other people's APIs, to connect software components that are implemented in different languages, and to understand that real-world software must be thought of as a large set of loosely connected components.

I'm also hopeful that this will be a great laboratory for learning about technical debt.  In particular, I'm hoping that students will cut corners early in the semester, and then have nobody but themselves to blame when they return to that code later in the semester.  We shall see how it goes.

Anyway, with all of that exposition out of the way, I'll note that a few weeks back, I put together a tutorial on how to do all the basic web things (forms, REST, connect to MongoDB, push notifications) that people do with Node.js.  The tutorial is publicly available through this link.

There are a few bugs in the tutorial, so if you notice anything incorrect, please let me know in the comments, so I can make corrections.

You'll also note that each tutorial has some "next steps", which I expect the students to do without my close guidance.  This is meant to encourage learning about how to teach oneself from on-line tutorials, and also how to evaluate on-line resources.  For what it's worth, I think the scotch.io tutorial series on passport.js is pretty good.

Wednesday, February 11, 2015

Particle Systems

LibGDX has some amazing support for particle systems.  Particle systems provide a way to produce some great effects, like snow or flames.

I just added some basic support for particle systems to LibLOL.  These particles are not Actors.  They don't have meaning in the Physics world.  But they do provide some nice visual effects.

Using particle effects is pretty easy.  There's a new facility, Effect, which provides a factory method for making particle effects.  (Hopefully I'll add other effects some day, so I made the code a little bit generic.)  All you need to do is provide the name of a particle effect file, give it x and y coordinates, and then indicate a few other parameters (Z index, whether it should repeat).

The hard part is making the particle effect file.  There's a tutorial here.  In effect, there are three parts:

First, you need to set up Android Studio to run the particle effect editor.  This is a lot like the step you took to make a "Desktop" target for your game.  You'll use the "Run/Edit Configurations" menu option, and set the path to "com.badlogic.gdx.tools.particleeditor.ParticleEditor".  If you've done it correctly, you'll be able to choose ParticleEditor from the run options.  Running it should start a program that looks like this:


Second, you can play with all of the parameters in the program until you get the effect you want.  To do this correctly, your best bet is to set Pixels per meter to 20 (because LibLOL has a pixel-to-meter ratio of 20).  Once you've done that, you'll need to divide a lot of the values in the editor by 20 to get things back to a reasonable state.  Once you've got everything looking good with 20 pixels per meter, save the effect as a text file in your android/assets folder.

The third step is to load your effect, see what doesn't work nicely, and adjust accordingly.  I know it's unsatisfying to say "trial and error", but sometimes that's what it takes.

Tuesday, February 3, 2015

Making Games in Liblol: Part 6: The Store

While this post title is "The Store", this is really about another component of LibLOL: the "Facts" interface.

In most games, there are things (typically numbers) that you might want to save.  During the play of a single level, you might want to count how many power-ups the player used.  During one interaction with the game (such as playing 18 holes of golf), you might want to keep track of the score on each hole.  You might also want to track some statistics relating to the history of every time the game has been played.

While you can manage most of this using fields in the objects of your game, it's often easier to have a unified interface.  That's where Facts comes in.

Facts come in a few flavors: first of all, we can store numbers related to the current level being played (LevelFacts), to the current interaction with the game (SessionFacts), or with the whole game (GameFacts).  For each of these, we can either put a fact as a string and an integer value, or we can get a fact, again as an integer value.

For the sake of completeness, I'll note that there is one special case for Facts: we can also save and retrieve actors (Goodies, Obstacles, Heroes, Enemies, Projectiles) for the current level, also as LevelFacts.

Getting back to our store example, the main idea is that we can use Actors in the store to represent buttons for things to purchase.  In a level, as we collect coins, the level's internal score increases.  To turn the coins of the level into a Fact, we can do something like this:


            LolCallback sc = new LolCallback() {
                public void onEvent() {
                    int oldCoins = Facts.getGameFact("Coins", 0);
                    int addedCoins = Score.getGoodiesCollected1();
                    Facts.putGameFact("Coins", oldCoins + addedCoins);
                }
            };
            Level.setWinCallback(sc);

Putting that code in our level will say that when the level is won, we'll add the score (score 1, to be precise... remember that we have counters for four different kinds of scores) to the old coin count.

We could get more fancy, for example by having callbacks on our coins so that we could directly add to a specific LevelFact.  But for our example, this is good enough.

What about the store, then?  Well, it's pretty simple: we can have obstacles on a store screen to represent buttons for purchasing power-ups, and then we can have TouchCallbacks on the buttons that subtract from the Facts to make a purchase happen.  Those callbacks should also update other GameFacts to indicate the numbers of power-ups remaining.

Hopefully that's enough information to get you started building a store for your app.  But I do have one question: are integer and Actor Facts enough?  Would String facts be useful?  Let me know in the comments.