• 0

[C++] Tic Tac Toe with Variable Size Board


Question

We've just started learning arrays and the what-not in my C++ class. Our assignment is to create a tic tac toe program that has a user-set variable size board (3x3, 4x4, 9x9, etc). He gave us an example 3x3 tic tac toe program listed below a week back or so and told us to play around with it to make it multi-sized. I've started playing with it slightly, but for the most part, am I just going to change the constant values of 3 to variables? I thought you could not set an array to size variable?

#include <stdio.h>
#include <stdlib.h>

char matrix[3][3];  /* the tic tac toe matrix */

char check(void);
void init_matrix(void);
void get_player_move(void);
void get_computer_move(void);
void disp_matrix(void);

int main(void)
{
  char done;

  printf("This is the game of Tic Tac Toe.\n");
  printf("You will be playing against the computer.\n");

  done =  ' ';
  init_matrix();

  do {
	disp_matrix();
	get_player_move();
	done = check(); /* see if winner */
	if(done!= ' ') break; /* winner!*/
	get_computer_move();
	done = check(); /* see if winner */
  } while(done== ' ');

  if(done=='X') printf("You won!\n");
  else printf("I won!!!!\n");
  disp_matrix(); /* show final positions */

  return 0;
}

/* Initialize the matrix. */
void init_matrix(void)
{
  int i, j;

  for(i=0; i<3; i++)
	for(j=0; j<3; j++) matrix[i][j] =  ' ';
}

/* Get a player's move. */
void get_player_move(void)
{
  int x, y;

  printf("Enter X,Y coordinates for your move: ");
  scanf("%d%*c%d", &x, &y);

  x--; y--;

  if(matrix[x][y]!= ' '){
	printf("Invalid move, try again.\n");
	get_player_move();
  }
  else matrix[x][y] = 'X';
}

/* Get a move from the computer. */
void get_computer_move(void)
{
  int i, j;
  for(i=0; i<3; i++){
	for(j=0; j<3; j++)
	  if(matrix[i][j]==' ') break;
	if(matrix[i][j]==' ') break;
  }

  if(i*j==9)  {
	printf("draw\n");
	exit(0);
  }
  else
	matrix[i][j] = 'O';
}

/* Display the matrix on the screen. */
void disp_matrix(void)
{
  int t;

  for(t=0; t<3; t++) {
	printf(" %c | %c | %c ",matrix[t][0],
			matrix[t][1], matrix [t][2]);
	if(t!=2) printf("\n---|---|---\n");
  }
  printf("\n");
}

/* See if there is a winner. */
char check(void)
{
  int i;

  for(i=0; i<3; i++)  /* check rows */
	if(matrix[i][0]==matrix[i][1] &&
	   matrix[i][0]==matrix[i][2]) return matrix[i][0];

  for(i=0; i<3; i++)  /* check columns */
	if(matrix[0][i]==matrix[1][i] &&
	   matrix[0][i]==matrix[2][i]) return matrix[0][i];

  /* test diagonals */
  if(matrix[0][0]==matrix[1][1] &&
	 matrix[1][1]==matrix[2][2])
	   return matrix[0][0];

  if(matrix[0][2]==matrix[1][1] &&
	 matrix[1][1]==matrix[2][0])
	   return matrix[0][2];

  return ' ';
}

Link to comment
Share on other sites

9 answers to this question

Recommended Posts

  • 0

Yes, you could start with a maximum size matrix and the jsut replace the 3's by a variable N (which would be the size)

also you'll need a double loop in

for(i=0; i<3; i++)  /* check rows */
	if(matrix[i][0]==matrix[i][1] &&
	   matrix[i][0]==matrix[i][2]) return matrix[i][0];

  for(i=0; i<3; i++)  /* check columns */
	if(matrix[0][i]==matrix[1][i] &&
	   matrix[0][i]==matrix[2][i]) return matrix[0][i];

  /* test diagonals */
  if(matrix[0][0]==matrix[1][1] &&
	 matrix[1][1]==matrix[2][2])
	   return matrix[0][0];

  if(matrix[0][2]==matrix[1][1] &&
	 matrix[1][1]==matrix[2][0])
	   return matrix[0][2];

which will allow you to check the entire row or column

Link to comment
Share on other sites

  • 0

You could also use the STL (standard template library) vector class for a dynamic array size based on user input. There's plenty of examples online (cplusplus.com for instance). Consider it if you absolutely have to have a dynamic size board that could be any size - otherwise, the past comments about a max size would work too and probably be more familiar to you.

Link to comment
Share on other sites

  • 0

Or if you feel experienced enough, you could always create it dynamically yourself... Just remember that the amount of memory available is finite. In other words, don't forget to delete[] what you allocate! ^_^

Link to comment
Share on other sites

  • 0
Or if you feel experienced enough, you could always create it dynamically yourself... Just remember that the amount of memory available is finite. In other words, don't forget to delete[] what you allocate! ^_^

Good tip! :) It is very important to take care of the garbage collection functionality (e.g. cleanup any unneeded resources). It is a good habit to get into.

Also, for this task couldn't you simply create a variable called "rows" and a variable called "columns" and have the user enter the number for each? Then, if I am correct, you would simply pass the array that you create the values that were entered.

Edited by winlonghorn
Link to comment
Share on other sites

  • 0

Thanks for all the replies guys...considering my experience and the scope of the course, I believe I'll stick with setting a constant for the matrix. Now I'm trying to actually get the matrix to display correctly.

char matrix[26][26];  // the tic tac toe matrix

char check(void);
void init_matrix(int BOARD_SIZE);
void get_player_move(void);
void get_computer_move(void);
void disp_matrix(int BOARD_SIZE);
void get_player2_move(void);
void get_computer2_move(void);

/* Initialize the matrix. */
void init_matrix(int BOARD_SIZE)
{
  int i, j;

  for(i=0; i<BOARD_SIZE; i++)
	for(j=0; j<BOARD_SIZE; j++) matrix[i][j] =  ' ';
}

//Display the matrix
void disp_matrix(int BOARD_SIZE)
{
int t; int u;
//Cosmetic bar above |---|---|---|
	printf("|");
	for (t=0; t<BOARD_SIZE; t++)
	do{
	if (t != BOARD_SIZE) printf("---|");}
	while(t>BOARD_SIZE);

//Bar t
	printf("\n|");
	do{
	for (u=0; u<BOARD_SIZE; u++)
	printf(" %c |", matrix [0][u]);
	}while(u>BOARD_SIZE);


//Cosmetic bar below |---|---|---|
	printf("\n|");
	for (t=0; t<BOARD_SIZE; t++)
	do{
	if (t != BOARD_SIZE) printf("---|");}
	while(t>BOARD_SIZE);
	printf("\n");

}

I'm slowly getting it. This will display only one vertical bar, but with the correct amount of spaces horizontally. I believe I just need to add another for loop....for (t=0, t<BOARD_SIZE; t++)....is this correct?

Edited by entropypl
Link to comment
Share on other sites

  • 0

Take the habit of typing your loops in full, it'll save you a lot of subtle bugs. Later when you feel very confident and are working alone on a project, you can do one-line loops with no brackets.

When you write a for loop, for instance, start by writing :

for ([initialization]; [break condition]; [increment]) {

}

Next, write what's inside the loop :

for ([initialization]; [break condition]; [increment]) {
	[statement 1];
	[statement 2];
	....
}

The same goes for if statements, functions, classes, while loops, anything that has a body. Except maybe individual cases in a switch statement.

I say this because your code is pretty hard to understand as it is, and it could break the minute you do any kind of modification to it. Take for instance this :

  for(i=0; i&lt;BOARD_SIZE; i++)
	for(j=0; j&lt;BOARD_SIZE; j++) matrix[i][j] =  ' ';

Let's say you have a second matrix, overlayed upon the first, which you'll want to initialize in the same spot. You might want to write :

  for(i=0; i&lt;BOARD_SIZE; i++)
	for(j=0; j&lt;BOARD_SIZE; j++) matrix1[i][j] =  ' '; matrix2[i][j] = ' ';

If this compiles, it will not do what you want. Can you tell why? Actually, the compiler will save you there, but it can't do the guesswork all the time. Just write the loops properly :

for(i=0; i&lt;BOARD_SIZE; i++) {
	for(j=0; j&lt;BOARD_SIZE; j++) { 
		matrix1[i][j] =  ' ';
		matrix2[i][j] = ' ';
	}
}

Link to comment
Share on other sites

  • 0
Take the habit of typing your loops in full, it'll save you a lot of subtle bugs. Later when you feel very confident and are working alone on a project, you can do one-line loops with no brackets.

I understand. Sometimes I guess I get excited and get ahead of myself :rolleyes:. I also need to start practicing proper indentation much more. I'll go through my project and clean it up after this post.

We will play on a variable-size board. Your program should define the following integer constants:

BOARD_SIZE

determines both the width and height of the game board (which is always square)

WIN_LENGTH

determines the number of Xs or Os in a row (either horizontally, vertically, or diagonally) that a player needs in order to win

so that the game can be played on different size boards simply by changing these values.

I've completed my disp_matrix function and it works flawlessly, now onto the hardest part, checking for a winner with a variable sized board AND variable sized WIN_LENGTH. Will a double loop work for the check() function? I was thinking I would have to totally butcher it and start anew.

Link to comment
Share on other sites

  • 0

It seems to me that BOARD_SIZE will always equal WIN_LENGTH, so what's the point of having that extra constant?

Your check function should work just like it did for a fixed size, just change the upper bounds to BOARD_SIZE.

Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.