Jump to content
  • Advertisement
Sign in to follow this  
vinb

new version of MasterMind. criticisms welcome

This topic is 5458 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Thanks to all who helped me with the first version of my game. It's a console version of MasterMind that I'm using to learn C++ with. I'm starting to use classes now instead of all functions and I would really appreciate any comments/criticisms you could offer. My intent with this was to try to encapsulate the game in a class to implement a sort of state machine (am I using the term correcly?). I got some great responses with the last post I made and it helped a lot. Thanks to all who responded. Here's the code... main.cpp
#ifndef ROW_WIDTH
	#include "gamestate.h"
#endif

color colorCodes[ROW_WIDTH] ;

// MAIN
int main() 
{
	char cScore[6] = "0", cCount[6] = "0", GAMETITLE[50] = "" ;
	gamestate *thisGame = new gamestate ;
	
	initColors() ;
	
	do {
		thisGame->reset();
		setTitle(GAMETITLE, itoa(thisGame->getTotalScore(),cScore,10), itoa(thisGame->getGameCount(), cCount,10) ) ;

		if ( !runGame(thisGame) ) break ;

		system("cls") ;

	} while (true) ;
	
	delete thisGame ;

	return 1 ;
	
}

bool runGame(gamestate *thisGame) {
	
	cout << "Set difficulty (5 to 20)" << endl ;	
	char tries[3] = "  " ;
	cin.get(tries,2) ;cin.ignore(2000, '\n') ;

	thisGame->setDifficulty(tries);

	int i = 0, score = 0, rowcount = 0; 

	Row line ;

	thisGame->setKey() ;
	writeInstructions(thisGame->getDifficulty()) ;

	do{
		getNextGuess(line) ;
		
		thisGame->update(line, rowcount) ;

		if ( thisGame->winner(line) ) {
			MessageBox(NULL, "YOU WIN!!", "MasterMind!", MB_OK);
			thisGame->setScore() ;

			break ;
		}
		else ;
		{
			system("cls") ;
		}
		
		if ( thisGame->looser() ){
			cout << "YOU LOSE!!!" << endl  ;
			cout << "Correct answer: " ; thisGame->writeKey() ;
			break ;
		}
		
		writeToScreen(thisGame) ;
	}
	while (true) ;
	
	if ( keepPlaying() ){
		return true ;
	}
	else{
		return false ;
	}
}



//////////////////////////////////////////
void initColors() {
	colorCodes[0].abbr = 'R' ;
	strcpy(colorCodes[0].longname, "(R)ed") ;
	
	colorCodes[1].abbr = 'G' ;
	strcpy(colorCodes[1].longname, "(G)reen") ;

	colorCodes[2].abbr = 'B' ;
	strcpy(colorCodes[2].longname, "(B)lue") ;

	colorCodes[3].abbr = 'Y' ;
	strcpy(colorCodes[3].longname, "(Y)ellow") ;

	colorCodes[4].abbr = 'W' ;
	strcpy(colorCodes[4].longname, "(W)hite") ;

	colorCodes[5].abbr = 'P' ;
	strcpy(colorCodes[5].longname, "(P)urple") ;

	colorCodes[6].abbr = 'O' ;
	strcpy(colorCodes[6].longname, "(O)range") ;

	for (int i = 0; i< ROW_WIDTH; i++) {
		colorCodes.index = i+1 ;
	}
}

//////////////////////////////////////////
void getNextGuess(Row &line){
	COORD point = setPoint(0, 3) ; 
	HANDLE stdCon = GetStdHandle(STD_OUTPUT_HANDLE);

	SetConsoleCursorPosition(stdCon, point);
	cin.get(line, ROW_WIDTH+1) ; cin.ignore(2000,'\n') ; 
}

//////////////////////////////////////////
bool keepPlaying() {
	char cResponse[3] = "  " ;
	cout << endl << "Play again? Y/N " ;
	cin.get(cResponse,2) ; cin.ignore(2000,'\n') ;
	
	return (cResponse[0] == 'Y' || cResponse[0] == 'y') ? true : false ;
}

//////////////////////////////////////////
char keyTranslate(int i){
	
	for (int j=0; j<ROW_WIDTH+1;j++){
		if (i == colorCodes[j].index)
            return colorCodes[j].abbr ;
	}
	return 'X' ;
}


//////////////////////////////////////////
void setTitle(char title[], char cScore[], char cGameCount[]){
	char GAMETITLE[50] = "MasterMind! score = " ;
	strcat(GAMETITLE, cScore) ;
	strcat(GAMETITLE, " Game #") ;
	strcat(GAMETITLE, cGameCount) ;
	SetConsoleTitle(GAMETITLE);
}

//////////////////////////////////////////
void writeToScreen(gamestate *thisGame){

	writeInstructions(thisGame->getDifficulty()) ;
	
	HANDLE stdCon = GetStdHandle(STD_OUTPUT_HANDLE);

	const int RED_ORANGE = 12 ;
		
	for (int i=0;i<thisGame->getRowCount();i++)
		{
			COORD point = setPoint(30,i + 3);
			SetConsoleCursorPosition(stdCon, point);

			for (int j=0;j<ROW_WIDTH;j++){
				switch (thisGame->game[j]){
					case 'R': SetConsoleTextAttribute(stdCon,FOREGROUND_RED | FOREGROUND_INTENSITY);
						break ;
					case 'G': SetConsoleTextAttribute(stdCon,FOREGROUND_GREEN | FOREGROUND_INTENSITY);
						break;
					case 'B': SetConsoleTextAttribute(stdCon,FOREGROUND_BLUE | FOREGROUND_INTENSITY);
						break;
					case 'P': SetConsoleTextAttribute(stdCon,FOREGROUND_BLUE | FOREGROUND_RED);
						break;
					case 'O': SetConsoleTextAttribute(stdCon, RED_ORANGE );
						break;
					case 'Y': SetConsoleTextAttribute(stdCon,FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY  );
						break;
					case 'W': SetConsoleTextAttribute(stdCon,FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
						break;
					default: SetConsoleTextAttribute(stdCon,FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
				}
				
				cout << thisGame->game[j] << " " ; }

			cout << "     " ;
	
			SetConsoleTextAttribute(stdCon,FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);

			for (int j=0;j<ROW_WIDTH;j++){
				if ( thisGame->game[j] == thisGame->key[j] )
					cout << 'Y' << " " ;
				else
					cout << 'N' << " " ;
			
			}
			cout << endl;
		}
}

//////////////////////////////////////////
COORD setPoint(const int x, const int y){
	COORD point = {x,y} ;
	return point ;
}

//////////////////////////////////////////
void writeInstructions(const int difficulty){
	cout << "Enter " << ROW_WIDTH << " colors " ;
	for (int i=0;i<ROW_WIDTH+1;i++)
		cout << colorCodes.longname << " " ;

	cout << endl;
	cout << "You have " << difficulty << " tries." << endl ;
}




gamestate.h
#include <iostream>
#include <time.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctime>

using namespace std ;

// GLOBALS
const int ROW_WIDTH = 7 ;
const int MAX_DIFFICULTY = 20 ;
const int BASE_SCORE = 100 ;

struct color{
	char abbr ;
	char longname[10] ;
	int index ;
} ;


typedef char Row[ROW_WIDTH] ;

class gamestate{
	
private:
	int difficulty ;
	int rowcount ;
	int score ;
	int totalScore ;
	int gameCount ;
	
	void setTotalScore();
	void setGame(const Row line);

public:

	gamestate();
	~gamestate();

	void getKey(Row key);
	int getDifficulty();
	int getRowCount() ;
	int getTotalScore();
	int getGameCount();
	int getScore();
	void setScore() ;
	bool winner(const Row line);
	bool looser() ;
	void setGameCount() ;
	void setGameCount(int count);
	void setDifficulty();
	void setRowCount() ;
	void setKey() ;
	void update(const Row line, const int rowcount) ;
	void writeKey();
	void reset()  ;
	
	Row key ;
	Row game[20] ;

} ;


// FUNCTIONS
char keyTranslate(int i) ;
bool checkPattern(const Row UserChoice, const Row key, Row returnRow ) ;
void writeToScreen(gamestate *thisGame) ;
bool runGame(gamestate *thisGame) ;
void setTitle(char title[], char cScore[], char cGameCount[]) ;
bool keepPlaying() ;
void getNextGuess(Row &line) ;
void initColors() ;
COORD setPoint(const int x, const int y) ;
void writeInstructions(const int difficulty) ;



gamestate.cpp
// gamestate.cpp
#ifndef ROW_WIDTH
	#include "gamestate.h"
#endif

////////////////////////////
gamestate::gamestate() {
	totalScore = 0 ;
	score = 0 ;
	rowcount = 0 ;
	difficulty = 0 ;
	gameCount = 0 ;

}

//////////////////////////////////////////
gamestate::~gamestate() {

}

//////////////////////////////////////////
int gamestate::getRowCount(){
	return rowcount ;
}

//////////////////////////////////////////
int gamestate::getDifficulty() {
	return this->difficulty;
}

//////////////////////////////////////////
int gamestate::getTotalScore(){
	return totalScore ;
}

//////////////////////////////////////////
int gamestate::getGameCount(){
	return gameCount ;
}

//////////////////////////////////////////
void gamestate::setGameCount(){
	gameCount++;
}

//////////////////////////////////////////
void gamestate::setGameCount(int count){
	gameCount = count;
}

//////////////////////////////////////////
void gamestate::setRowCount(){
	rowcount++ ;
}

//////////////////////////////////////////
void gamestate::reset() {
	rowcount = 0 ;
	score = 0 ;
	setGameCount();
}

//////////////////////////////////////////
bool gamestate::winner(const Row line){

	bool win = false ;
	int iNumCorrect = 0 ;

	for (int i=0;i < ROW_WIDTH; i++) {
		if ( line == key ){
			iNumCorrect++ ;
		}
	}

	if (iNumCorrect == ROW_WIDTH)
		win = true ;

	return win ;

}

int gamestate::getScore(){
	return score ;
}

//////////////////////////////////////////
void gamestate::setScore() {

	score += BASE_SCORE ; 
	score += (( MAX_DIFFICULTY - difficulty ) * 10) ; // add difficulty points
	score -= rowcount ; // subtract a point for each try

	totalScore +=score ;

}

//////////////////////////////////////////
void gamestate::setDifficulty(){
	char tries[3] = "  " ;
	
	cin.get(tries,2) ;cin.ignore(2000, '\n') ;
	this->difficulty = atoi(tries) ;

	if ( difficulty < 5 ) difficulty = 5 ;
	if ( difficulty > 20 ) difficulty = 20 ;

	system("cls");

}

//////////////////////////////////////////
void gamestate::setKey() 
{
	srand(time(NULL)) ; // should give us a random number all day
	for (int i=0;i < ROW_WIDTH; i++) {
		key = ( keyTranslate( (rand() % ROW_WIDTH) + 1)  ); } 
}

//////////////////////////////////////////
void gamestate::getKey(Row theKey) {

	theKey = this->key ;
}

//////////////////////////////////////////
void gamestate::writeKey() {
	for (int i=0;i < ROW_WIDTH; i++) 
		cout <<  key << " "  ;
		cout << endl ;
}

//////////////////////////////////////////
void gamestate::setGame(const Row line){

	if (line){
		for (int i=0;i<ROW_WIDTH;i++){
			game[rowcount] = line ;
		}
	}
}

//////////////////////////////////////////
bool gamestate::looser() {

	return rowcount == difficulty ;
}

//////////////////////////////////////////
void gamestate::update(const Row line, const int rowcount){

	this->setGame(line);
	this->setRowCount() ;
	
}



[Edited by - vinb on October 13, 2004 8:29:02 AM]

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!