I am somewhat new to the c++, so you've been warned.
Yesterday I decided I wanted to create a program that displayed a Go board
and allowed you make moves. Fairly simple task, didn't take me that long but, I feel that the code could be a lot shorter and I also want to add a save feature but am not sure how to go about it.

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

/* a go board is a 19x19 grid, and stones are placed on the one of the 361 intersections 
but here for the sake of easiness these intersections will be represented with
dots*/
int rownum,colnum;count = 0
const int ROWS = 19,COLUMNS = 19;
char board[ROWS][COLUMNS]=
{   {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'},
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'},
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'},
	        {'.' , '.' , '.' , 'o' , '.' , '.' , '.' , '.' , '.' , 'o' , '.' , '.' , '.' , '.' , '.' , 'o' , '.' , '.' , '.'}, 
                {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , 'o' , '.' , '.' , '.' , '.' , '.' , 'o' , '.' , '.' , '.' , '.' , '.' , 'o' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , 'o' , '.' , '.' , '.' , '.' , '.' , 'o' , '.' , '.' , '.' , '.' , '.' , 'o' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'} };

Wow 0.o huge right, this is the biggest part of it, this is where I wonder, could I make it any smaller. If there's anyway that I could make this smaller so I don't have to see such a horrible eyesore of a multidimensional array, that would be great.

void displayBoard();  
    
int main()
{   do {
    start:
    displayBoard();
    cout << "\n\n\nPlayer1>>";
    cout << "Column: ";
    cin >> colnum;
    cout << "Row: ";
    cin >> rownum;
    if (board[rownum-1][colnum-1] == 'X' or board[rownum-1][colnum-1] == '0')
    {cout << "\nThere is already a stone on that intersection!\n"; goto start;}
    else
    board[rownum-1][colnum-1] = 'X';
    start1:
    displayBoard();
    cout << "\n\n\nPlayer2>>>";
    cout << "Column: ";
    cin >> colnum;
    cout << "Row: ";
    cin >> rownum;
    if (board[rownum-1][colnum-1] == 'X' or board[rownum-1][colnum-1] == '0')
    {cout << "\nThere is already a stone on that intersection!\n"; goto start1;}
    else
    board[rownum-1][colnum-1] = '0';
    }while (colnum <= 19);
    system("PAUSE");
    return 0;}

void displayBoard()
{   int count=0;
    cout <<"Play Go!\n";
    cout << "1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19"<< endl;
        for (int i = 0; i < ROWS; ++i)
    {
        for (int j = 0; j < COLUMNS; ++j)
        { 
         cout << board[i][j];
         cout << "  ";
        }
        count = count + 1;cout << count;cout << endl;
     }
    cout <<"围棋";
    count=0;}

And here's where I've stopped. Now I want the save_game function to
basically take displayBoard()s' output and save it to the filename and directory of my users choice. Now, of course this program is lacking quite a few pieces and there's no real way to exit it quite yet(don't really care about it). Any advice or solutions you have would be very much appreciated.
Thanks for your time!

Recommended Answers

All 7 Replies

if (board[rownum-1][colnum-1] == 'X' or board[rownum-1][colnum-1] == '0')

What language are you using?

char board[ROWS][COLUMNS]=
{   {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'},
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'},
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'},
	        {'.' , '.' , '.' , 'o' , '.' , '.' , '.' , '.' , '.' , 'o' , '.' , '.' , '.' , '.' , '.' , 'o' , '.' , '.' , '.'}, 
                {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , 'o' , '.' , '.' , '.' , '.' , '.' , 'o' , '.' , '.' , '.' , '.' , '.' , 'o' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , 'o' , '.' , '.' , '.' , '.' , '.' , 'o' , '.' , '.' , '.' , '.' , '.' , 'o' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'}, 
	        {'.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.' , '.'} };

Oh my god! Why not initialize this way:

char board[ROWS][COLUMNS] = {'.'};
int main()
{
   board[3][3] = 'o';
   board[3][9] = 'o';
   board[3][15] = 'o';

   board[9][3] = 'o';
   board[9][9] = 'o';
   board[9][15] = 'o';

   board[12][3] = 'o';
   board[12][9] = 'o';
   board[12][15] = 'o';
}

I'm going to sleep now... I will complain some more when I wake up

That looks good in theory, but it's not working out right. nope.

>Wow 0.o huge right
Eh, I've seen worse.

>What language are you using?
Well, C++ does support those alternative tokens. C does as well if you include <iso646.h>.

>Oh my god! Why not initialize this way:
>char board[ROWS][COLUMNS] = {'.'};
Probably because that wouldn't work. It only initializes the first element to '.' and all of the rest to 0. If you want to slim down the initialization, you're pretty much stuck with something equivalent to this:

#include <cstring>

//...

for ( int i = 0; i < ROWS; i++ )
  std::memset ( board, '.', COLUMNS );

However, there's nothing wrong with a big table initialization, though it's even better if you generate it automatically to avoid manual mistakes:

// Table generator
#include <cstddef>
#include <fstream>
#include <utility>

namespace {
    // Convert an array of T to an array of char
    // for calculating the number of elements
    // at compile-time
    template <typename T, size_t N>
    char (&array(T(&)[N]))[N];

    const int ROWS = 19;
    const int COLS = 19;

    // Change this to match your project
    const char *filename = "tabledefs.cpp";

    // Magic numbers assuming this definition is standalone
    const char *object_type = "char";
    const char *object_name = "board";

    // Change this to change the table values
    const char *set_val = "'o'";
    const char *unset_val = "'.'";

    // Add or remove x,y pairs to set different cells
    const std::pair<int, int> set_indices[] = {
        std::make_pair ( 3, 3 ),
        std::make_pair ( 3, 9 ),
        std::make_pair ( 3, 15 ),
        std::make_pair ( 9, 3 ),
        std::make_pair ( 9, 9 ),
        std::make_pair ( 9, 15 ),
        std::make_pair ( 12, 3 ),
        std::make_pair ( 12, 9 ),
        std::make_pair ( 12, 15 ),
    };

    // Used for notational convenience since
    // this won't change at runtime
    const std::pair<int, int> *set_indices_end =
        set_indices + sizeof array ( set_indices );
}

int main()
{
    std::ofstream out ( filename );

    if ( out ) {
        // Declare the object and start initialization
        out<< object_type <<" "<< object_name
            <<"["<< ROWS <<"]["<< COLS <<"] = {\n";

        // Initialize the table
        for ( int i = 0; i < ROWS; i++ ) {
            out<<"    { ";

            for ( int j = 0; j < COLS; j++ ) {
                bool set_index =  std::find ( set_indices, set_indices_end,
                    std::make_pair ( i, j ) ) != set_indices_end;

                out<< ( set_index ? set_val : unset_val )
                    << ( j < COLS - 1 ? ", " : " " );
            }

            out<<"}"<< ( i < ROWS - 1 ? "," : "" ) <<'\n';
        }

        // Finish up
        out<<"};";
    }
}

wow after seeing the other possible solutions such a big initialization doesn't seem so bad.
Thanks for your help Narue and Invisal ^^.

As another solution you can avoid initializing the array elements and assign elements as needed instead. This seems to work for me at least.

#include <iostream>
using namespace std;
int main()
{
  int i, j;
  char board[19][19];

  //assign all elements ','
  for(i = 0; i < 19; ++i)
    for(j = 0; j < 19; ++j)
      board[i][j] = '.';
 
  //selectively assign certain elements 'o'
  board[3][3] = 'o';
  board[3][9] = 'o';
  board[3][15] = 'o';

  board[9][3] = 'o';
  board[9][9] = 'o';
  board[9][15] = 'o';

  board[12][3] = 'o';
  board[12][9] = 'o';
  board[12][15] = 'o';

  //display board
  for(i = 0; i < 19; ++i)
  {
    for(j = 0; j < 19; ++j)
    {
      cout << board[i][j];
    }
    cout << endl;
  }
}

It's two lines longer than invisals attempt at initialization, requires only routine knowledge of C++, doesn't burn out the eyeballs and is much less prone to typing errors. If you must initialize the array rather than using assignment to fill the array, then so be it.

I am really sorry for mistakenly explaining to you (next time, I will test first before I provide the answer.). Narue's explained it very well already.

Anyway, I provided you with my code, which served the same purpose, except a few improvements:

  • Check whether the output is out of range (smaller than 1 and bigger than the number of row and number of column)
  • Provide the exit option for user (by input 0 to row and column)
#include <iostream>

const int ROWS = 19,COLUMNS = 19;
// store the whole board
char board[ROWS][COLUMNS];
// use for store the user's input
int row_num, col_num;
// player's turn, true mean 'X' player
// and false mean 'O' player
bool turn = true;

// Draw the board
void Display()
{
   for(int i = 0; i < ROWS; i++) {
      for(int j = 0; j < COLUMNS; j++)
         std::cout << board[i][j] << "  ";
      std::cout << std::endl;
   }
}

// this function returns true when the player
// successfully input their coordinate, returns
// false whenever the player want to exit the
// program.
bool Input()
{
   Display(); // Draw the board

   while(true) { // Loop until the user input correctly
      std::cout << "Row number: "; std::cin >> row_num;
      std::cout << "Columns number: "; std::cin >> col_num;
      // The number of row and column are started from 1
      // but the first element of array is started from 0
      row_num--; col_num--;
      // if the inputs are out of range
      if (row_num < 0 || row_num > ROWS ||
         col_num < 0 || col_num > COLUMNS) {
         // if user want to exit the program
         if (row_num == -1 && col_num == -1) return false;
         std::cout << "Out of range, please try again\n";
         continue; // ask user to input again
      // check if the coordinate is taken
      } else if (board[row_num][col_num] != 'o' &&
            board[row_num][col_num] != '.') {
         std::cout << "There's already a stone on that intersection\n";
         continue; // ask user to input again
      }

      // place the stone to the board
      board[row_num][col_num] = turn?'X':'O';
      turn = !turn; // change the turn
      return true; // successfully inputed
   }
}

int main()
{
   // board initiatilization
   for(int i = 0; i < ROWS; i++)
      for(int j = 0; j < COLUMNS; j++)
         board[i][j] = ((j+3)%6+(i+3)%6) ? '.' : 'o';

   while(Input());

}

Wow, I like your code invisal!
it's simple yet clever ^^.

lol, i'm such a newb ><.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.