GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 24-Apr-2005, 14:58
cable_guy_67's Avatar
cable_guy_67 cable_guy_67 is offline
Senior Member
 
Join Date: Oct 2004
Location: Florina, Greece
Posts: 1,112
cable_guy_67 is a jewel in the roughcable_guy_67 is a jewel in the roughcable_guy_67 is a jewel in the roughcable_guy_67 is a jewel in the rough

Decks and Dice


I have been playing with some of the randomizing posts here and thought this might be of interest. The code here will all become part of some classes for decks and dice. I just want to see if there are any problems that I should be aware of before moving on (or just a better way to do it).

CPP / C++ / C Code:
// dice_deck.cpp
// This is a small set of functions for generating random numbers.
// I want to move these routines into classes thus the consts.
// All the const ints will become protected data members and relieve
// the passing of them.  The base class will be the random number
// stuff and the derived classes will be for a specific sided die
// or number of cards in the deck.
//
// dice_deck.cpp is free software. You can redistribute it and/or
// modify it as you see fit. If the shoe don't fit, get a bigger
// hammer. dice_deck.cpp is distributed in the hope that it will
// be useful, but WITHOUT ANY WARRANTY' without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>

using std::string;
using std::cin;
using std::cout;
using std::endl;

// Initalize random numbers using time()
// Call once before calling GenSeq() or GenSing()
void RndInit(){
  time_t	t;
  srand(time(&t));
}

// A private method used by GenSeq()
// It returns false if value exists in a array of ints
// or true if value is not found.
bool IsUnique(int* array, const int value, const int MAXVAL){

  for(int j = 0; j < MAXVAL; j++)
    if(array[j] == value) return false;
  return true;
}

// A public method that creates an array consisting of the
// values from MIN to MAX consisting of MAX-MIN+1 elements
// This will be part of the derived class Deck52.
void GenSeq(int* array,const int MIN,const int MAX){
  const int MAXVAL = (MAX-MIN)+1;
  bool found_new;
  int newcode;

  for (int j=0;j<MAXVAL;j++) array[j]=-1;

  for (int j = 0; j < MAXVAL; j++){
    found_new= false;
    while (!found_new){
      newcode = (rand() % MAXVAL) + MIN;
      if (IsUnique(array,newcode,MAXVAL)){
        array[j]=newcode;
        found_new = true;
      }
    }
  }
}

// A private method for obtaining a single value. It
// generates a single random value between MIN and MAX
// and places it in index[0] of the array.
// This will be part of the derived class Dice.
void GenSing(int* array,const int MIN,const int MAX){
  const int MAXVAL = (MAX-MIN)+1;
  array[0] = (rand() % MAXVAL) + MIN;
}

// A private method for displaying a deck of cards
// in four columns. Using the int array it will be
// a simple matter to use this for creating a randomly
// ordered deck.
void PrintSeq(int* array,const int MIN, const int MAX){
  const int COLS = 4;
  const int MAXVAL = (MAX-MIN)+1;
  cout<<endl<<"Generating unique and random set from "
      << MIN << " to " << MAX<<endl;
  for ( int idx=0; idx<MAXVAL;idx++){
    if ((idx%COLS)==0) cout<<endl<<'\t';
    cout<<array[idx]<< '\t';
  }
}

// A private method for displaying a dice roll.
void PrintDie(int* array){
  cout << "You rolled a " << array[0] << endl;
}

int main(){

  cout << endl << "Dice and Deck Generator" << endl;
  cout << "You can roll the dice or create a randomized deck of cards." << endl;
  cout << "Enter the Low and High then dice or deck for your number(s)" << endl;

  cout << "Enter the Low number  : ";
  string buffer;
  getline(cin, buffer);
  const int MINNUM = atoi(buffer.c_str());

  cout << "Enter the High number : ";
  getline(cin, buffer);
  const int MAXNUM = atoi(buffer.c_str());

  if ((MAXNUM-MINNUM)+1 < 1){
    cout << "You have entered an invalid range ... terminating";
    return 1;
  }
  const int NUMBERS = (MAXNUM-MINNUM)+1;
  int array[NUMBERS];
  RndInit();

  cout << "Would you like dice or a deck : ";
  getline(cin,buffer);

  if (buffer=="dice"){
    string input;
    do{
      GenSing(array,MINNUM,MAXNUM);
      PrintDie(array);
      cout << "Roll again y or n : ";
      getline(cin, input);
    }while(input == "y");
  }
  else if (buffer=="deck"){
    string input;
    do{
      GenSeq(array,MINNUM,MAXNUM);
      PrintSeq(array,MINNUM,MAXNUM);
      cout << endl << endl << "Deal again y or n : ";
      getline(cin, input);
    }while(input == "y");
  }
  else cout << "You must enter 'dice' or 'deck'" << endl;
  return 0;
} 

Anyhow, that's all there is to it. I thank the various posters that got me interested. I tried to adhere to the declare your variables if and only if you need them method as well as using the consts as I go so I could create the proper size array at runtime. Any and all sugestions for improvement are welcome!

Mark
__________________

"A happy person is not a person in a certain set of circumstances, but rather a person with a certain set of attitudes."
--Hugh Downs

Stories from the NICU Blog
  #2  
Old 24-Apr-2005, 19:31
ubergeek ubergeek is offline
Awaiting Email Confirmation
 
Join Date: Jan 2005
Posts: 775
ubergeek is a jewel in the roughubergeek is a jewel in the roughubergeek is a jewel in the rough
nice coding!

there is just one exceedingly minor thing I noticed as I was reading. In function RndInit():
CPP / C++ / C Code:
void RndInit(){
  time_t  t;
  srand(time(&t));
}
you don't actually have to give time() a variable to store the value in. you can just call time(NULL) and it will still return a value. this is simply an efficiency issue; you can avoid declaring a variable that you don't use anyways.
  #3  
Old 25-Apr-2005, 05:01
cable_guy_67's Avatar
cable_guy_67 cable_guy_67 is offline
Senior Member
 
Join Date: Oct 2004
Location: Florina, Greece
Posts: 1,112
cable_guy_67 is a jewel in the roughcable_guy_67 is a jewel in the roughcable_guy_67 is a jewel in the roughcable_guy_67 is a jewel in the rough
Quote:
Originally Posted by ubergeek
you don't actually have to give time() a variable to store the value in. you can just call time(NULL) and it will still return a value. this is simply an efficiency issue; you can avoid declaring a variable that you don't use anyways.

Cool, I have seen it both ways and didn't notice any difference in the output. I appreciate the feedback U...G..., now to wrap everything up in some handy dandy easy to use classes and get to work on the dice games!

Mark
__________________

"A happy person is not a person in a certain set of circumstances, but rather a person with a certain set of attitudes."
--Hugh Downs

Stories from the NICU Blog
  #4  
Old 30-Apr-2005, 18:00
cable_guy_67's Avatar
cable_guy_67 cable_guy_67 is offline
Senior Member
 
Join Date: Oct 2004
Location: Florina, Greece
Posts: 1,112
cable_guy_67 is a jewel in the roughcable_guy_67 is a jewel in the roughcable_guy_67 is a jewel in the roughcable_guy_67 is a jewel in the rough
Some changes mainly some simple classes to practice isa inheritance it seems.

CPP / C++ / C Code:
// RandomGen.h
// This is a small set of classes for generating random numbers.
// The derived classes with public constructors can be used to
// create specific sided dice or a deck of cards.
//
// RandomGen.h is free software. You can redistribute it and/or
// modify it as you see fit. If the shoe don't fit, get a bigger
// hammer. RandomGen.h is distributed in the hope that it will
// be useful, but WITHOUT ANY WARRANTY' without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

#if !defined __RandomGen_h__
#define __RandomGen_h__

class RandomGen {
  private:
    static bool seeded;

  protected:
    RandomGen();
    virtual ~RandomGen(){};
    virtual void RndInit();
    int RndGen(const int)const;
};

class Dice : public RandomGen {
  private:
    const int sides;
    int current_roll;
  protected:
    Dice(const int);
    virtual ~Dice(){};
  public:
    void Roll();
    int GetRoll();
    int GetSides();
};

class Dice2 : public Dice {
  public:
    Dice2():Dice(2){};
    ~Dice2(){};
};

class Dice6 : public Dice {
  public:
    Dice6():Dice(6){};
    ~Dice6(){};
};

class Dice10 : public Dice {
  public:
    Dice10():Dice(10){};
    ~Dice10(){};
};

class Dice20 : public Dice {
  public:
    Dice20():Dice(20){};
    ~Dice20(){};
};

class Dice100 : public Dice {
  public:
    Dice100():Dice(100){};
    ~Dice100(){};
};
#endif

CPP / C++ / C Code:
// RandomGen.cpp
// This is a small set of classes for generating random numbers.
// The derived classes with public constructors can be used to
// create specific sided dice or a deck of cards.
//
// RandomGen.cpp is free software. You can redistribute it and/or
// modify it as you see fit. If the shoe don't fit, get a bigger
// hammer. RandomGen.cpp is distributed in the hope that it will
// be useful, but WITHOUT ANY WARRANTY' without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

#include <cstdlib>
#include <ctime>
#include "RandomGen.h"

bool RandomGen::seeded(false);

RandomGen::RandomGen(){
  RndInit();
}

void RandomGen::RndInit(){
  if(seeded == false){
    srand(time(NULL));
    seeded = true;
  }
}

int RandomGen::RndGen(const int sides)const{
  return (rand() % sides) + 1;
}

Dice::Dice(const int s):sides(s){
  Roll();
}

int Dice::GetRoll(){
  return current_roll;
}

void Dice::Roll(){
  current_roll = RndGen(sides);
}

int Dice::GetSides(){
  return sides;
}

CPP / C++ / C Code:
// main.cpp is a test program for the classes defined
// in RandomGen.h and implemented in RandomGen.cpp

#include "RandomGen.h"
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::cin;
using std::string;

int main(){
  Dice20 die1;
  Dice100 die2;
  string input;

  do{
    cout << "Rolling dice" << endl;
    die1.Roll();
    die2.Roll();

    cout << "The value of die 1 is " << die1.GetRoll() << endl;
    cout << "The value of die 2 is " << die2.GetRoll() << endl;
    
    cout << endl << "Hit 'q' to quit " << endl;
    getline(cin,input);
  }while (input != "q");

  return 0;
}

compiled with:
Code:
g++ -Wall main.cpp RandomGen.cpp -s -o DiceTest
__________________

"A happy person is not a person in a certain set of circumstances, but rather a person with a certain set of attitudes."
--Hugh Downs

Stories from the NICU Blog
  #5  
Old 30-Apr-2005, 19:53
ubergeek ubergeek is offline
Awaiting Email Confirmation
 
Join Date: Jan 2005
Posts: 775
ubergeek is a jewel in the roughubergeek is a jewel in the roughubergeek is a jewel in the rough
sweet! I think I am going to have to take advantage of that "free software" clause! I am thinking of making a console-based (at least, console to begin with) RPG-like adventure game. I'll let you know how I fare.
  #6  
Old 10-Apr-2006, 15:44
davis
 
Posts: n/a

Re: Decks and Dice


Quote:
Originally Posted by cable_guy_67
Some changes mainly some simple classes to practice isa inheritance it seems.

While it may be true that a die is a "1 through n-sides random number generator," it isn't usually thought of as one.

In the case of your design, your RandomGen class provides no behavioral specification to the derived "Dice" class. Therefore, the relationship between RandomGen and Dice would better be handled through aggregation than inheritance. In fact, RandomGen's whole world is to init the random number seed and provide a "carefully guarded" interface to RndGen. When in reality, the utilitarian-ness of an RNG class would be fine as a standalone body of code, surely without the need to derive from it to gain that utility.

We find an overlapping of "responsibilities" in RandomGen::RndGen( const int sides );

...why would "sides" be used in a RNG operation? The "concept" of a "side" belongs to the "Dice" class. Sure, one can argue that it is just a name of an int than rand needs in order to produce something meaningful.

I'd probably change the interface so that Dice::Roll() returns an int equal to what GetRoll() would return. Why make the user use 2 operations when you know that all they want is the next random number? Also, in a multi-threaded world, two calls are going to mean a lot of headaches should the user somehow never call GetRoll after Roll, if blocking is required to protect the data value made during Roll.

I can see Dice having an instance of RNG in it and using it. I definitely do not understand the thinking behind a protected ctor that takes an int. What you're telling users is that they have to implement our own DiceN for every one that you decide not to support. For example, a D9 or D7, both common in D&D and similar "old fashioned" RPGs. And, to that extent, there is absolutely no reason why DNeg47 : public Dice { public: DNeg47()ice( -47 ){}; ~DNeg47(){};}; isn't perfectly legal.

What's the use of a public GetSides operation if the user had to use Dice6 d6; during construction? Let's see, I forgot how many sides a D6 has? The idea behind a GetSides is important when that value can be changed at the time of the object construction.

Generally, having to name a new type for every possible combination of integers is probably a bad design from the outset. Let's see:

D2,3,4,5,6,7,8,9,10...D100

Okay, that's great right until someone needs/wants a 114 sided dice. Granted, it may be unlikely, but why limit your code such?

When I take a look at the RNG class, I try to figure out what the benefit of the seeded bool is. It is always false on creation, so how is it ever going to be true without an instance of RNG? ...and won't every instance of RNG change it to true? RNG has no public ctors and only a protected no-args ctor, so only derived classes can even instantiate an RNG. This suggests all the "good inheritance" behavioral elements, but doesn't come through on any of them except by way of adding some "mechanics" to the code. In fact, it separates the concepts into dissimilar thinking patterns in a way that I don't think makes the code more useful, clearer or easier to understand/use.

Consider:

CPP / C++ / C Code:
RandomGen::RandomGen(){
  RndInit();
}

...why is this not:

CPP / C++ / C Code:
RandomGen::RandomGen(){
  srand(time(NULL));
}

Does anyone other than the ctor use "seeded?" Is seeded ever anything but false when entering the ctor?

Here are some changes you may want to consider:

CPP / C++ / C Code:
#ifndef _RNG_h_
#define _RNG_h_

#include <cstdlib>
#include <ctime>
using std::time;
using std::rand;
using std::srand;

class RNG {
  public:
    RNG();
    virtual ~RNG(){};
    int RndGen(const int)const;
};

class Dice {
  private:
    const unsigned int sides;
    RNG m_rng;
  public:
    Dice(const unsigned int);
    virtual ~Dice(){};
    int Roll();
    int GetSides();
};

#endif


CPP / C++ / C Code:

#include <RNG.h>

RNG::RNG(){
    srand(time(0));
}

int RNG::RndGen(const int max_value)const{
  return (rand() % max_value) + 1;
}

Dice::Dice(const unsigned int s):sides(s), m_rng(){
}

int Dice::Roll(){
  return m_rng.RndGen(sides);
}

int Dice::GetSides(){
  return sides;
}


CPP / C++ / C Code:
#include <RNG.h>
#include <iostream>
using namespace std;

int main()
{
    Dice d2( 2 );
    for( int i = 0; i < 100; i++ )
    {
        if( i > 0 && i % 10 == 0 )
        {
            cout << endl;
        }
        cout << d2.Roll() << " ";
    }
    cout << endl;

    Dice d1001( 1001 );
    for( int i = 0; i < 1001; i++ )
    {
        if( i > 0 && i % 10 == 0 )
        {
            cout << endl;
        }
        cout << d1001.Roll() << "\t";
    }
    cout << endl;

    return 0;
}


Code:
2 1 2 2 2 1 2 2 2 2 1 1 2 2 2 1 1 1 1 2 2 2 1 2 2 2 2 1 2 1 1 2 1 2 1 2 2 2 1 1 1 1 1 2 1 2 2 1 2 2 2 1 2 1 2 1 2 1 1 2 1 1 1 1 2 1 2 1 2 2 1 2 1 1 2 1 2 1 1 2 1 2 2 2 2 2 2 2 2 2 1 1 2 1 1 1 1 1 1 2 942 522 170 565 850 40 130 743 8 365 825 909 76 430 50 277 662 417 760 509 587 877 586 804 124 176 99 488 365 814 844 997 24 12 560 873 742 689 304 749 743 127 346 818 247 395 784 908 501 542 415 86 108 1001 579 231 866 677 718 921 179 560 916 202 261 474 764 1 852 66 439 593 884 784 100 129 868 883 35 368 114 449 143 221 138 722 451 3 87 858 923 266 106 837 157 366 1000 921 56 850 676 184 131 558 657 230 686 523 112 720 580 225 859 413 135 996 824 585 688 600 441 609 865 546 134 712 601 823 321 656 671 996 839 492 553 184 411 928 396 522 337 976 436 194 77 570 879 900 844 566 498 283 864 52 518 998 453 117 509 773 462 179 767 990 360 8 172 770 936 568 982 962 232 106 154 999 366 31 587 208 286 774 181 149 515 388 836 967 505 343 738 656 211 194 335 570 892 196 29 516 453 9 476 684 114 319 681 479 40 266 377 325 39 247 163 553 634 998 209 828 30 636 483 240 519 507 500 410 702 528 615 154 226 90 527 339 408 898 508 447 853 574 462 581 820 624 824 452 621 31 279 340 666 451 579 184 957 768 283 347 294 897 500 519 676 26 548 83 613 745 219 464 317 370 44 826 994 867 276 303 897 244 642 251 384 910 124 339 677 406 376 660 993 875 178 667 590 415 439 201 158 348 355 164 717 398 989 709 954 954 701 849 197 341 789 580 941 913 609 616 7 984 274 999 547 141 355 827 555 793 717 402 830 70 565 546 157 242 944 109 195 644 647 391 674 435 660 613 36 958 227 733 630 191 731 176 331 775 692 576 256 407 977 85 167 231 320 323 472 262 432 356 595 77 746 268 201 95 570 236 742 797 969 371 677 388 236 6 852 927 271 106 332 938 881 498 858 199 821 328 151 942 684 745 17 118 702 909 903 271 143 644 757 801 704 432 187 939 127 37 864 88 834 885 24 713 72 881 912 582 898 752 522 270 495 228 388 887 135 980 156 969 312 602 768 14 32 645 952 849 681 814 936 203 388 649 916 459 528 516 39 425 266 250 694 450 477 771 335 302 440 180 269 751 781 35 765 502 369 405 40 49 909 975 251 295 623 856 753 840 370 481 954 325 730 337 775 205 797 799 196 235 669 464 986 138 189 439 640 557 843 369 295 750 32 236 43 344 90 485 183 150 965 135 474 693 161 247 588 958 736 783 191 403 937 866 540 124 303 869 370 836 236 665 584 268 900 317 301 679 801 483 828 455 308 301 837 468 237 113 114 972 896 305 63 521 860 603 644 853 160 12 687 396 366 269 353 264 275 653 943 75 826 459 219 132 759 54 289 686 167 403 656 752 397 719 271 255 10 914 797 169 615 482 254 981 441 296 934 715 639 565 479 463 23 697 284 471 751 262 155 917 354 501 357 750 909 627 695 608 229 490 776 843 662 720 512 101 14 135 815 342 389 293 804 411 989 777 572 428 38 726 343 391 916 389 831 823 14 214 429 242 703 895 775 363 613 976 153 316 109 968 658 498 950 150 598 937 617 859 54 654 274 86 734 188 475 253 701 488 466 819 730 859 712 193 911 13 167 63 19 967 720 366 153 668 515 440 293 130 298 346 473 571 432 897 448 906 148 147 82 304 656 501 161 56 693 761 69 550 513 778 515 231 142 357 588 346 486 881 476 783 916 638 42 36 533 180 941 371 16 713 364 671 212 214 727 595 974 795 143 486 261 347 716 402 393 303 747 878 873 912 660 787 239 391 823 771 570 452 831 586 854 193 255 65 406 981 659 69 464 491 554 414 837 959 815 228 951 251 104 512 161 453 989 89 534 500 550 102 641 379 377 494 262 322 558 357 992 906 425 145 395 668 558 230 316 372 147 956 312 250 467 162 393 454 251 926 643 800 26 282 868 93 775 128 414 331 485 404 926 599 548 319 957 105 238 271 166 384 225 477 324 381 638 716 524 578 640 165 376 355 447 243 447 220 60 550 241 234 954 165 833 190 484 788 985 411 748 149 795 972 315 117 42 643 832 565 219 160 730 595 514 175 527 651 84 586 199 324 510 842 179 31 31 352 508 14 762 254 854 555 915 167 361 956 809 882 520 718 40 939 311 244 803 527 584 886 802 782 900 310 313 77 340 33 428 847 46 879 790 589 123 704 756 483 658 253 364 867 970 93 494 970 336 295 495 919 180 987 390 78 295 702 845 325 424 962 861 469 839 650 748 651 352 502 133 699 444 186 255 413 278 748 71 304 42 256 912 912 241

...now there is no reasonable limit to the number of sides a D may have and you don't need to maintain a bunch of duplicate code for each Dn that you want to be able to offer.

Of course, I may not have considered all of your design requirements, so let me know if this doesn't work for your needs.


:davis:
  #7  
Old 11-Apr-2006, 20:24
swarm32 swarm32 is offline
New Member
 
Join Date: Mar 2006
Location: VA or VT
Posts: 5
swarm32 is on a distinguished road

Re: Decks and Dice


Nice to see I'm not the only one thinking on this problem. I've been working on this class file for awhile now. It is designed to make rolls on strings based on YdX format used for roleplaying.

dice.h
CPP / C++ / C Code:
//Swarm32
//dice.h
//02_21_2006 

#include<iostream>
#include<cstdlib>
#include<fstream>
#include<ctime>
#include<string>
using namespace std;

class dice
{
    public:
        dice();
        ~dice();
        int roll(int); // Rolls a die with X sides
        void xdx(string &input); //Rolls Z, X sided die
        int xdx_sum(string input); //Sums the output of Z, X sided die
//        double xdx_math(string input); //Does linear math of using dice
    private:
        int N, rolls;
        
};


dice::dice() // class constructor
{
	int i, j;
	
	N=0;
	
	srand( (unsigned)time( NULL ) ); //creates new seed from system clock
	for (i=0; i <100; i++)
	   j=rand();
	
}

dice::~dice() // class destructor
{
	// insert your code here
}

int dice::roll(int x) //rolls a "die" with x sides
{
    int j;
    N = x;
    j = (int) N * rand() / (RAND_MAX + 1.0);
    
    return j;
}

void dice::xdx(string &input) //rolls X, Y sided die
{
    int i=0, isd=0, length=0, sides=0, die=0;
    string temp;
    string numd, sided;
    
    length = input.length();
    for(i=0; i<length; i++) //anylyses the string for necessary info
    {

        switch(input[i]) //Determines if its time to switch to interpreting
                         //the number of sides
        {
            case 'd':
            case 'D':
                isd=1;
                i++;
                break;
            default:
                ;
        }
                
        switch (isd) 
        {
            case 0: //tells add to the number of dice
                temp=input[i];
                numd.append(temp);
                break;
            case 1: //tells it to add to the number of sides
                temp=input[i];
                sided.append(temp);
                break;
            default:
                cout << "error in input";
        }

                        
    }
    
    sides = atoi( sided.c_str() ); //Translates necessary strings into integers
    die = atoi( numd.c_str() );
        
    int rolled[die+3];   //intializes die
    for(i=0; i<die; i++)
    {
        rolled[i]=roll(sides);
        cout << rolled[i] << "\n";
    }
        
/*    rolled[die]=-1; //intended for debug, return to main capability
    rolled[die+1]= sides;
    rolled[die+2]= die;
*/
}

int dice::xdx_sum(string input) //sums the rolls of X, Y sided die
{
    int i=0, isd=0, length=0, sides=0, die=0, sum=0;
    string temp;
    string numd, sided;
    
    length = input.length();
    for(i=0; i<length; i++)
    {

        switch(input[i])//Determines if its time to switch to interpreting
                         //the number of sides
        {
            case 'd':
            case 'D':
                isd=1;
                i++;
                break;
            default:
                ;
        }
                
        switch (isd)
        {
            case 0: //tells add to the number of dice
                temp=input[i];
                numd.append(temp);
                break;
            case 1: //tells it to add to the number of sides
                temp=input[i];
                sided.append(temp);
                break;
            default:
                cout << "error in input";
        }

                        
    }
    
    sides = atoi( sided.c_str() ); //Translates necessary strings into integers
    die = atoi( numd.c_str() );
        
    int rolled[die+3];   //intializes die
    for(i=0; i<die; i++)
    {
        rolled[i]=roll(sides);
//        cout << rolled[i] << "\n";
    }
        
    rolled[die]=-1;
    rolled[die+1]= sides; //intended for debug
    rolled[die+2]= die; //inteded for debug
    i=0;
    while(rolled[i]!=-1) //does actuall summing
    {
        sum=sum+rolled[i];
        i++;
    }

    return(sum);
}
  #8  
Old 11-Apr-2006, 21:05
WaltP's Avatar
WaltP WaltP is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Midwest US
Posts: 3,435
WaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to all

Re: Decks and Dice


Mark,
One thing I noticed that is a minor point but you may find easier to deal with eventually is your deck setup/initialization. As a magician I'm hyper-aware of how cards work as a deck so I though I'd toss this at you.

Your GenSeq() function both initializes and randomizes a deck. You might want to consider a more real world scenario and split the deck manipulation into
1) Initialization
2) Shuffle
Assuming a normal deck of cards, initialization could simply be loading the new deck with sequential values. This closely simulates a brand new unopened deck to start. Your function could in fact be used to assume a used deck to start with. Call once, like srand().

Then implement a shuffle function which could mimic a riffle and/or overhand shuffle for more realistic manipulation. These two are probably the most used shuffles. Simply randomizing the deck as most programs seem to do does not take into account the dynamics that shuffling offers. Which is a moot point if you don't really care -- which is just as acceptable...
__________________

Definition: Politics
Latin, from
poly meaning many and
tics meaning blood sucking parasites
-- Tom Smothers
  #9  
Old 12-Apr-2006, 06:09
cable_guy_67's Avatar
cable_guy_67 cable_guy_67 is offline
Senior Member
 
Join Date: Oct 2004
Location: Florina, Greece
Posts: 1,112
cable_guy_67 is a jewel in the roughcable_guy_67 is a jewel in the roughcable_guy_67 is a jewel in the roughcable_guy_67 is a jewel in the rough

Re: Decks and Dice


Thanks for the feedback everyone.

Walt, when I did this last year it was because of a bunch of randomization posts that were going on at the time. IIRC you posted some links talking about what is a shuffle and discussed it a bit. I like your idea of "opening a new box" with the constructor and then going through the physical process. I'm going to have to revisit those and see what a year has done for my thought process.

davis, when I was playing with this last year I was thinking along the lines of how I would use the class. I wasn't so much interested in the N-sided class, but the final concrete classes that would depict a particular object (in my case a 6 sided die) in a way I could wrap my brain around. I'll have to go through your reply a bit more to see if I have any questions based on that when I get a chance.

Mark
__________________

"A happy person is not a person in a certain set of circumstances, but rather a person with a certain set of attitudes."
--Hugh Downs

Stories from the NICU Blog
  #10  
Old 12-Apr-2006, 08:32
QED's Avatar
QED QED is offline
Member
 
Join Date: Feb 2005
Location: Hudson Valley, NY
Posts: 231
QED is a jewel in the roughQED is a jewel in the roughQED is a jewel in the rough

Re: Decks and Dice


Another idea building off of davis' code:
CPP / C++ / C Code:
template <unsigned int SIDES>
class Dice {
public:
  Dice() {}
  virtual ~Dice() {}
  int roll();
  int getSides() const;
private:
  RNG m_rng;
};
CPP / C++ / C Code:
template <unsigned int N_SIDES>
int Dice<N_SIDES>::roll()
{
  return m_rng.rndGen(N_SIDES);
}

template <unsigned int N_SIDES>
int Dice<N_SIDES>::getSides() const
{
  return N_SIDES;
}

I couldn't help uncapitalizing the first letters of method names, would you believe I actually have a hard time reading it the other way? Just locked into familiar styles, I guess. I also added a const qualifier to the getSides method, as we wouldn't expect the Dice to change in any way after simply checking the number of sides (Heisenberg anyone? ).

Matthew

P.S. I forgot to mention, you might also find it convenient to add the following:
CPP / C++ / C Code:
typedef Dice<4> Dice4;
typedef Dice<6> Dice6;
typedef Dice<8> Dice8;
typedef Dice<10> Dice10;
typedef Dice<12> Dice12;
typedef Dice<20> Dice20;
__________________
I was born not knowing and have only had a little time to change that here and there. -- Richard P. Feynman

Boris Podolsky: James! How's the rat business?
James Moreland: Well, actually it's mostly students I'm experimenting on now.
Kurt Gödel: My God, the mazes must be enormous.
 


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Network Sites: GIDNetwork · GIDApp · GIDBlog · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 21:55.


vBulletin, Copyright © 2000 - 2017, Jelsoft Enterprises Ltd.