Uno! -- A Nifty Assignment

Stephen Davies -- University of Mary Washington


Summary Uno! -- students write their own algorithms (as Java methods) to play a hand of Uno cards according to a strategy they devise. A simulator program then pits groups of four student strategies against each other, running large numbers of consecutive games, and displaying a running score in scoreboard-like fashion.
Topics
A thorough application of the earlier CS1 concepts: variables, loops, branching, arrays, enums, and writing functions.
Audience
Appropriate for CS1, regardless of incoming skill level. Writing a simple working strategy is relatively easy; but competition, and endless opportunities for tweaking one's algorithm to eke out better results, motivates advanced students to go beyond this.
Difficulty
This is an intermediate assignment, suitable for the middle of the semester, taking 2 weeks for a CS1 student.
Strengths
The competition aspect is very popular with students. Many of them have programmed before taking CS1, but almost none of them had written a program that would run against someone else's. A second important strength is that the assignment is applicable to a wide range of skill sets: it's not hard to write a strategy that makes legal plays (for instance, just choose the first card in your hand that is playable on the up card) but there are a surprising number of ways to optimize play.
Weaknesses
Students can be disoriented by the fact that they do not write a "main()" routine: instead, the simulator has the main(), and they are writing routines that will be called by it. Also, for the whole simulator structure to work, students' code has to be based on a template which involves some advanced OO techniques (use of multiple source files, implementing a Java interface, etc.) Providing this skeleton can minimize the fear factor, but the fact that scary things they don't understand are present in their source file can be potentially disquieting for some students.
Dependencies
Requires introductory competence with variables, branching, loops, collections (List), enums, and invoking methods on objects. The simulator provided is in Java, but of course could be ported to other languages if desired.
Variants
A "GameState" object is passed as an argument to the player's method, for use by more advanced students. Basic players can simply ignore it, but motivated students who want more strategy customization options can use callback methods on the GameState in order to find out how many cards each opponent has, what color was most recently called, the overall score of the match, etc.

Overview

One of the difficulties a CS1 instructor faces is the large gap in incoming skill sets. Some students are taking the "intro" course as a true "introduction" to programming, while others have been AP students or self-taught hackers for years. How can an instructor truly challenge and interest the programming-savvy while at the same time not overwhelming the novices with an overly complex assignment?

The Uno! assignment is intended to address this concern by introducing good-spirited competition within the class. Uno! is a simple but popular card game known to children (and adults) around the world. It involves players being dealt hands of cards and then playing them in a round-robin fashion, trying to be the first to "go out" (i.e., play all their cards.) The strategy required to play effectively is modest, but there are a surprising number of choices a player unconsciously makes as they play. (Should I match the up card's rank, or color? Should I play my wild card now or hold it? is the person after me ahead, or behind, and would it be wise to use a penalty card on them? What should I change the color to? etc.)

A Java simulator program (provided) can simulate thousands of consecutive Uno! games in seconds. It implements all the rules of the standard game, including the scoring, with only one thing missing: pluggable strategy methods for each player. Students have two weeks to formulate their strategies and write their code for choosing a (legal) card to play from a hand, and choosing which color to "call" if they play a wild. Each of these strategies (which is an implementation of a simple Java interface with two methods) is then "plugged in" to the simulator, which can simulate four (or any number) of players competing against each other for 50,000 (or any number of) straight games. A visual scoreboard displays the running totals as the game progresses. An in-class, bracket-style competition is suggested for the Friday after the programs are due, so that students can watch their programs compete against their classmates' and try to advance to the Uno Final Four.

Benefits

This assignment combines several nice features:

Materials provided

Sample assignment description

I have provided the sample assignment description I used for my course. It includes an overview of the game, instructions for students to download the necessary files to their NetBeans installations, a thorough description of the methods they are to implement, starter tips for strategy, and policies on grading. Note that in my course, I allowed students to implement a legal, but "brain dead" player (i.e., a simple algorithm that always followed the game rules) for a B, but earning an A required a more advanced program.

Simulator

The code for the simulator is available in a zip file, along with instructions for running it. Also included are some solutions from a handful of my students, of varying skill levels (including our grand champion, Becky Brown, who implemented full Vegas-style card counting to eke out a narrow Final Four victory.)

Bullet-proof tester

Also included in the zip file, above, are two "bullet-proof tester" programs which students can run on their own code before submission. (One version is for basic players, and the other for advanced players.) These programs call the student's methods with 10,000 random hands, making sure that the student's code makes a legal play on every one of them. (In other words, it ensures that the student's code never tries to play an illegal card -- like a red 5 on a yellow 2 -- and that it never mistakenly returns null, indicating no card can be played, when in fact a legal play is possible.) Requiring students to pass the bullet-proof tester before submitting their code is advisable, so that inadvertent cheating (and simulator crashes) are avoided.


Extra info about this assignment: