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 -s 10 -n 5 -c 10
Dance-Cards (v0.1)
10 0 0 0 0 0 
5 2 1 1 0 1 
3 2 2 1 1 1 
2 2 2 1 1 2 
2 2 1 1 2 2 
2 1 1 2 2 2 
1 1 2 2 2 2 
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
#include <iostream>
#include <string>
#include <sstream>

// defaults
const int MAX_STEPS = 100;
const int MAX_DANCERS = 20;
const int INIT_STEPS = 10;
const int INIT_DANCERS = 5;
const int INIT_CARDS = 6;

// globals are UGLY!
int cards[MAX_DANCERS+1] = {0};
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-Cards (v0.1)
5 dancers will dance 10 steps
Initial card count is 10
Let the dance begin!
10 0 0 0 0 0 
	step: 0 dancer 0
	  (10,0) --> (5,5)
	step: 0 dancer 1
	  (5,0) --> (2,3)
	step: 0 dancer 2
	  (3,0) --> (1,2)
	step: 0 dancer 3
	  (2,0) --> (1,1)
	step: 0 dancer 4
	  (1,0) --> (0,1)
5 2 1 1 0 1 
	step: 1 dancer 0
	  (5,2) --> (3,4)
	step: 1 dancer 1
	  (4,1) --> (2,3)
	step: 1 dancer 2
	  (3,1) --> (2,2)
	step: 1 dancer 3
	  (2,0) --> (1,1)
	step: 1 dancer 4
	  (1,1) --> (1,1)
3 2 2 1 1 1 
	step: 2 dancer 0
	  (3,2) --> (2,3)
	step: 2 dancer 1
	  (3,2) --> (2,3)
	step: 2 dancer 2
	  (3,1) --> (2,2)
	step: 2 dancer 3
	  (2,1) --> (1,2)
	step: 2 dancer 4
	  (2,1) --> (1,2)
2 2 2 1 1 2 
	step: 3 dancer 0
	  (2,2) --> (2,2)
	step: 3 dancer 1
	  (2,2) --> (2,2)
	step: 3 dancer 2
	  (2,1) --> (1,2)
	step: 3 dancer 3
	  (2,1) --> (1,2)
	step: 3 dancer 4
	  (2,2) --> (2,2)
2 2 1 1 2 2 
	step: 4 dancer 0
	  (2,2) --> (2,2)
	step: 4 dancer 1
	  (2,1) --> (1,2)
	step: 4 dancer 2
	  (2,1) --> (1,2)
	step: 4 dancer 3
	  (2,2) --> (2,2)
	step: 4 dancer 4
	  (2,2) --> (2,2)
2 1 1 2 2 2 
	step: 5 dancer 0
	  (2,1) --> (1,2)
	step: 5 dancer 1
	  (2,1) --> (1,2)
	step: 5 dancer 2
	  (2,2) --> (2,2)
	step: 5 dancer 3
	  (2,2) --> (2,2)
	step: 5 dancer 4
	  (2,2) --> (2,2)
1 1 2 2 2 2 
	step: 6 dancer 0
	  (1,1) --> (1,1)
	step: 6 dancer 1
	  (1,2) --> (1,2)
	step: 6 dancer 2
	  (2,2) --> (2,2)
	step: 6 dancer 3
	  (2,2) --> (2,2)
	step: 6 dancer 4
	  (2,2) --> (2,2)
system is stable