next up previous
Next: Virtuelle Funktionen Up: Folien zur AG Objektorientiertes Previous: CGI-Beispiel

Greed-Game (ASCII-Version)

Das folgende Programm soll Ihnen die Funktionsweise des Spiels nochmals näherbringen. Das Programm sollte zumindest um die Klasse Player erweitert werden (es können dann mehr als zwei Personen spielen).

die.h

#include <iostream.h>

extern "C" 
{
  #include <stdlib.h>
  #include <time.h>
}
const int FACES = 6;

class Die
{
public:
  Die(int spots=0);
  void Roll();
  int GetSpots();
private:
  int the_spots;
};

die.cc

#include "die.h"

Die::Die(int spots)
{
  the_spots = spots;
}

void Die::Roll()
{
  //srandom( time(NULL) ); // für main()
  the_spots = 1 + random() % FACES;
}

int Die::GetSpots()
{
  return the_spots;
}

roll.h

#include "die.h"

const int MAXDICE = 5;

// Klasse für einen Würfelvorgang
class Roll
{
public:
  Roll(int num=MAXDICE); // Runde 
  ~Roll();
  int DiceLeft();
  int FindScore();
  friend ostream& operator << (ostream&, Roll&);
private:
  Die *dice;
  int numDice;
  int score;
  int distribution[FACES+1];
  int unscoredDistribution[FACES+1];
};

roll.cc

#include "roll.h"

Roll::Roll(int num)
{
  dice = new Die [num];
  for (int i = 0; i < num; i++)
  {
    dice[i].Roll();
  }
  numDice = num;
  for (int j = 0; j <= FACES; j++)
    unscoredDistribution[j] = distribution[j] = 0;
}

Roll::~Roll()
{
  // cerr << "desctructor for a object of type Roll called" << endl;
  // cerr << *this << endl;
  delete [] dice;
}

int Roll::FindScore()
{
  int spots;

  score = 0;
  for (int i = 0; i < numDice; i++)
  {
    spots = dice[i].GetSpots();
    distribution[spots]++;
    unscoredDistribution[spots]++;
  }

  for (int j = 1; j <= FACES;  j++)
  {
    int k = distribution[j];    
    if (k >= 3) // triples
    {
      switch(j)
      {
      case 1:
        score += 1000;
        break;
      case 2:
      case 3:
      case 4:
      case 5:
      case 6:
        score += 100 * j;
        break;
      default:
        break;
      }
      k -= 3;   
      unscoredDistribution[j] = k;
    }

    if (k > 0) // singles
    {
      switch(j)
      {
        case 1: 
                score += 100 * k;       
                unscoredDistribution[j] -= k;
                break;
        case 5: 
                score += 50 * k;        
                unscoredDistribution[j] -= k;
                break;
        default: 
                break;
      } 
    }
  }
  return score;
}

int Roll::DiceLeft()
{
  int num = 0;
  for (int j = 1; j <= FACES;  j++)
        num += unscoredDistribution[j];
  return num;
}

ostream& operator << (ostream &s, Roll &r)
{
        for (int i = 0; i < r.numDice; i++)
                s << r.dice[i].GetSpots() << " ";
        return s;
}

main.cc

#include "roll.h"

int main()
{
  srandom( time(NULL) );
  
  int scoreA = 0, scoreB = 0, i = 0, cont;
  int repeatA = 0, repeatB = 0, currA, currB, leftB;
  char ask;     
  Roll *tmp, *rA = NULL, *rB = NULL;
        
  cout << "Wer fängt an: Ich=i oder HAL=h ?  ";
  cin >> ask;
  switch (ask)
  {
  case 'i':
  case 'I':
    ask = 'i';
    break;
  case 'h':
  case 'H':
    ask = 'n';
  }
  cont = 1;

  while(1)
  {
    if (!cont) 
    {
      cout << "Der Nächste=n Nochmals würfeln=r Spiel beenden=q  ? ";
      cin >> ask;
    }
    
    switch (ask)
    {
    case 'q':
    case 'Q':
      if (rA) delete rA;
      if (rB) delete rB;
      exit(0);
      break;
    case 'r':
    case 'R':
      repeatA = 1;
    case 'i':
      cout << "Roll " << ++i << ":" << endl;
      tmp = rA;
      if (ask == 'i')
        rA = new Roll();
      else
      {
        rA = new Roll(rA->DiceLeft());
        repeatA = 1;      
      }
      delete tmp;
      currA = rA->FindScore();
      if ((repeatA) && (!currA))
      {
        scoreA = 0;
        ask = 'n';
        cont =1;
      }
      else
      {
        scoreA += currA;
        cont = 0;
      }
      cout << "\tRoll set for A: " 
           << *rA << "Current: " << currA
           << " Score: " << scoreA << endl;
      repeatA = 0;
      if (scoreA >= 5000)
      {
        cout << "HAL hat verloren" << endl;
        exit(0);
      }
      break;
    case 'n':
    case 'N':
      cout << "Roll " << ++i << ":" << endl;
      leftB = MAXDICE;
      do 
      {
        tmp = rB;
        rB = new Roll(leftB);
        currB = rB->FindScore();
        if (tmp) delete tmp;
        if ((!currB) && (repeatB))
          scoreB = 0;
        else
          scoreB += currB;
        cout << "\tRoll set for B: "
             << *rB << "Current: " << currB 
             << " Score: " << scoreB << endl;
        if (scoreB >= 5000)
        {
          cout << "Sie haben verloren" << endl;
          exit(0);
        }
        repeatB = 1;
      } while (((leftB = rB->DiceLeft()) > 2) && (currB)); 
      // Strategie
      cont = 1;
      ask = 'i';
      repeatB = 0;
      break;    
    default:
      cerr << "Unbekannte Eingabe!!" << endl;
      break;
    }
  }
  return 0;
}


next up previous
Next: Virtuelle Funktionen Up: Folien zur AG Objektorientiertes Previous: CGI-Beispiel

© 1997 Gottfried Rudorfer, C++-AG, Lehrveranstaltungen, Abteilung für Angewandte Informatik, Wirtschaftsuniversität Wien, 3/19/1998