Lab 1: The Dance Simulator

For your first lab assignment in this class, I want you to create a C++/Python program that simulates the dance (version 1) that we did in class. There is C++ starter code at the end of this note.

Warning

The provided code is my solution, stripped of the details needed to make it work. It is not a “good” program. It lives in a single file, does not use classes, and it has those evil global variables. That is by design. I want to to craft your own code, doing as good a job as you can. Use my code as a guide to help you put together the needed parts.

General Lab Repository

We will do a few individual lab projects in this class. As we are doing for the homework problems, we will set up aa repository inside of which you will create folders for these labs. The invitation you need to set up this repository is here:

Accept this repository, then clone it onto your workstation as we did for the homework repository.

Design in Teams, Code on Your Own

For this lab, I want you to form up into teams of three or four classmates. (Less will be allowed only if needed - more is not allowed.) Your team should talk through the design of this simulation. After you talk, write your own code. You can look at each other’s code, but no sharing of files is allowed. I want you to fee that you wrote this code, and I expect you to do real original work to put this together. You can help each other get this done and put into your repository as needed to submit this. The “team” is done, when all team members have code on GitHub.

Sample Output

The output from this sample program is something I want you to reproduce, as best as you can. My solution uses the rules in the lecture, so you should be able to duplicate the output.

Here is a sample run for dance version 1:

sample-run
./dance
Dance-Cards (v0.1)
6 0 0 0 0 0 
3 1 1 0 0 1 
2 1 1 0 1 1 
1 1 1 1 1 1 
system is stable

And here is the stripped down solution code I created:

dance.cpp
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
#include <iostream>
#include <string>
#include <sstream>

// defaults
const int MAX_STEPS = 100;      // how long do we run the simulation
const int MAX_DANCERS = 20;     // no more than this many dancers allowed
const int INIT_STEPS = 10;      // we will run this many steps unless overridden
const int INIT_DANCERS = 5;     // start with this many dancers, unless overridden
const int INIT_CARDS = 6;       // start with this many cards 

// globals are UGLY!
int cards[MAX_DANCERS+1] = {0}; // every dancer starts with no cards
int nsteps = INIT_STEPS;
int ndancers = INIT_DANCERS;
int ncards = INIT_CARDS;
bool debug = false;
bool stable = false;

void usage() {
    std::cout << "Usage: " 
        << "dancer [-d] [-c cards] [-n dancers] [-s steps]"
        << std::endl;
    exit(1);
}

void show_cards() {
    // display the current cards
    for(int i=0;i<ndancers+1;i++)
        std::cout 
            << cards[i] 
            << " ";
    std::cout << std::endl;
}
 
std::string show_step(int d) {
    std::ostringstream out;
    out << "(" 
	    << cards[d] 
            << "," 
            << cards[d+1] 
            << ")";
    return out.str();
}

void arg_parse(int argc, char *argv[]) {
    // process input parameters    
    int i=1;
    while(true) {
        if(i>=argc) break;    
        if(argv[i][0] == '-')
            switch(argv[i][1]) {
            case 'c': ncards = std::stoi(argv[++i]); break;
            case 'n': ndancers = std::stoi(argv[++i]); break;
            case 's': nsteps = std::stoi(argv[++i]); break;
            case 'd': debug = true; break;
            default: usage();
        } else usage();
        i++; // look for next arg
    }
}

void dance_step(int dancer, int step) {
    // this dancer needs to get happy!
    if(debug) std::cout << "\tstep: " 
            << step << " dancer " 
            << dancer << std::endl;
    // show current cards
    if(debug) std::cout << "\t  " 
            << show_step(dancer) << " --> ";
    // balance the cards
    // show the final cards
    if(debug) std::cout << show_step(dancer) << std::endl;
}

int main(int argc, char *argv[]) {
    // say hello
    std::cout << "Dance-Cards (v0.1)" << std::endl;
    arg_parse(argc, argv);
    if(debug) {
        std::cout << ndancers 
            << " dancers will dance " 
	    << nsteps << " steps" << std::endl;
        std::cout << "Initial card count is " 
            << ncards << std::endl;
    }
    // let the music begin!
    if(debug) std::cout << "Let the dance begin!" << std::endl;
    cards[0] = ncards;
    show_cards();
    for(int step=0; step<nsteps; step++) {
        for(int dancer=0; dancer<ndancers; dancer++){
            dance_step(dancer, step);
        }
        if(stable) {
            std::cout << "system is stable" << std::endl;
            break;
        }
        show_cards();
    }
}
        

This lab uses some coding techniques and style that is common these days. Take some time to read this example code over, and note how it is presented. We will pay more attention to style as the term progresses.

Submitting this Lab

Place this in your new labs-username repository as usual.

Debug Output

I added a debug switch (-d) for the command line, to generate debug output that shows how the individual “get happy” steps worked. Here is the debug output from the sample run shown above:

sample-run-debug
./dance -d
Dance-Cards (v0.1)
5 dancers will dance 10 steps
Initial card count is 6
Let the dance begin!
6 0 0 0 0 0 
	step: 0 dancer 0
	  (6,0) --> (3,3)
	step: 0 dancer 1
	  (3,0) --> (1,2)
	step: 0 dancer 2
	  (2,0) --> (1,1)
	step: 0 dancer 3
	  (1,0) --> (0,1)
	step: 0 dancer 4
	  (1,0) --> (0,1)
3 1 1 0 0 1 
the system is unstable
3 1 1 0 0 1 
	step: 1 dancer 0
	  (3,1) --> (2,2)
	step: 1 dancer 1
	  (2,1) --> (1,2)
	step: 1 dancer 2
	  (2,0) --> (1,1)
	step: 1 dancer 3
	  (1,0) --> (0,1)
	step: 1 dancer 4
	  (1,1) --> (1,1)
2 1 1 0 1 1 
the system is unstable
2 1 1 0 1 1 
	step: 2 dancer 0
	  (2,1) --> (1,2)
	step: 2 dancer 1
	  (2,1) --> (1,2)
	step: 2 dancer 2
	  (2,0) --> (1,1)
	step: 2 dancer 3
	  (1,1) --> (1,1)
	step: 2 dancer 4
	  (1,1) --> (1,1)
1 1 1 1 1 1 
the system is unstable
1 1 1 1 1 1 
	step: 3 dancer 0
	  (1,1) --> (1,1)
	step: 3 dancer 1
	  (1,1) --> (1,1)
	step: 3 dancer 2
	  (1,1) --> (1,1)
	step: 3 dancer 3
	  (1,1) --> (1,1)
	step: 3 dancer 4
	  (1,1) --> (1,1)
1 1 1 1 1 1 
the system is stable
system is stable