Hi, I am fairly new to C++ but love to learn, so I wanted to create a simple program base on the group-party game mafia A.K.A "werewolf."

Just so whoever is not familiar gets the background. I will use just an example of 10 players. In a ten player game, there consists of 4 roles and this is how many there will be in the game:

3 Mafia
1 Cop
1 Doctor
5 Innocent

I figured I would assign those roles "randomly" to each player using those limits. So

0= mafia, 1= cop, 2= doctor, and 3 = innocent

I got somewhat of the code running ok only when generating a 3 player game. I only know how to use a bunch of "IF's" statement, if anyone knows how to make things easier, please feel free to teach me. When I try to compile a 10 player game, after getting all the player's names, the program just goes to a blank new line and nothing happens.

int main()
{
   int numOfPlayers = getNumOfPlayers();
   char playerName[numOfPlayers][256];

   //getPlayerName(numOfPlayers, playerName);
   getPlayerName(numOfPlayers, playerName);

   int player[10];

   //assign the roles to the players
   assignRoles(numOfPlayers, player);

   return 0;
}

int getNumOfPlayers()
{
   int numOfPlayers;
   cout << "How many players are there? ";
   cin >> numOfPlayers;

   return numOfPlayers;
}

char getPlayerName(int numOfPlayers, char playerName[][256])
{
  for(int count = 0; count < numOfPlayers; count++)
    {
      cout << "Please enter the players name: ";
      cin >> playerName[count];
    }
}

int assignRoles(int numOfPlayers, int player[])
{
  int mafia = 0;
  int cop = 0;
  int doc = 0;
  int innocent = 0;

  srand ( time(NULL) );

  for (int i = 0; i < numOfPlayers; i++)
        {
        if (mafia < 3 && cop < 1 && doc < 1)
          {player[i] = rand() % 4;

        switch(player[i])
              {
              case 0:
              mafia++;
              break;

              case 1:
              cop++;
              break;

              case 2:
              doc++;
              break;

              case 3:
              innocent++;
              }
          }
        else    if (mafia < 3 && cop == 1 && doc < 1)
    {
            do (player[i] = rand() % 4);
            while(player[i] != 1);

        switch(player[i])
              {
              case 1:
              mafia++;
              break;

              case 2:
              cop++;
              break;

              case 3:
              doc++;
              break;

              case 4:
              innocent++;
              }
          }
 else  if (mafia < 3 && cop < 1 && doc ==  1 )
          {
            do (player[i] = rand() % 4);
            while(player[i] != 2);

        switch(player[i])
              {
              case 1:
              mafia++;
              break;

              case 2:
              cop++;
              break;

              case 3:
              doc++;
              break;

              case 4:
              innocent++;
             }
          }

  else  if (mafia == 3 && cop < 1 && doc < 1 )
          {
            do (player[i] = rand() % 4);
            while(player[i] != 0);

        switch(player[i])
              {
              case 1:
              mafia++;
              break;

              case 2:
              cop++;
              break;

              case 3:
              doc++;
              break;
              case 4:
              innocent++;
              }
          }

  else   if (mafia == 3 && cop == 1 && doc < 1)
          {
            do (player[i] = rand() % 4);
            while((player[i] != 0) || (player[i] != 1));

        switch(player[i])
              {
              case 1:
              mafia++;
              break;

              case 2:
              cop++;
              break;

              case 3:
              doc++;
             break;

              case 4:
              innocent++;
              }
           }

  else  if (mafia == 3 && cop < 1 && doc == 1 )
          {
            do (player[i] = rand() % 4);
            while((player[i] !=0) || (player[i] != 2));

        switch(player[i])
              {
              case 1:
              mafia++;
              break;

              case 2:
              cop++;
              break;
            case 3:
              doc++;
              break;

              case 4:
              innocent++;
              }
          }

  else  if (mafia < 3 && cop == 1 && doc == 1)
          {
            do (player[i] = rand() % 4);
            while((player[i] != 1) || (player[i] != 2));

        switch(player[i])
              {
              case 1:
              mafia++;
              break;

              case 2:
              cop++;
             break;

              case 3:
              doc++;
              break;

              case 4:
              innocent++;
              }
          }
        }

   cout << "There are " << mafia << " mafias" << endl;
   cout << "There are " << cop << " cops" << endl;
   cout << "There are " << doc << " doctors" << endl;
   cout << "There are " << innocent << " innocent" << endl;

   return 0;
}

So basically, playerName[0] will be player[0],
playerName[1] will be player[1],

Oh, This user will be playing this as playerName[0], and the rest of the players will be computers.

The game continues in 2 Phases, a NIGHT time, and a DAY time.

During the NIGHT time, the mafia's will choose first who do they want to "kill, or get rid of" How should I write it that the mafia's will know who each other is, and if all the mafias are computers, they will randomly choose a person to kill other than mafias. If there is a 1 to 1 ness where more people are chosen, then it loops until there is a majority vote. They can only kill 1 per NIGHT time. The Cop then gets to choose who to investigate and find out their ROLES, this knowledge comes in handy. The Doctor, gets to choose who does he want to heal, which will negate the kill of a mafia if the same person gets chosen.

DAY TIME:
The revealed person whom the Mafia choose is announced dead.
Everyone Gets to vote who they think is the mafia. Of course mafias won't vote for mafias, and the COP will know who is innocent so he won't vote for that person. These votes will all be randomized unless stated above.
Then display who each person voted for.
Whoever gets the most vote, gets killed, reveal their role.
Show how many players are left, and what roles.

REPEAT NIGHT and DAY
Until All Mafias are killed, OR the # of Mafia's are equal to # of The others combine.


Whew, that was long, So, is this writable?? Or is it too much?
Thanks for any help!

Recommended Answers

All 7 Replies

Most folks would not like to read your code, because you have failed to use code tags.

Hi, I am fairly new to C++ but love to learn, so I wanted to create a simple program base on the group-party game mafia A.K.A "werewolf."

Just so whoever is not familiar gets the background. I will use just an example of 10 players. In a ten player game, there consists of 4 roles and this is how many there will be in the game:

3 Mafia
1 Cop
1 Doctor
5 Innocent

I figured I would assign those roles "randomly" to each player using those limits. So

0= mafia, 1= cop, 2= doctor, and 3 = innocent

I got somewhat of the code running ok only when generating a 3 player game. I only know how to use a bunch of "IF's" statement, if anyone knows how to make things easier, please feel free to teach me.

I would suggest that you use a random selection from a collection to build your groups. You could do something like this

int n; // Some number of items
int aCt = (int)( PCT_A * n );
int bCt = (int)( PCT_B * n );;
vector<Item>itemPool( n );
vector<Item>poolA;
vector<Item>poolB;
vector<Item>poolC;
srand(time(0));
int pick;
for( int i=0; i<aCtt; i++ )
{
    pick = rand % itemPool.size();  // Notice that the pool size is shrinking
    poolA.push_back( itemPool[pick] );
    swap( itemPool[pick], itemPool.back() );
    itemPool.pop_back();
}
// Create similar loop for poolB
poolC.insert( poolC.begin(), itemPoolbegin(), itemPool.end() );  // Put the remainder into poolC

It is helpful to utilize the STL containers, and I used the vector container here. Try to get this sort of partitioning working. You could also simply use the shuffle method, and partition the randomized list into the correct sizes. When you have properly partitioned your groups, let us know, and we'll move forward from there.

Disclaimer: I did not compile the code I provided, and it is only a stub, so it won't work right out the door. However, the concept should help you

Sorry dustreader, but if you are going to be using the STL, do this:

// Assign players in any order (not random)
shuffle(players,players+10);

The code given is horrific. It has three vectors etc...

However Calyso8 is starting, so it is important for him/her to understand the algorithm and what the c++ is doing:

Let us look at the required algorithm you want 10 players to have a
fixed number of thing. So just like dealing out cards you start with
10 cards which have 5 innocent, 1 doctor, 3 mafia , 1 cop.

Then you deal the cards to each player.

In code that looks something like this:

// SET CARDS:
int players[10];  // Unassigned at the moment
int cards[10];
for(int i=0;i<5;i++)
   cards[i]=3;
cards[5]=1;  // doctor
cards[6]=2;  // cop
cards[7]=cards[8]=cards[9]=0; // mafia

// DEAL Cards:
int numCards=10;     // Number of cards left
for(int i=0;i<10;i++)   // loop over players  
   {
      
      const int cardNumber=rand() % numCards;
      player[i]=cards[cardNumber];
       // NOW the clever bit : Move the last card to the used slot.
      cards[cardNumber]=cards[numCards-1];
       numCards--;                  // subtract 1 from the number of cards
  }

// Done:

That can be "shortened" and you can optimize out a number of the varables but this is an attempt to allow you to see the algorithm.

THANKS so much stuXYZ, that is simple and understand..it is a clever move...thats why i didn't think of that, ok so now, I added this after it.

//display mafia message and partners
      if (player[0] == 0)
        {cout << "You are a Mafia!" << endl
              << "Your partners are: " << endl;
      for (int i = 1; i < numOfPlayers; i++)
           if (player[i] == 0)
           {
             cout << "Player " << i << endl;
           }
        }

      //display doctor message
      if (player[0] == 1)
        cout << "You are a Doctor!" << endl;

      //display cop message
      if (player[0] == 2)
        cout << "You are a Cop!" << endl;

      //display innocent message
      if (player[0] == 3)
        cout << "You are an Innocent!" << endl;

This will let the user, who is playing player[0] know who he/she is, as well as if mafia, his partners.

Now, here is my next challenge:

I think i'm going to call this the interaction. It probably is going to be one BIG Do-While LOOP until the win conditions is met. That is if mafia's are all dead = 0, or mafia's are equal to doc + cop + innocent.

First thing it will run is the NIGHT TIME.

It will prompt the mafias who they want to kill. Say, if player[0] IS one of the mafia, then

cout << "Which player do you want to kill? ";
cin >> ?????;

* Question, what could I use for this?
I was thinking an int variable.

The reason it is hard, because the other computer mafia's have to choose randomly who they want to kill too. So I need a way on how to add up who they choose. Plus they can't kill themselves either. I'm going to confirm which ones have a majority vote. If there is a tie, I think i would want it to keep on prompting the mafias.

An int sounds fine.

You might consider declaring a function to randomly select an int between 0-6 and passing it the array of players (as per StuXYZ) they can eliminate and have the return value be the int selected. If the element of the player array with the int selected is already D then randomly select again. Keep selecting until an int is selected that doesn't correspond to an element of the player array that is D.

Call the function three times retaining the values returned in an array of three ints. Once all three ints have been selected see if the first int equals either of the other two or if the second equals the third. If so that's the person eliminated this round. If no matches, then redo the selection process.

Sorry dustreader, but if you are going to be using the STL, do this:

// Assign players in any order (not random)
shuffle(players,players+10);

O RLY?

You didn't notice that I mentioned this exact approach in my post. I decided to show random selection to give the OP an idea of how one can randomly choose and remove a single element from a container.

Of course, I'm sure that in your haste to edify me you momentarily forgot the proper syntax: random_shuffle( players.begin(), players.end() );

The code given is horrific. It has three vectors etc...

As opposed to sending a learner down the path of inflexible non-extensible code? There are 3 vectors because it is assumed (as described by the OP) that there are different roles for different item types. Perhaps it was naive of me to make the logical deduction that since each separate item type performs a separate function on a specific item group, it would be nice to have them in separate containers. Of course, a polymorphic class hierarchy would be the preferred solution for this sort of algorithm. However, the OP probably doesn't want to tangle with classes and inheritance yet.

However Calyso8 is starting, so it is important for him/her to understand the algorithm and what the c++ is doing:

Right, and since the OP is learning, introducing the STL is probably a good idea so that when the OP starts using larger collections, the OP doesn't continually use statically allocated arrays inappropriately.

Of course, I am speaking out of turn. Using two integer arrays of identical length to shuffle a list is the correct solution.

sorry guys I still am having a bit trouble...its gonna take a while...um..ok so now im trying to figure out still how to do the mafia kill during the night time.

Heres what I got so far,

mafiaKill()
{
  //prompt the mafias who they want to kill.
  int kill[10];

  //this is for the user, he gets to choose
  if (player[0] == 0)
    cout << "What player number do you want to kill?" << endl;
  cin >> kill[0];

  //loop to get the other mafia's choice
  for (int i = 0; i < numOfPlayers; i++)
    {
      //we start with player[1] because of above if player[0].... 
      if (player[i + 1] == 0)
        {
        do (kill[i]= rand() % 10);
        //mafia cannot kill a player who is a mafia nor "-1" equals dead
        while(player[kill[i]] != 0 && player[kill[i]] != -1);
        }
      //now im not sure how to record a kill...and compare them
      if (kill[i] >= 2)

    }
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.