You are viewing the MafiaScum.net Wiki. To play the game, visit the forum.

Mini2 Analysis

From MafiaWiki
Jump to navigation Jump to search
#include "stdafx.h"


#include <iostream>
#include <algorithm>
#include <string.h>

using namespace std;

#define FALSE 0
#define TRUE 1

const Cubestudent = 0;
const IS = 1;
const VinnyQ = 2;
const Poki= 3;
const Corsato = 4;
const Omega= 5;
const MiriYami= 6;
const Sketchwick= 7;
const Groza528= 8;
const Mikegoo= 9;
const Sofis= 10;

const MAX_INVESTIGATIONS = 30;
const NUM_PLAYERS = 12;
const MAX_INNOCENT = 9;

/*Name: returns the players name, based on the player's number*/
char * name (int player)
{
  switch (player) {
      case Cubestudent : return "Cubestudent"; break;
      case IS : return "IS"; break;
      case VinnyQ : return "VinnyQ"; break;
      case Poki : return "Poki"; break;
      case Corsato : return "Corsato"; break;
      case Omega : return "Omega"; break;
      case MiriYami : return "MiriYami"; break;
      case Sketchwick : return "Sketchwick"; break;
      case Groza528 : return "Groza528"; break;
      case Mikegoo : return "Mikegoo"; break;
      case Sofis : return "Sofis"; break;
      default : return "I dunno";
  }
	
}


// Hard coded the round 1 investiagtions
bool round1_valid (char a[])
{
  bool isValidSanity (char a[], int investigator, int investigatee, char *result);

  return isValidSanity(a,  Cubestudent,  IS, "Guilty")	&& 
     isValidSanity(a, Sofis, IS, "Guilty") && 
     isValidSanity(a, Sketchwick, IS, "Not Guilty") && 
     isValidSanity(a, IS, Mikegoo, "Guilty") && 
     isValidSanity(a, VinnyQ, Cubestudent, "Guilty") && 
     isValidSanity(a, Corsato, Cubestudent, "Guilty") && 
     isValidSanity(a, Poki, Omega, "Guilty") && 
     isValidSanity(a, Omega, Groza528, "Not Guilty") && 
     isValidSanity(a, MiriYami, Sofis, "Not Guilty") && 
     isValidSanity(a, Groza528, Sofis, "Guilty");
}


// Hard coded the round 2 investiagtions
bool round2_valid (char a[])
{
  bool isValidSanity (char a[], int investigator, int investigatee, char *result);

  return isValidSanity(a,  Groza528,  Sketchwick, "Guilty")	&& 
     isValidSanity(a, IS, Cubestudent, "Not Guilty") && 
     isValidSanity(a, Mikegoo, Sketchwick, "Not Guilty") && 
     isValidSanity(a, MiriYami, Poki, "Not Guilty") && 
     isValidSanity(a, Omega, MiriYami, "Not Guilty") && 
     isValidSanity(a, Poki, MiriYami, "Guilty") && 
     isValidSanity(a, Sketchwick, Cubestudent, "Not Guilty");
}

// Hard coded the round 3 investigations
bool round3_valid (char a[])
{
  bool isValidSanity (char a[], int investigator, int investigatee, char *result);

  return isValidSanity(a,  Groza528,  IS, "Guilty")	&& 
     isValidSanity(a, IS, VinnyQ, "Not Guilty") && 
     isValidSanity(a, Mikegoo, IS, "Not Guilty") && 
     isValidSanity(a, MiriYami, IS, "Not Guilty") && 
     isValidSanity(a, Omega, Mikegoo, "Not Guilty") && 
     isValidSanity(a, Poki, Groza528, "Not Guilty") && 
     isValidSanity(a, Sketchwick, Groza528, "Not Guilty");
}

/*****************************************************************
 main Calculate permutations and combinations for mafia.  
		Output to file
*****************************************************************/
void main()
{

  /*****************************************************************
	 declare variables and predeclare functions*/
  bool isValidSanity (char a[], int investigator, int investigatee, char *result);
  bool ismafia(char a[], int mafiamember);
  char * name (int player);
  void display_players (void);

  int innocent[MAX_INNOCENT];
  int inn, guil, or, ee, guilty1, guilty2, guilty3;
  char res;
  int a_ee[MAX_INVESTIGATIONS], a_or[MAX_INVESTIGATIONS];
  char *a_res[MAX_INVESTIGATIONS];
  int prob_maf[NUM_PLAYERS], prob_sane[NUM_PLAYERS], prob_insane[NUM_PLAYERS], prob_paranoid[NUM_PLAYERS], prob_naive[NUM_PLAYERS];
  bool shouldIncludeRound1,shouldIncludeRound2,shouldIncludeRound3, isYOrN, shouldShowPermutations;
  /*****************************************************************
	 initialize variables*/
  guilty1=-1;
  guilty2=-1;
  guilty3=-1;

  for (int z = 0 ; z <= NUM_PLAYERS ; z++) {
    prob_maf[z]=0;
    prob_sane[z]=0;
    prob_paranoid[z]=0;
    prob_insane[z]=0;
    prob_naive[z]=0;
    if (z < MAX_INNOCENT) {
      innocent[z] = -1;
    }
  }

  for (z = 0; z < MAX_INVESTIGATIONS ; z++) {
    a_ee[z]=-1;
    a_or[z]=-1;
    a_res[z]="U";
  }

  /*****************************************************************
	 Get various inputs */
  display_players();

  printf ("\nWho should I assume is innocent? \n-1 for no one\n");
  scanf("%d", &inn);

  int inn_ctr = 0;

  while (inn >= 0 && inn < NUM_PLAYERS-1) {  // keep going as long as a valid player was entered

    innocent[inn_ctr]=inn;
    inn_ctr++;
    if (inn_ctr >= MAX_INNOCENT) {  // exit the loop since we cannot have any more innocents declared
      break;
    }
    printf ("Who else? \n");
    scanf("%d", &inn);
  }

  printf ("\nWho should I assume is guilty? \n-1 for no one\n");
  scanf("%d", &guil);

  if (guil >= 0 && guil < NUM_PLAYERS-1) {
    guilty1=guil;
    printf ("Who else? \n");

    scanf("%d", &guil);
    if (guil >= 0 && guil < NUM_PLAYERS-1) {
      guilty2=guil;
      printf ("Who else? \n");

      scanf("%d", &guil);
      if (guil >= 0 && guil < NUM_PLAYERS-1) {
	guilty3=guil;
      }
    }
  }

	
  printf ("\nShould I include round 1 investigations? (y/n)\n");
  char c;
  isYOrN=FALSE;
  while ( ! isYOrN ) {
    scanf ("%c", &c);
    switch (c) {
        case 'Y' :
        case 'y' : {isYOrN = TRUE; shouldIncludeRound1 = TRUE; printf("Round 1 investigations will be automatically entered\n"); break;}
        case 'N' :
        case 'n' : {isYOrN = TRUE; shouldIncludeRound1 = FALSE; printf ("Round 1 investigations will NOT be automatically entered\n"); break;}
        default  : isYOrN = FALSE;
    }
  } 

  printf ("\nShould I include round2 investigations? (y/n)\n");
  isYOrN=FALSE;	
  while ( ! isYOrN ) {
    scanf ("%c", &c);
    switch (c) {
        case 'Y' :
        case 'y' : {isYOrN = TRUE; shouldIncludeRound2 = TRUE; printf("Round 2 investigations will be automatically entered\n"); break;}
        case 'N' :
        case 'n' : {isYOrN = TRUE; shouldIncludeRound2 = FALSE; printf ("Round 2 investigations will NOT be automatically entered\n"); break;}
        default : isYOrN = FALSE;
    }
  } 

  printf ("\nShould I include round3 investigations (after mod error fixed)? (y/n)\n");
  isYOrN=FALSE;		
  while ( ! isYOrN ) {
    scanf ("%c", &c);
    switch (c) {
        case 'Y' :
        case 'y' : {isYOrN = TRUE; shouldIncludeRound3 = TRUE; printf("Round 3 investigations will be automatically entered\n"); break;}
        case 'N' :
        case 'n' : {isYOrN = TRUE; shouldIncludeRound3 = FALSE; printf ("Round 3 investigations will NOT be automatically entered\n"); break;}
        default : isYOrN = FALSE;
    }
  } 

  printf ("\n");
  printf ("Should I show all permutations? (y/n)\n");
  isYOrN=FALSE;
  char d;
  while ( ! isYOrN ) {
    scanf ("%c", &d);
    switch (d) {
    case 'Y' :
    case 'y' : {isYOrN = TRUE; shouldShowPermutations = TRUE; break;}
    case 'N' :
    case 'n' : {isYOrN = TRUE; shouldShowPermutations = FALSE;break;}
    default : ;
    }
  }

  printf ("\n");
  display_players();
  printf ("\nInvestigations:\nWho investigated whom and with what result (G or N)?\n");
  printf ("e.g.  in round 1 %s investigated %s and got guilty so you would put:\n", name(0), name(1));
  printf ("0 1 G\n");
  printf ("-1 to quit\n");

  z=0;
  or=0;
	
  while (or != -1) {
    scanf("%d", &or);
    if (or == -1) break;
    scanf("%d %c", &ee, &res);
    if (or < NUM_PLAYERS-1 && or >=0 && ee < NUM_PLAYERS-1 && ee >=0) {
      a_or[z]= or;
      a_ee[z]= ee;
      switch (res) {
          case 'G' :
          case 'g' : {a_res[z]="Guilty"; z++; break;}
          case 'N' :
          case 'n' : {a_res[z]="Not Guilty"; z++; break;}
          default : printf ("Invalid result."); break;
      }
    } else {
      printf("invalid investigator or investigatee\n");
    }
		
    if (z>MAX_INVESTIGATIONS) break;
  }

  /*****************************************************************
	 Now we have the info we need, figure things out */

  printf ("\nThe output will be in a file called mafperm.txt and mafiacomb.txt\n");
  FILE *fp_perm, *fp_comb;

  if ( (fp_perm = fopen("mafperm.txt", "w") ) == NULL) {
    printf("Unable to open file.\n");
    exit(1);
  };
  if ( (fp_comb = fopen("mafcomb.txt", "w") ) == NULL) {
    printf("Unable to open file.\n");
    exit(1);
  };


  // put header in file
  if (shouldShowPermutations) {
    for (int ctr = 0; ctr < NUM_PLAYERS - 1 ; ctr++) {
      fprintf (fp_perm, "%s\t", name(ctr));
    }
    fprintf (fp_perm, "\n");
  }

  // for next_permutation() to work, this must be alphabetized
  char a[] = { 'i', 'i', 'm', 'm', 'm', 'n', 'n', 'p', 'p', 's', 's' };
  int count = 0;
  int bad_count = 0;

  do   //    while ( next_permutation( a, a+NUM_PLAYERS-1 ) );
    {

      // Check to see if any known innocents are tagged as mafia, if so
      // then this is not a valid permutation
      bool keep_going;
      keep_going = TRUE;
      int array_loop;

      for (array_loop = 0; array_loop < MAX_INNOCENT ; array_loop ++ ) {

	if ((innocent[array_loop] != -1) && (a[innocent[array_loop]] == 'm')) {
	  bad_count ++;
	  keep_going = FALSE; // indicate that we already know this is not valid
	  break; // out of for loop
	}
      }
      if ( ! keep_going ) continue; // we know this is not valid, so do not continue
      // Done checking known innocent

      // Check if investigations are legit
      for (array_loop = 0; array_loop < MAX_INVESTIGATIONS; array_loop ++) {
	if ( ! isValidSanity(a, a_or[array_loop], a_ee[array_loop], a_res[array_loop]) ) {
	  bad_count ++;
	  keep_going = FALSE;
	  break; // gets out of for loop
	}
      }
      if ( ! keep_going ) continue;  // goes to next permutation
      // entered investigations have been checked

      // Check if round 1 investigations are legit
      if ( shouldIncludeRound1 && round1_valid(a) ) {
	keep_going = TRUE;
      } else if ( shouldIncludeRound1 ) {
	bad_count++;
	continue;  // we included round 1 and it wasn't valid so go to next permutation
      }
      // round 1 investigations have been checked, if they were supposed to be checked

      // Check if round 2 investigations are legit
      if ( shouldIncludeRound2 && round2_valid(a) ) {
	keep_going = TRUE;
      } else if ( shouldIncludeRound2 ) {
	bad_count++;
	continue;  // we included round 2 and it wasn't valid so go to next permutation
      }
      // round 2 investigations have been checked, if they were supposed to be checked

      // Check if round 2 investigations are legit
      if ( shouldIncludeRound3 && round3_valid(a) ) {
	keep_going = TRUE;
      } else if ( shouldIncludeRound3 ) {
	bad_count++;
	continue;  // we included round 3 and it wasn't valid so go to next permutation
      }
      // round 3 investigations have been checked, if they were supposed to be checked



      // check to make sure that confirmed mafia are mafia
      // this is the final check, so no need to deal with the continue...
      if ( ismafia(a, guilty1) && ismafia(a, guilty2) && ismafia(a, guilty3)) {
	if (shouldShowPermutations) {
	  for ( int i = 0 ; i < 11 ; i++ )
	    fprintf (fp_perm, "%c\t", a[ i ]);

	  fprintf(fp_perm, "\n");
	}
				
	for ( int playernum = 0 ; playernum < NUM_PLAYERS - 1 ; playernum++ ) {	
	  switch (a[playernum]) {
    	      case 'm' : prob_maf[playernum]++; fprintf (fp_comb, "%s,", name(playernum));break;
	      case 's' : prob_sane[playernum]++; break;
	      case 'i' : prob_insane[playernum]++; break;
	      case 'n' : prob_naive[playernum]++; break;
	      case 'p' : prob_paranoid[playernum]++; break;
	  }
	}
	count++;
	fprintf (fp_comb, "\n");

      } else {
	bad_count++;
      }

    } while ( next_permutation( a, a+NUM_PLAYERS-1 ) );


  // print results to file
  fprintf (fp_perm, "%d permutations were accepted\n", count);
  fprintf (fp_perm,  "%d permutations were rejected\n", bad_count);
  fprintf (fp_perm, "\n");

  fprintf (fp_perm, "\t\t\tMafia,  Sane, Insane, Paranoid, Naive\n");
  for (int looper = 0; looper <= 10; looper++) {
    fprintf (fp_perm,  "Prob[%s]\t= %3.1f\t%3.1f\t%3.1f\t%3.1f\t%3.1f\n", name(looper), (float) (100*prob_maf[looper])/count,(float) (100*prob_sane[looper])/count, (float) (100*prob_insane[looper])/count, (float) (100*prob_paranoid[looper])/count,  (float) (100*prob_naive[looper])/count);
  }

  fclose (fp_perm);
  fclose (fp_comb);

}

/*****************************************************************
 display_players : lists all players and their 'number' 
*****************************************************************/
void display_players (void)
{
  char * name (int player);
  int ctr;

  for (ctr = 0 ; ctr < NUM_PLAYERS-1; ctr++) {
    printf ("%s = %d\n", name(ctr), ctr);
  }
}



/*****************************************************************
 ismafia:
	input:	array, and member number
	output: true if member number is mafia or -1, flase otherwise
*****************************************************************/
bool ismafia(char a[], int mafiamember)
{ 

  return mafiamember == -1 || a[mafiamember] == 'm';
}


/*****************************************************************
 isValidSanity:
	input:	array, investigator, investigatee, guilty/not guilty
	output: true if the investigator could have gotten the given
		result for the investigatee. 
		Mafia can say anything
		Sane returns guilty if mafia, not guilty otherwise
		Insane return guilty if not mafia, not guilty otherwise
		paranoid always returns guilty
		naive always returns not guilty
*****************************************************************/
bool isValidSanity (char a[], int investigator, int investigatee, char *result)
{ 

  if (investigator == -1 || a[investigator] == 'm') 
    return true;

  if (result == "Guilty") {
    switch (a[investigator]) {
        case 's' : return a[investigatee] == 'm';
        case 'i' : return a[investigatee] != 'm';
        case 'p' : return true;
        case 'n' : return false;
    }

  } else {
    switch (a[investigator])
      {
          case 's' : return a[investigatee] != 'm';
          case 'i' : return a[investigatee] == 'm';
          case 'p' : return false;
          case 'n' : return true;
      }

  }
  printf ("You should never be able to get here.  There is a problem.\n");
  return true;

} // isValidSanity