• 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 ' ';
}

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

  • 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.

  • 0
  rpgfan said:
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
  • 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
  • 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] = ' ';
	}
}

  • 0
  Dr_Asik said:
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.

  Quote
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.

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

    • No registered users viewing this page.
  • Posts

    • Be careful what you wish for. Microsoft’s ideas for bells and whistles either brings ads, web views, “AI stuff”, bugs, or all four. I’d be happy if it was just full of performance optimizations and bugfixes.
    • Still needs many more bricks to accurately model that pos. 
    • Ha! Just as i was mentioning here yesterday that it was weird that MS hadn't announced any 25H2! Hope it includes some more bells and whistles.
    • 65-inch Hisense U8 Series Google Smart TV drops to its lowest price by Fiza Ali Amazon US is currently offering the 65-inch Hisense U8 Series Google Smart TV at its lowest price to date. So, if you are thinking of upgrading your home entertainment system, you may want to check it out. The Hisense U8 uses Mini‑LED Pro backlighting with Full Array Local Dimming to deliver up to 5,000 nits of peak brightness. Its QLED Colour system employs quantum dots to render over a billion shades, while Dolby Vision IQ, HDR10+, HDR10, HLG and Advanced HDR by Technicolor formats ensure a wide dynamic range and accurate colour reproduction. A native 165Hz refresh rate combined with a Variable Refresh Rate (VRR) of 48Hz to 165Hzthanks to AMD FreeSync Premium Pro, and Low‑Latency MEMC (Motion enhancement and compensation) eliminate screen tearing and input lag. The Anti‑Glare Low Reflection Pro coating reduces reflections from ambient light. Furthermore, audio is handled by a 72W 4.1.2 channel system featuring Dolby Atmos, with four primary and surround speakers, two up‑firing height channels and a built‑in subwoofer. Powered by the Hi‑View AI Engine Pro, the U8 Series automatically analyses and optimises picture and sound according to the content on screen. Moreover, Google TV provides a full smart platform with Google Assistant built in, compatibility with Alexa, access to apps, and voice control. Finally, connectivity options include Wi‑Fi 6E, Bluetooth 5.3, three HDMI 2.1 ports (one with eARC), two USB ports (one USB 3.0, one USB 2.0), optical digital audio output, RF antenna input (NTSC/Clear QAM/ATSC 3.0), composite video and L/R audio inputs, and an Ethernet LAN port. 65-inch Hisense U8 Series Google Smart TV: $1,242.87 (Amazon US) - 44% off This Amazon deal is US-specific and not available in other regions unless specified. If you don't like it or want to look at more options, check out the Amazon US deals page here. Get Prime (SNAP), Prime Video, Audible Plus or Kindle / Music Unlimited. Free for 30 days. As an Amazon Associate, we earn from qualifying purchases.
  • Recent Achievements

    • Dedicated
      Cole Multipass earned a badge
      Dedicated
    • Week One Done
      Alexander 001 earned a badge
      Week One Done
    • Week One Done
      icecreamconesleeves earned a badge
      Week One Done
    • One Year In
      PAC0 earned a badge
      One Year In
    • One Month Later
      PAC0 earned a badge
      One Month Later
  • Popular Contributors

    1. 1
      +primortal
      564
    2. 2
      +FloatingFatMan
      188
    3. 3
      ATLien_0
      184
    4. 4
      Skyfrog
      113
    5. 5
      Som
      109
  • Tell a friend

    Love Neowin? Tell a friend!