Homepage Ralf BürgerSSEAnhang > Hutspiel Ralf Bürger SSE Hutspiel Inhaltsverzeichnis Index Vorseite Folgeseite
 

Auf dem Friedhof sah ich drei neue Gräber.
 Auf einem Grabstein stand: "Hier ruht Salvatore, der Hütchenspieler."
  Auf dem zweiten: "... oder hier?"
   Auf dem dritten: "... oder hier?"

Hutspiel


Ich warne deutlich vor der Teilnahme an einem echten Hütchenspiel um Geld. Sie haben gegen die Trickbetrüger keine Chance und werden verlieren! Deshalb ist dieses Spiel in der Öffentlichkeit auch verboten!

Dieses kleine Programm habe ich aus Jux während eines C-Kurses mit den Teilnehmern gemeinsam entwickelt. Wir haben dabei viel Wert auf eine systematische Vorgehensweise gelegt. Wer mich kennt, der weiß, dass ich kein Command-Line-Junkie bin; ich wollte hier aber zeigen, dass selbst nur mit dem vi (ein sehr spartanischer UNIX-Editor) als Tool systematisch und in kurzer Zeit entwickelt werden kann. Übersetzt haben wir die Programmquelle mit dem GNU C-Compiler der Linux-Distribution RedHat 7.0.

Gemäß dieser Abhandlung haben wir das Problem über den Namen, den Zielsatz, einem kleinen Fachkonzept, einer Sammlung der fachlichen und technischen Anforderungen, einem Zweck- und Tragweiten-Diagramm, einer Sammlung von Anwendungsfällen, einem Aktivitätendiagramm mit konzeptioneller, spezifizierender und implementierender Sicht, einer Datensammlung und schließlich einer Schnittstellenbeschreibung herunter gebrochen - wohlbemerkt, alles im vi!

Das eigentliche Programmieren bestand nachher nur noch aus einem Herunterschreiben der Schnittstellen als Funktionen, dem Ausfüllen der Funktionen mit den Informationen aus der implementierenden Sicht des Aktivitätendiagramms, dem Deklarieren der gesammelten Daten sowie dem weiteren Ausfüllen der Funktionen.

Der große Bagatello

Die Teilnehmer des Kurses waren überrascht, dass der Compiler nach nur zwei unbedeutenden Syntaxfehlern durchlief und das Programm dann auf Anhieb funktionierte ;-) Es ist zwar ein super kleines Programm, aber keiner hatte erwartet, dass die gesamte Entwicklung dieses Spielchens live im Kurs nur drei Stunden dauern würde (und die Dokumentation ist integriert!).


/*

SOFTWARE SYSTEM NAME:
SoftHat

MAIN GOAL:
SoftHat is a game where someone wants to lose money to the machine.

USER SPECIFICATION:
A fix account of 100 bucks is assumed. A user places the money onto the desk and guesses under
which of 3 hats the ball resides. Some strange guy is mixing the hats very quickly and the player
has to decide under which hat the ball might be. If he's right he get's the money he placed onto
the desk doubled; if he's wrong he loses his money. Then he might play again to get rich or poor.

BUSINESS REQUIREMENTS:
starting money account of 100 bucks
some money
3 hats
1 ball
mixing algorithm
1 player (the 2nd one is the machine)
player guesses
account modification (more if won, less if lost)
decision for continuation

TECHNICAL REQUIREMENTS:
implementation on some linux systems
C-language
executable on standard Intel machines

PURPOSE AND SCOPE DIAGRAM:

           pays money                    +-------------------------+
     O   ---------------------------->   |                         |
    /|\    guesses ball position         |   System Under Design   |
     |   ---------------------------->   |                         |
    / \    mixes hats                    |                         |
         <----------------------------   |                         |
           gives results                 |                         |
         <----------------------------   |                         |
                                         +-------------------------+

BUSINESS USE CASES:
<Rule>: User is named "player"
UC1 Player pays money
UC2 Player guesses ball position
UC3 Player decides for next turn

SYSTEM USE CASES:
UC4 System sets starting account
UC5 System mixes the hats
UC6 System proofs result
UC7 Player gets payed back doubled
UC8 Player looses his money

DERIVED USE CASES:
UC9 SYSTEM: Welcome-message
UC10 SYSTEM: Display starting account
UC11 SYSTEM: increments the account by the doubled money
UC12 SYSTEM: decrements the account by the money

USE CASE DESCRIPTIONS:
UC5 System mixes the hats
 This use case should have an algorithm for generating a ball position
 (i.e. a hat number) randomly. We may use the system time in milliseconds
 as a base to generate a really new number every time.

USE CASE ORDER:
UC9 UC4 UC10 UC1 UC5 UC2 UC6 UC7(UC11)/UC8(UC12) UC3

ACTIVITY DIAGRAM:

                          conceptual                   specifications                  implementation
^
|              +---------------------------------+
|              | UC9: Welcome-message            |     "Hy, I'm SoftHat."              printf (...);
|              +---------------------------------+
|                              |
|                              |
|                              V
Banner()       +---------------------------------+
|              | UC4: set starting account       |     set variable "Account"          int iAccount = 100
|              +---------------------------------+
|                              |
|                              |
|                              V
|              +---------------------------------+
|              | UC10: display starting account  |     "You have n bucks."             printf ("... %d ... \n", iAccount);
|              +---------------------------------+
V                              |
         +-------------------->|                                                       do {
^        |                     V
|        |     +---------------------------------+
Pay()    |     | UC1: pay money                  |     set variable "Money"            int iMoney;
|        |     +---------------------------------+                                     scanf ("%d", &iMoney);
V        |                     |
         |                     |
^                              V
|              +---------------------------------+
Mix()          | UC5: mixing                     |     set variable "Position"         srand (time (NULL));
|              +---------------------------------+     by randomizing algorithm        int iPosition = (rand()%3)+1
V                              |
                               |
^                              V
|              +---------------------------------+
Guess()        | UC2: guess                      |     set variable "Choice"           int iChoice;
|              +---------------------------------+                                     scanf ("%d", &iChoice);
V                              |
                               |
^                              V
|              +---------------------------------+
|             <  UC6: proof result (equal?)       >    "Position" equal to "Choice"?   if (iPosition == iChoice)
|              +---------------------------------+
|                             / \ 
|                          y /   \ n
|                           /     \
|                          /       \
|                         V         V
Proof()    +-----------------+     +-----------------+
|          | UC7: pay back   |     | UC8: loose      | modify variable "Account"
|          +-----------------+     +-----------------+
|                   |                       |
|                   |                       |
|                   V                       V
|          +-----------------+     +-----------------+
|          | UC11: increment |     | UC12: decrement | increment variable "Account"    iAccount += iMoney;
|          |       account   |     |       account   | or decrement variable "Account" iAccount -= iMoney;
|          +-----------------+     +-----------------+
V                        \             /
                          \           /
^                          V         V
|              +---------------------------------+
Decide()      <  UC3: decision                    >                                    char cAnswer;
|              +---------------------------------+                                     scanf ("%c", &cAnswer);
V                        /     |
         ^        replay/      |exit
         |             /       |
         +------------         V                                                       } while (cAnswer == 'y');


DATA:
int iAccount;   used by: Banner(), Proof()
int iMoney;     used by: Pay(), Proof()

INTERFACES:
void Banner(int *piAccount);
void Pay(int *piMoney);
int Mix(void);      returns iPosition 
int Guess(void);    returns iChoice 
void Proof(int iPosition, int iChoice, int *piAccount, int iMoney);
int Decide(void);   returns 1 for continue and 0 for exit

GLOSSAR:
Player: is the user using the program, i.e. the player playing the game
*/


#include "stdio.h"
#include "stdlib.h"
#include "time.h"

#define ACCOUNT 100

void Banner(int *piAccount);
void Pay(int *piMoney);
int Mix(void);     /* returns iPosition */
int Guess(void);   /* returns iChoice */
void Proof(int iPosition, int iChoice, int *piAccount, int iMoney);
int Decide(void);  /* returns 1 for continue and 0 for exit */

int main () {
    int iAccount;
    int iMoney;

    Banner (&iAccount);
    do {
        Pay (&iMoney);
        Proof (Mix (), Guess (), &iAccount, iMoney);
    } while (Decide () == 1);
    return 0;
}


void Banner(int *piAccount) {
    printf ("Hy, I'm SoftHat.\n");
    printf ("You have %d bucks.\n", *piAccount = ACCOUNT);
}

void Pay(int *piMoney) {
    printf ("How much money do you want to lose ;-) ");
    scanf ("%d", piMoney);
    printf ("\n");
}

int Mix(void) {
    srand ((unsigned)time (NULL));
    return (rand() % 3) + 1;
}

int Guess(void) {
    int iChoice;

    do {
        printf ("Where is the ball? (1,2,3) ");
        scanf ("%d", &iChoice);
        printf ("\n");
    } while (iChoice < 1 || iChoice > 3);

    return iChoice;
}

void Proof(int iPosition, int iChoice, int *piAccount, int iMoney) {
    if (iPosition == iChoice) {
        /* matches means: player found our ball */
        *piAccount += iMoney;
        printf ("$$$ Congratulations $$$\n");
    } else {
        /* no match means: player missed it */
        *piAccount -= iMoney;
        printf ("--- Sorry, you missed it ---\n");
    }
    printf ("Your current account is: %d bucks\n", *piAccount);
}

int Decide(void) {  /* returns 1 for continue and 0 for exit */
    char cAnswer;

    do {
        printf ("Do you wanna play again? (y/n) ");
        scanf ("%c", &cAnswer);
        printf ("\n");
    } while (cAnswer != 'y' && cAnswer != 'n');

    return cAnswer == 'y' ? 1 : 0;
}


Homepage Ralf Bürger Ralf Bürger SSE Hutspiel Konventionen/Hilfe Änderungen/Neues Inhaltsverzeichnis Index Vorseite Folgeseite Seitenanfang