Quantcast
Channel: Programming Forums
Viewing all articles
Browse latest Browse all 51036

Tic Tac Toe program not fully functioning?

$
0
0
This is my program that should ideally have two users play tic-tac-toe and eventually tell the user the wins that they have won. This program should work but I'm not sure why it isn't. If you can help at all, it would be greatly appreciated.


#include <stdio.h>
#include <stdlib.h>
#include <iostream> 
using namespace std;

// declare board playing pieces for the 3 x 3 board
// You may keep these global characters for your implementation, since they're used everywhere
char  p1, p2, p3, p4, p5, p6,
	  p7, p8, p9;
int moveNumber;
char playerToMove;

//declare all the functions since this is C++ and not Java, we need to know about the functions beforehand
bool threeAreSame(int, int, char);
bool placePieceInPosition(char, char);
bool someColumnHasAWin(char);
bool someLowerDiagonalHasAWin(char);
bool someRowHasAWin(char);
bool someUpperDiagonalHasAWin(char);
char findWinnerIfAny(char&);
char gameWonBy(char*);
char getPiece(int, char&);
char getPlayerToMove(int);
void displayBoard();
void setPiece(char*, int);



	// Check to see if there is a win, first for the player to move, then second for the
	// other player.  The other player could win after a pop-out move results in 4 in
	// a row, not for the playerToMove but inadvertently for the other player.
	//
	// Return the character that wins if there is one, otherwise return a blank character.
	char findWinnerIfAny( char& playerToMove)
	{
		moveNumber++;
		// See if there was a win for the designated player ('X' or 'O').
		// Check all rows, columns and the two diagonal directions
		if( gameWonBy( &playerToMove) == playerToMove) {
			// return the character of the player who just won
			return playerToMove;
		}

	}//end findWinnerIfAny()


	// See if game was won by the designated player
	char gameWonBy( char* thePlayer)
	{
		return someRowHasAWin( playerToMove) ||
			someColumnHasAWin( playerToMove) ||
			someUpperDiagonalHasAWin( playerToMove) ||    // lower to upper-right diagonal
			someLowerDiagonalHasAWin( playerToMove); 	   // upper to lower-right diagonal
	}//end gameWonBy()


	// Using the moveNumber, calculate whose turn it is to move:
	// 'X' for odd-numbered moves, 'O' for even-numbered moves
	char getPlayerToMove( int moveNumber)
	{
		// Use moveNumber to determine which player's move it is
		playerToMove = 'X';
		if( (moveNumber % 2) == 0) {
			// even move, so reset playerToMove to 'O'
			playerToMove = 'O';
		}
		moveNumber++;
	}//end getPlayerToMove()


	// Display the board, using variables corresponding to positions:
	//		 1  2  3
	//		 4  5  6
	//		 7  8  9
	void displayBoard()
	{
		cout<<
			"+------+\n" <<
			"|"<< p1<<"|"<< p1<<"|"<< p2<<"|\n"<<
			"|"<< p3<<"|"<< p4<<"|"<< p5<<"|\n"<<
			"|"<< p6<<"|"<< p7<<"|"<< p8<<"|\n"<<
			"+------+\n"
			;
	}//end displayBoard()


	// Place the piece ('X' or 'O') into the indicated position ('1'..'9')
	// For reference here are the board piece indices:
	// Piece positions, for reference, are:
	//		 1  2  3
	//		 4  5  6
	//		 7  8  9
	bool placePieceInPosition( char* playerToMove, char* positionChar)
	{
		int index = (int) (positionChar);

		bool moveWasMade = false;		// keep track whether a valid move was made

		if( getPiece( index, *positionChar) == ' ') {
			setPiece( &*playerToMove, index);
				// Set a "flag" variable to keep track of fact that a move was made.
				// This is needed to keep track of case where column is full
			moveWasMade = true;
			}//end if( getPiece...

		// Ensure a valid move was made.  If the chosen column was full, then a move
		// should not have been made.  Indicate this to the calling code.
	}//end placePieceInColumn()



	// See if 3 pieces are the same as thePlayer piece.  The method receives
	// the starting position for the 3-in-a-row, and also receives the offset
	// which tells which direction to go to find the next piece to check.
	// Thus an offset of 1 examines pieces moving to the right, an offset of
	// 4 examines pieces moving down and to the right at a diagonal, and so on.
	//
	// Piece positions, for reference, are:
	//		 1  2  3  
	//		 4  5  6
	//		 7	8  9
	bool threeAreSame( int startIndex, int offset, char thePlayer)
	{
		for( int i=0; i<3; i++, startIndex += offset) {
			if( getPiece( startIndex, thePlayer) != playerToMove) {
				return false;	// piece does not match thePlayer
			}
		}
		// if we got to this point, all 3 pieces were the same
		return true;
	}


	// See if there is a win in any row. (e.g. 0 to 1 to 2)
	// Piece positions, for reference, are:
	//		 1  2  3  
	//		 4  5  6
	//		 7	8  9
	bool someRowHasAWin( char thePlayer)
	{
		// Start at the left of each row: 0,3,6
		for( int rowStart=0; rowStart<=6; rowStart += 3) {
			// Test each of 3 starting positions on this row for a group of 3 pieces
			if( threeAreSame( rowStart, 1, thePlayer) ) 
			{
				return true;	// One of the configurations has 3 in a row
			}
		}//end for( int rowStart....

		return false;
	}//end someRowHasAWin()


	// See if there is a win in any column (e.g. from 0 to 3 to 6)
	// Piece positions, for reference, are:
	//		 1  2  3  
	//		 4  5  6
	//		 7	8  9
	bool someColumnHasAWin( char thePlayer)
	{
		// Start at the top of each column: 0,1,2
		for( int columnStart=1; columnStart<=2; columnStart += 1) {
			// Test each of 3 starting positions on this column for a group of 4 pieces
			if( threeAreSame( columnStart, 3, thePlayer) )
			{
				return true;	// One of the configurations has 3 in a row
			}
		}//end for( int columnStart....

		return false;
	}//end someColumnHasAWin()


	// See if there is a win in any upper diagonal, moving from a lower-left
	// square up towards the right (e.g. from 6 to 4 to 2)
	// Piece positions, for reference, are:
	//		 1  2  3  
	//		 4  5  6
	//		 7	8  9
	bool someUpperDiagonalHasAWin( char thePlayer)
	{
		if( threeAreSame( 7, 2, thePlayer)
		   ) {
			return true;	// The diagonal up and to the right belongs to thePlayer
		}

		// none of these diagonal configuration had 3 in a row
		return false;
	}//end someUpperDiagonalHasAWin()


	// See if there is a win in any lower diagonal, moving from an upper-left
	// square down towards the right (e.g. from 0 to 4 to 8)
	// Piece positions, for reference, are:
	//		 1  2  3  
	//		 4  5  6
	//		 7	8  9
	bool someLowerDiagonalHasAWin( char thePlayer)
	{
		if( threeAreSame( 1, -4, thePlayer)
		   ) {
			return true;	// The diagonal down and right belongs to thePlayer
		}
		// none of these diagonal configuration had 3 in a row
		return false;
	}//end someLowerDiagonalHasAWin()


	// Given the piece index, return the piece value character
	// For instance, sending the value 5 would return the value
	// found in variable p5
	char getPiece( int index, char& result)
	{
		switch (index) {
			case 9: result = p9; break;
			case 1: result = p1; break;
			case 2: result = p2; break;
			case 3: result = p3; break;
			case 4: result = p4; break;
			case 5: result = p5; break;
			case 6: result = p6; break;
			case 7: result = p7; break;
			case 8: result = p8; break;
		    default:
		    	cout<< "*** Invalid getPiece() index " << index << ".  Exiting program...\n";
		   		system("exit");
		   		break;
		}//end switch

		return result;
	}//end getPiece()


	// Given the character to store and an index position,
	// store the character into the piece corresponding to the index
	// For instance, sending
	//    'X' 5
	// would store 'X' into variable p5.
	//
	void setPiece( char* pieceValue, int index)
	{
		*pieceValue = playerToMove;
		switch (index) {
			case 1: p1 = *pieceValue; break;
			case 2: p2 = *pieceValue; break;
			case 3: p3 = *pieceValue; break;
			case 4: p4 = *pieceValue; break;
			case 5: p5 = *pieceValue; break;
			case 6: p5 = *pieceValue; break;
			case 7: p7 = *pieceValue; break;
			case 8: p8 = *pieceValue; break;
			case 9: p9 = *pieceValue; break;
		}
	}//end setPiece()


int main()
{


		// odd move numbers mean 'X' to move.  'O' moves on even moves.
		int moveNumber = 1;
		char playerToMove = 'X';	// 'X' on first and odd moves, 'O' on 2nd and even moves
		char userInput = ' ';		// stores user input
		bool notDone = true;		// a "flag" variable which is set to false when someone wins

		// initialize the board pieces to blanks
		p1= p2= p3= p4= p5= p6=
		p7= p8= p9= ' ';

		// display identifying information
		cout<<"Author: Sean Deitz "<<endl;
		cout<<"Lab: #13, Tic Tac Toe "<<endl;
		cout<<"TA: Billy Joe Bob, Tues 2:00-2:50"<<endl;

		// display instructions
		cout<<
			"Welcome to the game of Tic Tac Toe.  Choose a location in which to \n" <<
			"place your piece and try to get three pieces in a row, either horizontally,\n" <<
			"diagonally, or vertically. At any point you may enter 'x' to exit the program.\n" <<
			"Your moves will be marked by an 'X', and the opponent's moves by an 'O'. \n";

		// Main loop.  Keep looping until board is full or one player has
		// 3 in a row. Move number determines whose move it is ('X' or 'O')
		while( notDone) {

			// Using the moveNumber find out whose turn it is: 'X' for odd moves,
			// 'O' for even numbered moves.
			playerToMove = getPlayerToMove( moveNumber);

			// Display the board
			displayBoard();

			// Prompt for and get user input
			cout<<			 " 1 2 3 \n" <<
							 " 4 5 6 \n" <<
							 " 7 8 9 \n" <<
							 "to place piece \n\n";

			cout<<moveNumber << ". Enter position for " << playerToMove << " to play -> ";
			cin>>userInput;

			// See if "X" to exit was entered
			if( userInput == 'x') {
				cout<<"Exiting program..."<<endl;
				break;
			}

			// See if user input was numerical (for column move) or alphabetic
			// (to pop-out a bottom piece)
			char inputChar = userInput;
			if( inputChar >= '1' && inputChar <= '9') {
				// place the piece into the indicated column, returning whether or not
				// a valid move was made.
				bool validMove = placePieceInPosition( &playerToMove, &inputChar);
				if( ! validMove) {
					cout<<"*** That place is already full. Please retry...\n"<<endl;
					continue;	// go back up to top of loop to retry move
				}
			}
			else {
				// Sanity check.  Should never get here
				cout<<"*** Invalid move.  Please retry. ***"<<endl;
				continue;
			}

			// Find the winner ('X' or 'O') if any, otherwise return ' '
			char winner = findWinnerIfAny( playerToMove);
			if( winner != ' ') {
				// winner was 'X' or 'O'
				cout<< "\n*** " << winner << " has won the game! ***"<<endl;
				notDone = false;	// set variable to end main loop
				// display final board
				displayBoard();
				break;
			}

			// increment moveNumber, which indirectly switches the player to move
			moveNumber++;
		}//end while( noWinYet...

		cout<<"Exiting program...";
	}//end doIt()





Viewing all articles
Browse latest Browse all 51036

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>